aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-01-13 19:47:21 +0200
committerPekka Enberg <penberg@kernel.org>2012-02-01 17:03:48 +0200
commitaf7dedb289556e0c206d436c45c64f326013e120 (patch)
tree41853295b2f7d1ec7707343440bfb6e19c2ca07f
parentf784e9727db3d2c891bf0bb20a1ad4135a9fe5c8 (diff)
downloadjato-af7dedb289556e0c206d436c45c64f326013e120.tar.gz
x86-32: Fix non-standard stack frame layout
This patch fixes the non-standard stack frame layout on 32-bit. Prolog is changed as follows: Before: [main] 0xa736b790: 57 push %edi [main] 0xa736b791: 56 push %esi [main] 0xa736b792: 53 push %ebx [main] 0xa736b793: 55 push %ebp [main] 0xa736b794: 89 e5 mov %esp,%ebp [main] 0xa736b796: 83 ec 10 sub $0x10,%esp After: [main] 0xa73db4a8: 55 push %ebp [main] 0xa73db4a9: 89 e5 mov %esp,%ebp [main] 0xa73db4ab: 83 ec 10 sub $0x10,%esp [main] 0xa73db4ae: 57 push %edi [main] 0xa73db4af: 56 push %esi [main] 0xa73db4b0: 53 push %ebx Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--arch/x86/emit_32.c12
-rw-r--r--arch/x86/emit_64.c4
-rw-r--r--arch/x86/include/arch/stack-frame.h3
-rw-r--r--arch/x86/stack-frame.c8
-rw-r--r--test/unit/arch-x86/encode-test.c6
5 files changed, 8 insertions, 25 deletions
diff --git a/arch/x86/emit_32.c b/arch/x86/emit_32.c
index 40004c06..f133bdac 100644
--- a/arch/x86/emit_32.c
+++ b/arch/x86/emit_32.c
@@ -621,14 +621,14 @@ static void emit_restore_callee_save_regs(struct buffer *buf)
void emit_prolog(struct buffer *buf, struct stack_frame *frame,
unsigned long frame_size)
{
- emit_save_callee_save_regs(buf);
-
__emit_push_reg(buf, MACH_REG_EBP);
__emit_mov_reg_reg(buf, MACH_REG_ESP, MACH_REG_EBP);
if (frame_size)
__emit_sub_imm_reg(buf, frame_size, MACH_REG_ESP);
+ emit_save_callee_save_regs(buf);
+
if (opt_debug_stack)
__emit_push_imm(buf, STACK_FRAME_REDZONE_END);
}
@@ -667,22 +667,18 @@ void emit_epilog(struct buffer *buf)
if (opt_debug_stack)
emit_stack_redzone_check(buf);
- emit_leave(buf);
emit_restore_regs(buf);
+ emit_leave(buf);
emit_ret(buf);
}
-/*
- * FIXME: We use different stack layout on 32-bit and 64-bit so prolog, epilog,
- * and unwind sequences are slightly different.
- */
void emit_unwind(struct buffer *buf)
{
if (opt_debug_stack)
emit_stack_redzone_check(buf);
- emit_leave(buf);
emit_restore_regs(buf);
+ emit_leave(buf);
__emit_jmp(buf, (unsigned long)&unwind);
}
diff --git a/arch/x86/emit_64.c b/arch/x86/emit_64.c
index f78bb665..081ab8df 100644
--- a/arch/x86/emit_64.c
+++ b/arch/x86/emit_64.c
@@ -1265,10 +1265,6 @@ void emit_epilog(struct buffer *buf)
emit_ret(buf);
}
-/*
- * FIXME: We use different stack layout on 32-bit and 64-bit so prolog, epilog,
- * and unwind sequences are slightly different.
- */
void emit_unwind(struct buffer *buf)
{
if (opt_debug_stack)
diff --git a/arch/x86/include/arch/stack-frame.h b/arch/x86/include/arch/stack-frame.h
index fc0ab27c..d19e58e4 100644
--- a/arch/x86/include/arch/stack-frame.h
+++ b/arch/x86/include/arch/stack-frame.h
@@ -22,9 +22,6 @@ struct native_stack_frame {
struct jit_stack_frame {
void *prev; /* previous stack frame link */
- unsigned long old_ebx;
- unsigned long old_esi;
- unsigned long old_edi;
unsigned long return_address;
unsigned long args[0];
} __attribute__((packed));
diff --git a/arch/x86/stack-frame.c b/arch/x86/stack-frame.c
index c7db807e..236c2960 100644
--- a/arch/x86/stack-frame.c
+++ b/arch/x86/stack-frame.c
@@ -40,10 +40,7 @@
#include "arch/stack-frame.h"
/*
- * The three callee-saved registers are unconditionally stored on the stack
- * after EIP and EBP (see emit_prolog() for details). Therefore, there are five
- * 32-bit stack slots before the first argument to a function as illustrated by
- * the following diagram:
+ * The stack frame layout is illustrated by the following diagram:
*
* : : ^
* : : | Higher memory addresses
@@ -52,9 +49,6 @@
* : ... :
* | Arg 1 | <-- Start offset of arguments
* | Old EIP |
- * | EDI |
- * | ESI |
- * | EBX |
* | Old EBP | <-- New EBP
* | Local 1 |
* : ... :
diff --git a/test/unit/arch-x86/encode-test.c b/test/unit/arch-x86/encode-test.c
index 56f8d09d..e417d890 100644
--- a/test/unit/arch-x86/encode-test.c
+++ b/test/unit/arch-x86/encode-test.c
@@ -948,7 +948,7 @@ void test_encoding_reg_memdisp(void)
void test_encoding_memlocal(void)
{
#ifdef CONFIG_32_BIT
- uint8_t encoding[] = { 0xff, 0xb5, 0x14, 0x00, 0x00, 0x00 };
+ uint8_t encoding[] = { 0xff, 0xb5, 0x08, 0x00, 0x00, 0x00 };
#else
uint8_t encoding[] = { 0xff, 0xb5, 0x10, 0x00, 0x00, 0x00 };
#endif
@@ -981,7 +981,7 @@ void test_encoding_memlocal(void)
void test_encoding_fstp_memlocal(void)
{
#ifdef CONFIG_32_BIT
- uint8_t encoding[] = { 0xd9, 0x9d, 0x14, 0x00, 0x00, 0x00 };
+ uint8_t encoding[] = { 0xd9, 0x9d, 0x08, 0x00, 0x00, 0x00 };
#else
uint8_t encoding[] = { 0xd9, 0x9d, 0x10, 0x00, 0x00, 0x00 };
#endif
@@ -1014,7 +1014,7 @@ void test_encoding_fstp_memlocal(void)
void test_encoding_fstp_64_memlocal(void)
{
#ifdef CONFIG_32_BIT
- uint8_t encoding[] = { 0xdd, 0x9d, 0x14, 0x00, 0x00, 0x00 };
+ uint8_t encoding[] = { 0xdd, 0x9d, 0x08, 0x00, 0x00, 0x00 };
#else
uint8_t encoding[] = { 0xdd, 0x9d, 0x10, 0x00, 0x00, 0x00 };
#endif