diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2011-11-08 17:07:11 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2011-11-08 21:14:09 -0800 |
| commit | ff5b319ce551e6b9b79ce8f127e25d26d0f4d085 (patch) | |
| tree | bc4c8e307509232e0f599d7e39bb3b8815c77de7 /src/rt | |
| parent | 2edd3135adcf4a3812487df75c503a95fbbc1a38 (diff) | |
| download | rust-ff5b319ce551e6b9b79ce8f127e25d26d0f4d085.tar.gz rust-ff5b319ce551e6b9b79ce8f127e25d26d0f4d085.zip | |
correct stack alignment
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/arch/i386/regs.h | 2 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/_context.S | 86 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/context.cpp | 3 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/context.h | 4 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/regs.h (renamed from src/rt/arch/x86_64/x86_64_regs.h) | 24 |
5 files changed, 60 insertions, 59 deletions
diff --git a/src/rt/arch/i386/regs.h b/src/rt/arch/i386/regs.h new file mode 100644 index 00000000000..80eacd80178 --- /dev/null +++ b/src/rt/arch/i386/regs.h @@ -0,0 +1,2 @@ +// This file is not used by i386, but we keep it here so all +// architectures have the same set of header files. diff --git a/src/rt/arch/x86_64/_context.S b/src/rt/arch/x86_64/_context.S index 39df5b6610b..7fdc6114b0a 100644 --- a/src/rt/arch/x86_64/_context.S +++ b/src/rt/arch/x86_64/_context.S @@ -1,5 +1,7 @@ -#include "x86_64_regs.h" - +#include "regs.h" +#define ARG0 RUSTRT_ARG0_S +#define ARG1 RUSTRT_ARG1_S + .text /* @@ -41,7 +43,10 @@ First four arguments: /* Stores current registers into arg0/RCX and restores registers found in arg1/RDX. This is used by our - implementation of getcontext. + implementation of getcontext. Only saves/restores nonvolatile + registers and the register used for the first argument. + Volatile registers in general ought to be saved by the caller + anyhow. */ // swap_registers(registers_t *oregs, registers_t *regs) @@ -56,60 +61,53 @@ swap_registers: // return address. We can therefore just return normally to // jump back into the old code. -# if defined(RUSTRT_ARG0_S) - mov RUSTRT_ARG0_S, %rdi - mov RUSTRT_ARG1_S, %rsi -# endif - // Save instruction pointer: pop %rax - mov %rax, (RUSTRT_IP*8)(%rdi) + mov %rax, (RUSTRT_IP*8)(RUSTRT_ARG0_S) // Save non-volatile integer registers: // (including RSP) - mov %rbx, (RUSTRT_RBX*8)(%rdi) - mov %rsp, (RUSTRT_RSP*8)(%rdi) - mov %rbp, (RUSTRT_RBP*8)(%rdi) - mov %r12, (RUSTRT_R12*8)(%rdi) - mov %r13, (RUSTRT_R13*8)(%rdi) - mov %r14, (RUSTRT_R14*8)(%rdi) - mov %r15, (RUSTRT_R15*8)(%rdi) - - // Save relevant argument registers: - mov %rcx, (RUSTRT_RCX*8)(%rdi) - mov %rdi, (RUSTRT_RDI*8)(%rdi) + mov %rbx, (RUSTRT_RBX*8)(ARG0) + mov %rsp, (RUSTRT_RSP*8)(ARG0) + mov %rbp, (RUSTRT_RBP*8)(ARG0) + mov %r12, (RUSTRT_R12*8)(ARG0) + mov %r13, (RUSTRT_R13*8)(ARG0) + mov %r14, (RUSTRT_R14*8)(ARG0) + mov %r15, (RUSTRT_R15*8)(ARG0) + + // Save 0th argument register: + mov ARG0, (RUSTRT_ARG0*8)(ARG0) // Save non-volatile XMM registers: - movapd %xmm0, (RUSTRT_XMM0*8)(%rdi) - movapd %xmm1, (RUSTRT_XMM1*8)(%rdi) - movapd %xmm2, (RUSTRT_XMM2*8)(%rdi) - movapd %xmm3, (RUSTRT_XMM3*8)(%rdi) - movapd %xmm4, (RUSTRT_XMM4*8)(%rdi) - movapd %xmm5, (RUSTRT_XMM5*8)(%rdi) + movapd %xmm0, (RUSTRT_XMM0*8)(ARG0) + movapd %xmm1, (RUSTRT_XMM1*8)(ARG0) + movapd %xmm2, (RUSTRT_XMM2*8)(ARG0) + movapd %xmm3, (RUSTRT_XMM3*8)(ARG0) + movapd %xmm4, (RUSTRT_XMM4*8)(ARG0) + movapd %xmm5, (RUSTRT_XMM5*8)(ARG0) // Restore non-volatile integer registers: // (including RSP) - mov (RUSTRT_RBX*8)(%rsi), %rbx - mov (RUSTRT_RSP*8)(%rsi), %rsp - mov (RUSTRT_RBP*8)(%rsi), %rbp - mov (RUSTRT_R12*8)(%rsi), %r12 - mov (RUSTRT_R13*8)(%rsi), %r13 - mov (RUSTRT_R14*8)(%rsi), %r14 - mov (RUSTRT_R15*8)(%rsi), %r15 - - // Restore relevant argument registers: - mov (RUSTRT_RCX*8)(%rsi), %rcx - mov (RUSTRT_RDI*8)(%rsi), %rdi + mov (RUSTRT_RBX*8)(ARG1), %rbx + mov (RUSTRT_RSP*8)(ARG1), %rsp + mov (RUSTRT_RBP*8)(ARG1), %rbp + mov (RUSTRT_R12*8)(ARG1), %r12 + mov (RUSTRT_R13*8)(ARG1), %r13 + mov (RUSTRT_R14*8)(ARG1), %r14 + mov (RUSTRT_R15*8)(ARG1), %r15 + + // Restore 0th argument register: + mov (RUSTRT_ARG0*8)(ARG1), ARG0 // Restore non-volatile XMM registers: - movapd (RUSTRT_XMM0*8)(%rsi), %xmm0 - movapd (RUSTRT_XMM1*8)(%rsi), %xmm1 - movapd (RUSTRT_XMM2*8)(%rsi), %xmm2 - movapd (RUSTRT_XMM3*8)(%rsi), %xmm3 - movapd (RUSTRT_XMM4*8)(%rsi), %xmm4 - movapd (RUSTRT_XMM5*8)(%rsi), %xmm5 + movapd (RUSTRT_XMM0*8)(ARG1), %xmm0 + movapd (RUSTRT_XMM1*8)(ARG1), %xmm1 + movapd (RUSTRT_XMM2*8)(ARG1), %xmm2 + movapd (RUSTRT_XMM3*8)(ARG1), %xmm3 + movapd (RUSTRT_XMM4*8)(ARG1), %xmm4 + movapd (RUSTRT_XMM5*8)(ARG1), %xmm5 // Jump to the instruction pointer // found in regs: - jmp *(RUSTRT_IP*8)(%rsi) + jmp *(RUSTRT_IP*8)(ARG1) diff --git a/src/rt/arch/x86_64/context.cpp b/src/rt/arch/x86_64/context.cpp index 09577dbd151..d9070c6385a 100644 --- a/src/rt/arch/x86_64/context.cpp +++ b/src/rt/arch/x86_64/context.cpp @@ -26,8 +26,9 @@ void context::call(void *f, void *arg, void *stack) { swap(*this); // set up the stack - uint32_t *sp = (uint32_t *)stack; + uint64_t *sp = (uint64_t *)stack; sp = align_down(sp); + *--sp = 0xdeadbeef; // takes place of ret. addr. regs.data[RUSTRT_ARG0] = (uint64_t)arg; regs.data[RUSTRT_RSP] = (uint64_t)sp; diff --git a/src/rt/arch/x86_64/context.h b/src/rt/arch/x86_64/context.h index 5d764cfdb0a..3f01a4479d7 100644 --- a/src/rt/arch/x86_64/context.h +++ b/src/rt/arch/x86_64/context.h @@ -23,8 +23,8 @@ T align_down(T sp) // The struct in which we store the saved data. This is mostly the // volatile registers and instruction pointer, but it also includes // RCX/RDI which are used to pass arguments. The indices for each -// register are found in <x86_64_regs.h>: -#include "x86_64_regs.h" +// register are found in "regs.h": +#include "regs.h" struct registers_t { uint64_t data[RUSTRT_MAX]; }; diff --git a/src/rt/arch/x86_64/x86_64_regs.h b/src/rt/arch/x86_64/regs.h index 084ab03fdc4..7d090ff5b27 100644 --- a/src/rt/arch/x86_64/x86_64_regs.h +++ b/src/rt/arch/x86_64/regs.h @@ -1,13 +1,13 @@ -#define RUSTRT_RBX 0 -#define RUSTRT_RSP 1 -#define RUSTRT_RBP 2 -#define RUSTRT_RDI 3 -#define RUSTRT_RCX 4 -#define RUSTRT_R12 5 -#define RUSTRT_R13 6 -#define RUSTRT_R14 7 -#define RUSTRT_R15 8 -#define RUSTRT_IP 9 +#define RUSTRT_RBX 0 +#define RUSTRT_RSP 1 +#define RUSTRT_RBP 2 +#define RUSTRT_ARG0 3 // RCX on Windows, RDI elsewhere +#define RUSTRT_R12 4 +#define RUSTRT_R13 5 +#define RUSTRT_R14 6 +#define RUSTRT_R15 7 +#define RUSTRT_IP 8 +#define RUSTRT_XXX 9 // Not used, just padding #define RUSTRT_XMM0 10 #define RUSTRT_XMM1 12 #define RUSTRT_XMM2 14 @@ -19,11 +19,11 @@ // ARG0 is the register in which the first argument goes. // Naturally this depends on your operating system. #if defined(__MINGW32__) || defined(_WINDOWS) -# define RUSTRT_ARG0 RUSTRT_RCX # define RUSTRT_ARG0_S %rcx # define RUSTRT_ARG1_S %rdx #else -# define RUSTRT_ARG0 RUSTRT_RDI +# define RUSTRT_ARG0_S %rdi +# define RUSTRT_ARG1_S %rsi #endif |
