--- src/x86_64/Gos-bsdsunix.c.orig 2021-07-08 07:34:01.503380000 +1000 +++ src/x86_64/Gos-bsdsunix.c 2021-07-08 07:34:47.992552000 +1000 @@ -0,0 +1,218 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2010 Konstantin Belousov + +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. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "unwind_i.h" +#include "ucontext_i.h" + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + /* XXXKIB */ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, b0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors_int (as); + arg = c->dwarf.as_arg; + + /* Check if RIP points at sigreturn sequence. +48 8d 7c 24 10 lea SIGF_UC(%rsp),%rdi +6a 00 pushq $0 +48 c7 c0 a1 01 00 00 movq $SYS_sigreturn,%rax +0f 05 syscall +f4 0: hlt +eb fd jmp 0b + */ + + ip = c->dwarf.ip; + c->sigcontext_format = X86_64_SCF_NONE; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0) + return 0; + w2 &= 0xffffff; + if (w0 == 0x48006a10247c8d48 && + w1 == 0x050f000001a1c0c7 && + w2 == 0x0000000000fdebf4) + { + c->sigcontext_format = X86_64_SCF_BSDSUNIX_SIGFRAME; + return (c->sigcontext_format); + } + /* Check if RIP points at standard syscall sequence. +49 89 ca mov %rcx,%r10 +0f 05 syscall + */ + if ((ret = (*a->access_mem) (as, ip - 5, &b0, 0, arg)) < 0) + return (0); + Debug (12, "b0 0x%lx\n", b0); + if ((b0 & 0xffffffffffffff) == 0x050fca89490000 || + (b0 & 0xffffffffff) == 0x050fca8949) + { + c->sigcontext_format = X86_64_SCF_BSDSUNIX_SYSCALL; + return (c->sigcontext_format); + } + return (X86_64_SCF_NONE); +} + +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ucontext; + int ret; + + if (c->sigcontext_format == X86_64_SCF_BSDSUNIX_SIGFRAME) + { + ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc); + c->sigcontext_addr = c->dwarf.cfa; + Debug(1, "signal frame, skip over trampoline\n"); + + struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + + c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); + c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); + c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); + c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); + c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); + c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); + c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); + c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); + + return 0; + } + else if (c->sigcontext_format == X86_64_SCF_BSDSUNIX_SYSCALL) + { + c->dwarf.loc[RCX] = c->dwarf.loc[R10]; + /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ + /* rbp_loc = c->dwarf.loc[RBP]; */ + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); + Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", + (unsigned long long) DWARF_GET_LOC (c->dwarf.loc[RIP]), + (unsigned long long) c->dwarf.ip); + if (ret < 0) + { + Debug (2, "returning %d\n", ret); + return ret; + } + c->dwarf.cfa += 8; + c->dwarf.use_prev_instr = 1; + return 1; + } + else + return -UNW_EBADFRAME; + +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.mc_r8; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.mc_r9; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.mc_r10; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.mc_r11; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.mc_r12; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.mc_r13; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.mc_r14; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.mc_r15; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.mc_rdi; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.mc_rsi; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.mc_rbp; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.mc_rbx; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.mc_rdx; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.mc_rax; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.mc_rcx; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.mc_rsp; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.mc_rip; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t *uc = (ucontext_t *)(c->sigcontext_addr + + offsetof(struct sigframe, sf_uc)); + + uc->uc_mcontext.mc_r8 = c->uc->uc_mcontext.mc_r8; + uc->uc_mcontext.mc_r9 = c->uc->uc_mcontext.mc_r9; + uc->uc_mcontext.mc_r10 = c->uc->uc_mcontext.mc_r10; + uc->uc_mcontext.mc_r11 = c->uc->uc_mcontext.mc_r11; + uc->uc_mcontext.mc_r12 = c->uc->uc_mcontext.mc_r12; + uc->uc_mcontext.mc_r13 = c->uc->uc_mcontext.mc_r13; + uc->uc_mcontext.mc_r14 = c->uc->uc_mcontext.mc_r14; + uc->uc_mcontext.mc_r15 = c->uc->uc_mcontext.mc_r15; + uc->uc_mcontext.mc_rdi = c->uc->uc_mcontext.mc_rdi; + uc->uc_mcontext.mc_rsi = c->uc->uc_mcontext.mc_rsi; + uc->uc_mcontext.mc_rbp = c->uc->uc_mcontext.mc_rbp; + uc->uc_mcontext.mc_rbx = c->uc->uc_mcontext.mc_rbx; + uc->uc_mcontext.mc_rdx = c->uc->uc_mcontext.mc_rdx; + uc->uc_mcontext.mc_rax = c->uc->uc_mcontext.mc_rax; + uc->uc_mcontext.mc_rcx = c->uc->uc_mcontext.mc_rcx; + uc->uc_mcontext.mc_rsp = c->uc->uc_mcontext.mc_rsp; + uc->uc_mcontext.mc_rip = c->uc->uc_mcontext.mc_rip; + + Debug (8, "resuming at ip=%llx via sigreturn(%p)\n", + (unsigned long long) c->dwarf.ip, uc); + sigreturn(uc); + abort(); +} +#endif --- src/x86_64/Gregs.c.orig 2021-07-08 07:36:21.405423000 +1000 +++ src/x86_64/Gregs.c 2021-07-08 07:37:36.095473000 +1000 @@ -41,10 +41,15 @@ case X86_64_SCF_LINUX_RT_SIGFRAME: addr += LINUX_UC_MCONTEXT_OFF; break; - +#ifdef __FreeBSD__ case X86_64_SCF_FREEBSD_SIGFRAME: addr += FREEBSD_UC_MCONTEXT_OFF; break; +#else + case X86_64_SCF_BSDSUNIX_SIGFRAME: + addr += BSDSUNIX_UC_MCONTEXT_OFF; + break; +#endif } return DWARF_REG_LOC (&c->dwarf, reg); --- src/x86_64/getcontext.S.orig 2021-07-08 07:38:03.748474000 +1000 +++ src/x86_64/getcontext.S 2021-07-08 07:39:23.401186000 +1000 @@ -66,7 +66,7 @@ #endif // UC_MCONTEXT_FPREGS_PTR fnstenv (%r8) stmxcsr FPREGS_OFFSET_MXCSR(%r8) -#elif defined __FreeBSD__ +#elif defined __FreeBSD__ | defined __BSDSUniX__ fxsave UC_MCONTEXT_FPSTATE(%rdi) movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi) --- src/x86_64/init.h.orig 2021-07-08 07:39:34.889029000 +1000 +++ src/x86_64/init.h 2021-07-08 07:40:02.322684000 +1000 @@ -32,7 +32,7 @@ # define REG_INIT_LOC(c, rlc, ruc) \ DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.gregs[REG_ ## ruc], 0) -#elif defined UNW_LOCAL_ONLY && defined __FreeBSD__ +#elif defined UNW_LOCAL_ONLY && (defined __FreeBSD__ || defined __BSDSUniX__) # define REG_INIT_LOC(c, rlc, ruc) \ DWARF_LOC ((unw_word_t) &c->uc->uc_mcontext.mc_ ## rlc, 0) --- src/x86_64/offsets.h.orig 2021-07-08 07:35:21.063595000 +1000 +++ src/x86_64/offsets.h 2021-07-08 07:35:54.370354000 +1000 @@ -1,3 +1,6 @@ /* FreeBSD specific definitions */ #define FREEBSD_UC_MCONTEXT_OFF 0x10 + +/* BSDSUniX specific definitions */ +#define BSDSUNIX_UC_MCONTEXT_OFF 0x10 --- src/x86_64/setcontext.S.orig 2021-07-08 07:40:20.470799000 +1000 +++ src/x86_64/setcontext.S 2021-07-08 07:40:43.392064000 +1000 @@ -46,7 +46,7 @@ #endif // UC_MCONTEXT_FPREGS_PTR fldenv (%r8) ldmxcsr FPREGS_OFFSET_MXCSR(%r8) -#elif defined __FreeBSD__ +#elif defined __FreeBSD__ || defined __BSDSUniX__ /* restore fp state */ cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi) jne 1f --- src/x86_64/ucontext_i.h.orig 2021-07-08 07:40:58.789431000 +1000 +++ src/x86_64/ucontext_i.h 2021-07-08 07:41:20.102412000 +1000 @@ -44,7 +44,7 @@ #define UC_MCONTEXT_FPREGS_MEM 0xe0 #define UC_SIGMASK 0x128 #define FPREGS_OFFSET_MXCSR 0x18 -#elif defined __FreeBSD__ +#elif defined __FreeBSD__ || defined __BSDSUniX__ #define UC_SIGMASK 0x0 #define UC_MCONTEXT_GREGS_RDI 0x18 #define UC_MCONTEXT_GREGS_RSI 0x20