Patchwork [3/5] exec: Do not use absolute address hints for code_gen_buffer with -fpie

login
register
mail settings
Submitter Stefan Weil
Date Nov. 18, 2012, 8:48 p.m.
Message ID <50A9498B.2040209@weilnetz.de>
Download mbox | patch
Permalink /patch/199908/
State Superseded
Headers show

Comments

Stefan Weil - Nov. 18, 2012, 8:48 p.m.
Am 16.10.2012 09:30, schrieb Richard Henderson:
> The hard-coded addresses inside alloc_code_gen_buffer only make sense
> if we're building an executable that will actually run at the address
> we've put into the linker scripts.
>
> When we're building with -fpie, the executable will run at some
> random location chosen by the kernel.  We get better placement for
> the code_gen_buffer if we allow the kernel to place the memory,
> as it will tend to to place it near the executable, based on the
> PROT_EXEC bit.
>
> Since code_gen_prologue is always inside the executable, this effect
> is easily seen at the end of most TB, with the exit_tb opcode, and
> with any calls to helper functions.
>
> Signed-off-by: Richard Henderson<rth@twiddle.net>
> ---
>   exec.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/exec.c b/exec.c
> index 6c0b2d7..5e33a3d 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -578,7 +578,12 @@ static inline void *alloc_code_gen_buffer(void)
>       /* Constrain the position of the buffer based on the host cpu.
>          Note that these addresses are chosen in concert with the
>          addresses assigned in the relevant linker script file.  */
> -# if defined(__x86_64__)&&  defined(MAP_32BIT)
> +# if defined(__PIE__) || defined(__PIC__)
> +    /* Don't bother setting a preferred location if we're building
> +       a position-independent executable.  We're more likely to get
> +       an address near the main executable if we let the kernel
> +       choose the address.  */
> +# elif defined(__x86_64__)&&  defined(MAP_32BIT)
>       /* Force the memory down into low memory with the executable.
>          Leave the choice of exact location with the kernel.  */
>       flags |= MAP_32BIT;


This patch breaks the TCG interpreter. Here is a test run on Debian 
x86_64 (output shortened):

$ ./configure --enable-debug --enable-tcg-interpreter 
--target-list=i386-softmmu --disable-docs
$ make
$ gdb --args i386-softmmu/qemu-system-i386 -L pc-bios
(gdb) r
Starting program: i386-softmmu/qemu-system-i386 -L pc-bios
[Thread debugging using libthread_db enabled]
[New Thread 0x7fffe8f73700 (LWP 1446)]
[New Thread 0x7fffe0470700 (LWP 1447)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe8f73700 (LWP 1446)]
0x00005555558e7ded in tcg_qemu_tb_exec (cpustate=0x55555656f7e0, 
tb_ptr=0xeab74acb <Address 0xeab74acb out of bounds>) at tci.c:445
445             TCGOpcode opc = tb_ptr[0];
(gdb) q

QEMU crashes early while executing a jmp opcode.

This patch restores functionality:

         an address near the main executable if we let the kernel

Regards

Stefan W.
Richard Henderson - Nov. 19, 2012, 4:27 p.m.
On 2012-11-18 12:48, Stefan Weil wrote:
> This patch breaks the TCG interpreter. Here is a test run on Debian x86_64 (output shortened):

Nack.  This is hiding some bug elsewhere in the tcg interpreter.

I disbelieve that the interpreter *requires* a pointer in the
low 32-bits of the x86_64 address space.


r~

Patch

diff --git a/exec.c b/exec.c
index 8435de0..44e4504 100644
--- a/exec.c
+++ b/exec.c
@@ -564,7 +564,7 @@  static inline void *alloc_code_gen_buffer(void)
      /* Constrain the position of the buffer based on the host cpu.
         Note that these addresses are chosen in concert with the
         addresses assigned in the relevant linker script file.  */
-# if defined(__PIE__) || defined(__PIC__)
+# if !defined(CONFIG_TCG_INTERPRETER) && (defined(__PIE__) || 
defined(__PIC__))
      /* Don't bother setting a preferred location if we're building
         a position-independent executable.  We're more likely to get