123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /* 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
|