summaryrefslogtreecommitdiff
path: root/src/third_party/unwind/dist/src/x86_64/getcontext.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/unwind/dist/src/x86_64/getcontext.S')
-rw-r--r--src/third_party/unwind/dist/src/x86_64/getcontext.S134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/third_party/unwind/dist/src/x86_64/getcontext.S b/src/third_party/unwind/dist/src/x86_64/getcontext.S
new file mode 100644
index 00000000000..7a8b5664bda
--- /dev/null
+++ b/src/third_party/unwind/dist/src/x86_64/getcontext.S
@@ -0,0 +1,134 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2008 Google, Inc
+ Contributed by Paul Pluzhnikov <ppluzhnikov@google.com>
+ Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "ucontext_i.h"
+
+/* int _Ux86_64_getcontext (ucontext_t *ucp)
+
+ Saves the machine context in UCP necessary for libunwind.
+ Unlike the libc implementation, we don't save the signal mask
+ and hence avoid the cost of a system call per unwind.
+
+*/
+
+ .global _Ux86_64_getcontext
+ .type _Ux86_64_getcontext, @function
+_Ux86_64_getcontext:
+ .cfi_startproc
+
+ /* Callee saved: RBX, RBP, R12-R15 */
+ movq %r12, UC_MCONTEXT_GREGS_R12(%rdi)
+ movq %r13, UC_MCONTEXT_GREGS_R13(%rdi)
+ movq %r14, UC_MCONTEXT_GREGS_R14(%rdi)
+ movq %r15, UC_MCONTEXT_GREGS_R15(%rdi)
+ movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi)
+ movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi)
+
+ /* Save argument registers (not strictly needed, but setcontext
+ restores them, so don't restore garbage). */
+ movq %r8, UC_MCONTEXT_GREGS_R8(%rdi)
+ movq %r9, UC_MCONTEXT_GREGS_R9(%rdi)
+ movq %rdi, UC_MCONTEXT_GREGS_RDI(%rdi)
+ movq %rsi, UC_MCONTEXT_GREGS_RSI(%rdi)
+ movq %rdx, UC_MCONTEXT_GREGS_RDX(%rdi)
+ movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi)
+ movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi)
+
+#if defined __linux__
+ /* Save fp state (not needed, except for setcontext not
+ restoring garbage). */
+ leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8
+ movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi)
+ fnstenv (%r8)
+ stmxcsr FPREGS_OFFSET_MXCSR(%r8)
+#elif defined __FreeBSD__
+ fxsave UC_MCONTEXT_FPSTATE(%rdi)
+ movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
+ movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
+ /* Save rflags and segment registers, so that sigreturn(2)
+ does not complain. */
+ pushfq
+ .cfi_adjust_cfa_offset 8
+ popq UC_MCONTEXT_RFLAGS(%rdi)
+ .cfi_adjust_cfa_offset -8
+ movl $0, UC_MCONTEXT_FLAGS(%rdi)
+ movw %cs, UC_MCONTEXT_CS(%rdi)
+ movw %ss, UC_MCONTEXT_SS(%rdi)
+#if 0
+ /* Setting the flags to 0 above disables restore of segment
+ registers from the context */
+ movw %ds, UC_MCONTEXT_DS(%rdi)
+ movw %es, UC_MCONTEXT_ES(%rdi)
+ movw %fs, UC_MCONTEXT_FS(%rdi)
+ movw %gs, UC_MCONTEXT_GS(%rdi)
+#endif
+ movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi)
+#else
+#error Port me
+#endif
+
+ leaq 8(%rsp), %rax /* exclude this call. */
+ movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi)
+
+ movq 0(%rsp), %rax
+ movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi)
+
+ xorq %rax, %rax
+ retq
+ .cfi_endproc
+ .size _Ux86_64_getcontext, . - _Ux86_64_getcontext
+
+/* int _Ux86_64_getcontext_trace (ucontext_t *ucp)
+
+ Saves limited machine context in UCP necessary for libunwind.
+ Unlike _Ux86_64_getcontext, saves only the parts needed for
+ fast trace. If fast trace fails, caller will have to get the
+ full context.
+*/
+
+ .global _Ux86_64_getcontext_trace
+ .hidden _Ux86_64_getcontext_trace
+ .type _Ux86_64_getcontext_trace, @function
+_Ux86_64_getcontext_trace:
+ .cfi_startproc
+
+ /* Save only RBP, RBX, RSP, RIP - exclude this call. */
+ movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi)
+ movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi)
+
+ leaq 8(%rsp), %rax
+ movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi)
+
+ movq 0(%rsp), %rax
+ movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi)
+
+ xorq %rax, %rax
+ retq
+ .cfi_endproc
+ .size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace
+
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits