summaryrefslogtreecommitdiffstats
path: root/third_party/rust/crash-context/src/linux/getcontext/x86.rs
diff options
context:
space:
mode:
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.rs53
1 files changed, 53 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..b9d4b5ab72
--- /dev/null
+++ b/third_party/rust/crash-context/src/linux/getcontext/x86.rs
@@ -0,0 +1,53 @@
+#[cfg(target_os = "android")]
+compile_error!("please file an issue if you care about this target");
+
+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
+ "leal 0xec(%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)
+}