diff options
Diffstat (limited to 'third_party/rust/crash-context/src/linux/getcontext/x86.rs')
-rw-r--r-- | third_party/rust/crash-context/src/linux/getcontext/x86.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/third_party/rust/crash-context/src/linux/getcontext/x86.rs b/third_party/rust/crash-context/src/linux/getcontext/x86.rs new file mode 100644 index 0000000000..cb823e1182 --- /dev/null +++ b/third_party/rust/crash-context/src/linux/getcontext/x86.rs @@ -0,0 +1,68 @@ +// Unfortunately, the asm! macro has a few really annoying limitations at the +// moment +// +// 1. const operands are unstable +// 2. cfg attributes can't be used inside the asm macro at all +// +// and the worst part is we need it for literally only 1 thing, using a different +// offset to the fpstate in ucontext depending on whether we are targeting android +// or not :( +macro_rules! asm_func { + ($offset:expr) => { + std::arch::global_asm! { + ".text", + ".global crash_context_getcontext", + ".hidden crash_context_getcontext", + ".align 4", + ".type crash_context_getcontext, @function", + "crash_context_getcontext:", + "movl 4(%esp), %eax", // eax = uc + + // Save register values + "movl %ecx, 0x3c(%eax)", + "movl %edx, 0x38(%eax)", + "movl %ebx, 0x34(%eax)", + "movl %edi, 0x24(%eax)", + "movl %esi, 0x28(%eax)", + "movl %ebp, 0x2c(%eax)", + + "movl (%esp), %edx", /* return address */ + "lea 4(%esp), %ecx", /* exclude return address from stack */ + "mov %edx, 0x4c(%eax)", + "mov %ecx, 0x30(%eax)", + + "xorl %ecx, %ecx", + "movw %fs, %cx", + "mov %ecx, 0x18(%eax)", + + "movl $0, 0x40(%eax)", + + // Save floating point state to fpregstate, then update + // the fpregs pointer to point to it + stringify!(leal $offset(%eax),%ecx), + "fnstenv (%ecx)", + "fldenv (%ecx)", + "mov %ecx, 0x60(%eax)", + + // Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) + "leal 0x6c(%eax), %edx", + "xorl %ecx, %ecx", + "push %edx", /* &uc->uc_sigmask */ + "push %ecx", /* NULL */ + "push %ecx", /* SIGBLOCK == 0 on i386 */ + "call sigprocmask@PLT", + "addl $12, %esp", + + "movl $0, %eax", + "ret", + + ".size crash_context_getcontext, . - crash_context_getcontext", + options(att_syntax) + } + }; +} + +#[cfg(target_os = "linux")] +asm_func!(0xec); +#[cfg(target_os = "android")] +asm_func!(0x74); |