wip/hplibunwind-git: import hplibunwind-1.1.0nb20180906

The primary goal of this project is to define a portable and efficient C
programming interface (API) to determine the call-chain of a program. The API
additionally provides the means to manipulate the preserved (callee-saved)
state of each call-frame and to resume execution at any point in the call-chain
(non-local goto). The API supports both local (same-process) and remote
(across-process) operation. As such, the API is useful in a number of
applications.

Some examples include:
- exception handling
    The libunwind API makes it trivial to implement the stack-manipulation
    aspects of exception handling.
- debuggers
    The libunwind API makes it trivial for debuggers to generate the call-chain
    (backtrace) of the threads in a running program.
- introspection
    It is often useful for a running thread to determine its call-chain. For
    example, this is useful to display error messages (to show how the error
    came about) and for performance monitoring/analysis.
- efficient setjmp()
    With libunwind, it is possible to implement an extremely efficient version
    of setjmp(). Effectively, the only context that needs to be saved consists
    of the stack-pointer(s).
This commit is contained in:
Kamil Rytarowski 2018-09-07 00:55:18 +02:00
parent 1d7ba11822
commit cb53a98405
23 changed files with 1241 additions and 0 deletions

23
hplibunwind-git/DESCR Normal file
View File

@ -0,0 +1,23 @@
The primary goal of this project is to define a portable and efficient C
programming interface (API) to determine the call-chain of a program. The API
additionally provides the means to manipulate the preserved (callee-saved)
state of each call-frame and to resume execution at any point in the call-chain
(non-local goto). The API supports both local (same-process) and remote
(across-process) operation. As such, the API is useful in a number of
applications.
Some examples include:
- exception handling
The libunwind API makes it trivial to implement the stack-manipulation
aspects of exception handling.
- debuggers
The libunwind API makes it trivial for debuggers to generate the call-chain
(backtrace) of the threads in a running program.
- introspection
It is often useful for a running thread to determine its call-chain. For
example, this is useful to display error messages (to show how the error
came about) and for performance monitoring/analysis.
- efficient setjmp()
With libunwind, it is possible to implement an extremely efficient version
of setjmp(). Effectively, the only context that needs to be saved consists
of the stack-pointer(s).

31
hplibunwind-git/Makefile Normal file
View File

@ -0,0 +1,31 @@
# $NetBSD: Makefile.common,v 1.7 2015/07/20 05:49:53 adam Exp $
PKGNAME= hplibunwind-1.1.0
CATEGORIES= lang devel
GIT_REPOSITORIES= libunwind
GIT_REPO.libunwind= http://git.savannah.gnu.org/r/libunwind.git
MAINTAINER= pkgsrc-users@NetBSD.org
HOMEPAGE= http://www.nongnu.org/libunwind/
COMMENT= NONGNU libunwind
LICENSE= mit
WRKSRC= ${WRKDIR}/libunwind
GNU_CONFIGURE= yes
USE_TOOLS+= autoreconf autoconf automake
USE_LIBTOOL= yes
USE_LANGUAGES= c c++
CONFIGURE_ARGS+= --disable-coredump
CONFIGURE_ARGS+= --enable-tests
pre-configure:
${RUN} cd ${WRKSRC} && pwd && ./autogen.sh
.include "../../wip/mk/git-package.mk"
.include "../../wip/llvm-git/buildlink3.mk"
.include "../../mk/bsd.pkg.mk"

17
hplibunwind-git/PLIST Normal file
View File

@ -0,0 +1,17 @@
@comment $NetBSD$
include/libunwind-common.h
include/libunwind-dynamic.h
include/libunwind-ptrace.h
include/libunwind-x86_64.h
include/libunwind.h
include/unwind.h
lib/libunwind-generic.a
lib/libunwind-generic.so
lib/libunwind-ptrace.la
lib/libunwind-setjmp.la
lib/libunwind-x86_64.la
lib/libunwind.la
lib/pkgconfig/libunwind-generic.pc
lib/pkgconfig/libunwind-ptrace.pc
lib/pkgconfig/libunwind-setjmp.pc
lib/pkgconfig/libunwind.pc

View File

@ -0,0 +1,13 @@
# $NetBSD$
BUILDLINK_TREE+= nongnu-libunwind
.if !defined(NONGNU_LIBUNWIND_BUILDLINK3_MK)
NONGNU_LIBUNWIND_BUILDLINK3_MK:=
BUILDLINK_API_DEPENDS.nongnu-libunwind+= non-libunwind>=1.1nb20151127
BUILDLINK_PKGSRCDIR.nongnu-libunwind?= ../../wip/nongnu-libunwind-git
.endif # NONGNU_LIBUNWIND_BUILDLINK3_MK
BUILDLINK_TREE+= -nongnu-libunwind

32
hplibunwind-git/distinfo Normal file
View File

@ -0,0 +1,32 @@
$NetBSD: distinfo,v 1.35 2015/09/11 01:21:57 tnn Exp $
SHA1 (cfe-3.6.2.src.tar.xz) = 7ba809c9c17819a16b668640a642ed134d7052f0
RMD160 (cfe-3.6.2.src.tar.xz) = 10d913b4d5317f8c2520e5fc6117df30937317a8
Size (cfe-3.6.2.src.tar.xz) = 8617576 bytes
SHA1 (compiler-rt-3.6.2.src.tar.xz) = c6c52d2923a60f1a2ca2f22fea1770fd2e25728d
RMD160 (compiler-rt-3.6.2.src.tar.xz) = 9b68a32d49d4bef4603d550934192f39fea42895
Size (compiler-rt-3.6.2.src.tar.xz) = 1128080 bytes
SHA1 (libcxx-3.6.2.src.tar.xz) = 6c5aee9f05ecf17d1e3ecb1add34a33a5a904469
RMD160 (libcxx-3.6.2.src.tar.xz) = 42b8832d01d4e6b553babc93cb5dbd4ce2bb1931
Size (libcxx-3.6.2.src.tar.xz) = 944020 bytes
SHA1 (llvm-3.6.2.src.tar.xz) = 7a00257eb2bc9431e4c77c3a36b033072c54bc7e
RMD160 (llvm-3.6.2.src.tar.xz) = 521cbc5fe2925ea3c6e90c7a31f752a04045c972
Size (llvm-3.6.2.src.tar.xz) = 12802380 bytes
SHA1 (patch-configure.ac) = b989360cb443b8ce31499e84ea6f84192b9fc305
SHA1 (patch-include_tdep-x86__64_jmpbuf.h) = a2c8f1894c3476e6efb4e3f47145a235a31d2e83
SHA1 (patch-include_tdep-x86__64_libunwind__i.h) = cc36cb94e9b807794c041096fd8eadfd4cb45da5
SHA1 (patch-src_Makefile.am) = 663e12ea40e58058a2e0473c5ef5f6b8ed1e6881
SHA1 (patch-src_coredump___UCD__create.c) = 154b87069833adb922f4d1353ac62e2ebac8879e
SHA1 (patch-src_os-netbsd.c) = 65bf98a33289a21a6af012a62631faf9ceff568a
SHA1 (patch-src_ptrace___UPT__access__fpreg.c) = be943875cdc5049e6ff2bb59beda63ce9be1379b
SHA1 (patch-src_ptrace___UPT__access__reg.c) = 0341a6a879905852814ee233452e305840af1c6b
SHA1 (patch-src_ptrace___UPT__reg__offset.c) = d8ba12ce138cba7f7dd909291c0a64411755a36f
SHA1 (patch-src_setjmp_siglongjmp.c) = 03e2b4328662d44bed16c58916a772b26b5c6577
SHA1 (patch-src_x86_Gos-netbsd.c) = c9310e02439b731e6d5ecec7d84875abe4cdc6b1
SHA1 (patch-src_x86_Los-netbsd.c) = 3a1a888bde4c416ddc355cb6b5e776401561ee0a
SHA1 (patch-src_x86__64_Gos-netbsd.c) = ff6e1f76f50a988f5be288047d27095cf322c16c
SHA1 (patch-src_x86__64_Los-netbsd.c) = bf3ff9f374076b358458886d78c260e9806f6799
SHA1 (patch-src_x86__64_getcontext.S) = 4ddd6b53f432488ac85e7c3067d331ca429f79b6
SHA1 (patch-src_x86__64_setcontext.S) = 0be36e0ffc09cff8d4a2822aa966675e6ee089e1
SHA1 (patch-src_x86__64_ucontext__i.h) = 34ca3b15d5cde083c410a401348733a251fa1417
SHA1 (patch-src_x86_getcontext-netbsd.S) = c88ae78218abee5cb37fbb7a547502519ccef1b0

View File

@ -0,0 +1,21 @@
$NetBSD$
--- configure.ac.orig 2018-09-04 09:38:02.000000000 +0000
+++ configure.ac
@@ -136,7 +136,7 @@ AC_MSG_RESULT([$enable_ptrace])
AC_ARG_ENABLE(setjmp,
AS_HELP_STRING([--enable-setjmp],[building libunwind-setjmp library]),,
- [AS_IF([test x$target_arch == x$host_arch], [enable_setjmp=yes], [enable_setjmp=no])]
+ [AS_IF([test x$target_arch = x$host_arch], [enable_setjmp=yes], [enable_setjmp=no])]
)
AC_ARG_ENABLE(documentation,
@@ -179,6 +179,7 @@ AM_CONDITIONAL(ARCH_S390X, test x$target
AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null)
AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null)
AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null)
+AM_CONDITIONAL(OS_NETBSD, expr x$target_os : xnetbsd >/dev/null)
AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null)
AC_MSG_CHECKING([for ELF helper width])

View File

@ -0,0 +1,16 @@
$NetBSD$
--- include/tdep-x86_64/jmpbuf.h.orig 2018-09-04 09:38:02.000000000 +0000
+++ include/tdep-x86_64/jmpbuf.h
@@ -40,4 +40,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
#define JB_MASK_SAVED 0
#define JB_MASK 9
+#elif defined __NetBSD__
+
+#define JB_SP 6
+#define JB_RP 7
+#define JB_MASK_SAVED 8
+#define JB_MASK 9
+
#endif

View File

@ -0,0 +1,22 @@
$NetBSD$
--- include/tdep-x86_64/libunwind_i.h.orig 2018-09-04 09:38:02.000000000 +0000
+++ include/tdep-x86_64/libunwind_i.h
@@ -200,7 +200,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf
#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path)
#define tdep_access_reg UNW_OBJ(access_reg)
#define tdep_access_fpreg UNW_OBJ(access_fpreg)
-#if __linux__
+#if __linux__ || __NetBSD__
# define tdep_fetch_frame UNW_OBJ(fetch_frame)
# define tdep_cache_frame UNW_OBJ(cache_frame)
# define tdep_reuse_frame UNW_OBJ(reuse_frame)
@@ -248,7 +248,7 @@ extern int tdep_access_reg (struct curso
unw_word_t *valp, int write);
extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
unw_fpreg_t *valp, int write);
-#if __linux__
+#if __linux__ || __NetBSD__
extern void tdep_fetch_frame (struct dwarf_cursor *c, unw_word_t ip,
int need_unwind_info);
extern int tdep_cache_frame (struct dwarf_cursor *c);

View File

@ -0,0 +1,35 @@
$NetBSD$
--- src/Makefile.am.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/Makefile.am
@@ -152,6 +152,8 @@ libunwind_la_SOURCES_os_hpux = os-hpux.c
libunwind_la_SOURCES_os_freebsd = os-freebsd.c
+libunwind_la_SOURCES_os_netbsd = os-netbsd.c
+
libunwind_la_SOURCES_os_qnx = os-qnx.c
libunwind_dwarf_common_la_SOURCES = dwarf/global.c
@@ -538,6 +540,13 @@ if OS_FREEBSD
libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c
endif
+if OS_NETBSD
+ libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_netbsd)
+ libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_netbsd_local)
+ libunwind_la_SOURCES_x86_64_os = x86_64/Gos-netbsd.c
+ libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-netbsd.c
+endif
+
if OS_QNX
libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx)
libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local)
@@ -738,6 +747,7 @@ EXTRA_DIST = $(libunwind_la_SOURCES_aarc
$(libunwind_la_SOURCES_sh) \
$(libunwind_la_SOURCES_x86) \
$(libunwind_la_SOURCES_os_freebsd) \
+ $(libunwind_la_SOURCES_os_netbsd) \
$(libunwind_la_SOURCES_os_linux) \
$(libunwind_la_SOURCES_os_hpux) \
$(libunwind_la_SOURCES_os_qnx) \

View File

@ -0,0 +1,14 @@
$NetBSD$
--- src/coredump/_UCD_create.c.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/coredump/_UCD_create.c
@@ -61,7 +61,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
#endif
#include <elf.h>
+#ifdef HAVE_SYS_PROCFS_H
#include <sys/procfs.h> /* struct elf_prstatus */
+#endif
#include "_UCD_lib.h"
#include "_UCD_internal.h"

View File

@ -0,0 +1,124 @@
$NetBSD$
--- src/os-netbsd.c.orig 2018-09-05 10:31:53.462583014 +0000
+++ src/os-netbsd.c
@@ -0,0 +1,119 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2018 Kamil Rytarowski <n54@gmx.com>
+
+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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "libunwind_i.h"
+
+static void *
+get_mem(size_t sz)
+{
+ void *res;
+
+ res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (res == MAP_FAILED)
+ return (NULL);
+ return (res);
+}
+
+static void
+free_mem(void *ptr, size_t sz)
+{
+ munmap(ptr, sz);
+}
+
+int
+tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
+ unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen)
+{
+ int mib[5], error, ret;
+ size_t len, len1;
+ char *buf, *bp, *eb;
+ struct kinfo_vmentry *kv;
+
+ len = 0;
+ mib[0] = CTL_VM;
+ mib[1] = VM_PROC;
+ mib[2] = VM_PROC_MAP;
+ mib[3] = pid;
+ mib[4] = sizeof(struct kinfo_vmentry);
+
+ error = sysctl(mib, 4, NULL, &len, NULL, 0);
+ if (error == -1)
+ return (-UNW_EUNSPEC);
+ len1 = len * 4 / 3;
+ buf = get_mem(len1);
+ if (buf == NULL)
+ return (-UNW_EUNSPEC);
+ len = len1;
+ error = sysctl(mib, 4, buf, &len, NULL, 0);
+ if (error == -1) {
+ free_mem(buf, len1);
+ return (-UNW_EUNSPEC);
+ }
+ ret = -UNW_EUNSPEC;
+ for (bp = buf, eb = buf + len; bp < eb; bp += sizeof(struct kinfo_vmentry)) {
+ kv = (struct kinfo_vmentry *)(uintptr_t)bp;
+ if (ip < kv->kve_start || ip >= kv->kve_end)
+ continue;
+ if (kv->kve_type != KVME_TYPE_VNODE)
+ continue;
+ *segbase = kv->kve_start;
+ *mapoff = kv->kve_offset;
+ if (path)
+ {
+ strncpy(path, kv->kve_path, pathlen);
+ }
+ ret = elf_map_image (ei, kv->kve_path);
+ break;
+ }
+ free_mem(buf, len1);
+ return (ret);
+}
+
+#ifndef UNW_REMOTE_ONLY
+
+void
+tdep_get_exe_image_path (char *path)
+{
+ int mib[4], error;
+ size_t len;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = -1;
+ mib[3] = KERN_PROC_PATHNAME;
+
+ error = sysctl(mib, 4, path, &len, NULL, 0);
+ if (error == -1)
+ path[0] = 0;
+}
+
+#endif

View File

@ -0,0 +1,40 @@
$NetBSD$
--- src/ptrace/_UPT_access_fpreg.c.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/ptrace/_UPT_access_fpreg.c
@@ -73,7 +73,11 @@ _UPT_access_fpreg (unw_addr_space_t as,
{
struct UPT_info *ui = arg;
pid_t pid = ui->pid;
+#if defined __NetBSD__
+ __fpregset_t fpreg;
+#else
fpregset_t fpreg;
+#endif
#if defined(__amd64__)
if (1) /* XXXKIB */
@@ -97,7 +101,11 @@ _UPT_access_fpreg (unw_addr_space_t as,
return -UNW_EBADREG;
if (write) {
#if defined(__amd64__)
+#if defined __NetBSD__
+ memcpy(&((struct fxsave*)&fpreg)->fx_xmm[reg], val, sizeof(unw_fpreg_t));
+#else
memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t));
+#endif
#elif defined(__i386__)
memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t));
#elif defined(__arm__)
@@ -111,7 +119,11 @@ _UPT_access_fpreg (unw_addr_space_t as,
return -UNW_EBADREG;
} else
#if defined(__amd64__)
+#if defined __NetBSD__
+ memcpy(val, &((struct fxsave*)&fpreg)->fx_xmm[reg], sizeof(unw_fpreg_t));
+#else
memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t));
+#endif
#elif defined(__i386__)
memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t));
#elif defined(__arm__)

View File

@ -0,0 +1,16 @@
$NetBSD$
--- src/ptrace/_UPT_access_reg.c.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/ptrace/_UPT_access_reg.c
@@ -318,7 +318,11 @@ _UPT_access_reg (unw_addr_space_t as, un
{
struct UPT_info *ui = arg;
pid_t pid = ui->pid;
+#if defined __NetBSD__
+ __gregset_t regs;
+#else
gregset_t regs;
+#endif
char *r;
#if UNW_DEBUG

View File

@ -0,0 +1,35 @@
$NetBSD$
--- src/ptrace/_UPT_reg_offset.c.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/ptrace/_UPT_reg_offset.c
@@ -311,6 +311,30 @@ const int _UPT_reg_offset[UNW_REG_LAST +
// UNW_R_OFF(EFLAGS, rflags)
// UNW_R_OFF(SS, ss)
#undef UNW_R_OFF
+#elif defined __NetBSD__
+#define UNW_R_OFF(R, r) \
+ [UNW_X86_64_##R] = _REG_##R * 8,
+ UNW_R_OFF(RAX, rax)
+ UNW_R_OFF(RDX, rdx)
+ UNW_R_OFF(RCX, rcx)
+ UNW_R_OFF(RBX, rbx)
+ UNW_R_OFF(RSI, rsi)
+ UNW_R_OFF(RDI, rdi)
+ UNW_R_OFF(RBP, rbp)
+ UNW_R_OFF(RSP, rsp)
+ UNW_R_OFF(R8, r8)
+ UNW_R_OFF(R9, r9)
+ UNW_R_OFF(R10, r10)
+ UNW_R_OFF(R11, r11)
+ UNW_R_OFF(R12, r12)
+ UNW_R_OFF(R13, r13)
+ UNW_R_OFF(R14, r14)
+ UNW_R_OFF(R15, r15)
+ UNW_R_OFF(RIP, rip)
+// UNW_R_OFF(CS, cs)
+// UNW_R_OFF(EFLAGS, rflags)
+// UNW_R_OFF(SS, ss)
+#undef UNW_R_OFF
#elif defined __linux__
[UNW_X86_64_RAX] = 0x50,
[UNW_X86_64_RDX] = 0x60,

View File

@ -0,0 +1,13 @@
$NetBSD$
--- src/setjmp/siglongjmp.c.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/setjmp/siglongjmp.c
@@ -103,7 +103,7 @@ siglongjmp (sigjmp_buf env, int val)
|| (_NSIG > 8 * sizeof (unw_word_t)
&& unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0))
abort ();
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0)
abort();
#else

View File

@ -0,0 +1,379 @@
$NetBSD$
--- src/x86/Gos-netbsd.c.orig 2018-09-05 10:31:53.492275380 +0000
+++ src/x86/Gos-netbsd.c
@@ -0,0 +1,374 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2018 Januk Rytarowski <n54@gmx.com>
+
+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 <sys/types.h>
+#include <signal.h>
+#include <stddef.h>
+#include <ucontext.h>
+#include <machine/sigframe.h>
+
+#include "unwind_i.h"
+#include "offsets.h"
+
+int
+unw_is_signal_frame (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ unw_word_t w0, w1, w2, w3, w4, w5, 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 EIP points at sigreturn() sequence. It can be:
+sigcode+4: from amd64 freebsd32 environment
+8d 44 24 20 lea 0x20(%esp),%eax
+50 push %eax
+b8 a1 01 00 00 mov $0x1a1,%eax
+50 push %eax
+cd 80 int $0x80
+
+sigcode+4: from real i386
+8d 44 24 20 lea 0x20(%esp),%eax
+50 push %eax
+f7 40 54 00 02 00 testl $0x20000,0x54(%eax)
+75 03 jne sigcode+21
+8e 68 14 mov 0x14(%eax),%gs
+b8 a1 01 00 00 mov $0x1a1,%eax
+50 push %eax
+cd 80 int $0x80
+
+freebsd4_sigcode+4:
+XXX
+osigcode:
+XXX
+ */
+ ip = c->dwarf.ip;
+ ret = X86_SCF_NONE;
+ c->sigcontext_format = ret;
+ if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 ||
+ (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0 ||
+ (*a->access_mem) (as, ip + 8, &w2, 0, arg) < 0 ||
+ (*a->access_mem) (as, ip + 12, &w3, 0, arg) < 0)
+ return ret;
+ if (w0 == 0x2024448d && w1 == 0x01a1b850 && w2 == 0xcd500000 &&
+ (w3 & 0xff) == 0x80)
+ ret = X86_SCF_FREEBSD_SIGFRAME;
+ else {
+ if ((*a->access_mem) (as, ip + 16, &w4, 0, arg) < 0 ||
+ (*a->access_mem) (as, ip + 20, &w5, 0, arg) < 0)
+ return ret;
+ if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 &&
+ w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000)
+ ret = X86_SCF_FREEBSD_SIGFRAME;
+ }
+
+ /* Check for syscall */
+ if (ret == X86_SCF_NONE && (*a->access_mem) (as, ip - 2, &w0, 0, arg) >= 0 &&
+ (w0 & 0xffff) == 0x80cd)
+ ret = X86_SCF_FREEBSD_SYSCALL;
+ Debug (16, "returning %d\n", ret);
+ c->sigcontext_format = ret;
+ return (ret);
+}
+
+HIDDEN int
+x86_handle_signal_frame (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ int ret;
+
+ if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
+ struct sigframe *sf;
+ uintptr_t uc_addr;
+ struct dwarf_loc esp_loc;
+
+ sf = (struct sigframe *)c->dwarf.cfa;
+ uc_addr = (uintptr_t)&(sf->sf_uc);
+ c->sigcontext_addr = c->dwarf.cfa;
+
+ esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0);
+ ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
+ if (ret < 0)
+ {
+ Debug (2, "returning 0\n");
+ return 0;
+ }
+
+ c->dwarf.loc[EIP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0);
+ c->dwarf.loc[ESP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0);
+ c->dwarf.loc[EAX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EAX_OFF, 0);
+ c->dwarf.loc[ECX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ECX_OFF, 0);
+ c->dwarf.loc[EDX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDX_OFF, 0);
+ c->dwarf.loc[EBX] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBX_OFF, 0);
+ c->dwarf.loc[EBP] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0);
+ c->dwarf.loc[ESI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESI_OFF, 0);
+ c->dwarf.loc[EDI] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EDI_OFF, 0);
+ c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0);
+ c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_TRAPNO_OFF, 0);
+ c->dwarf.loc[ST0] = DWARF_NULL_LOC;
+ } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) {
+ c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0);
+ c->dwarf.loc[EAX] = DWARF_NULL_LOC;
+ c->dwarf.cfa += 4;
+ c->dwarf.use_prev_instr = 1;
+ } else {
+ Debug (8, "Gstep: not handling frame format %d\n", c->sigcontext_format);
+ abort();
+ }
+ return 0;
+}
+
+HIDDEN dwarf_loc_t
+x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg)
+{
+ unw_word_t addr = c->sigcontext_addr, off, xmm_off;
+ unw_word_t fpstate, fpformat;
+ int ret, is_fpstate = 0, is_xmmstate = 0;
+
+ switch (c->sigcontext_format)
+ {
+ case X86_SCF_NONE:
+ return DWARF_REG_LOC (&c->dwarf, reg);
+
+ case X86_SCF_FREEBSD_SIGFRAME:
+ addr += offsetof(struct sigframe, sf_uc) + FREEBSD_UC_MCONTEXT_OFF;
+ break;
+
+ case X86_SCF_FREEBSD_SIGFRAME4:
+ abort();
+ break;
+
+ case X86_SCF_FREEBSD_OSIGFRAME:
+ /* XXXKIB */
+ abort();
+ break;
+
+ case X86_SCF_FREEBSD_SYSCALL:
+ /* XXXKIB */
+ abort();
+ break;
+
+ default:
+ /* XXXKIB */
+ abort();
+ break;
+ }
+
+ off = 0; /* shut gcc warning */
+ switch (reg)
+ {
+ case UNW_X86_GS: off = FREEBSD_UC_MCONTEXT_GS_OFF; break;
+ case UNW_X86_FS: off = FREEBSD_UC_MCONTEXT_FS_OFF; break;
+ case UNW_X86_ES: off = FREEBSD_UC_MCONTEXT_ES_OFF; break;
+ case UNW_X86_DS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break;
+ case UNW_X86_EDI: off = FREEBSD_UC_MCONTEXT_EDI_OFF; break;
+ case UNW_X86_ESI: off = FREEBSD_UC_MCONTEXT_ESI_OFF; break;
+ case UNW_X86_EBP: off = FREEBSD_UC_MCONTEXT_EBP_OFF; break;
+ case UNW_X86_ESP: off = FREEBSD_UC_MCONTEXT_ESP_OFF; break;
+ case UNW_X86_EBX: off = FREEBSD_UC_MCONTEXT_EBX_OFF; break;
+ case UNW_X86_EDX: off = FREEBSD_UC_MCONTEXT_EDX_OFF; break;
+ case UNW_X86_ECX: off = FREEBSD_UC_MCONTEXT_ECX_OFF; break;
+ case UNW_X86_EAX: off = FREEBSD_UC_MCONTEXT_EAX_OFF; break;
+ case UNW_X86_TRAPNO: off = FREEBSD_UC_MCONTEXT_TRAPNO_OFF; break;
+ case UNW_X86_EIP: off = FREEBSD_UC_MCONTEXT_EIP_OFF; break;
+ case UNW_X86_CS: off = FREEBSD_UC_MCONTEXT_CS_OFF; break;
+ case UNW_X86_EFLAGS: off = FREEBSD_UC_MCONTEXT_EFLAGS_OFF; break;
+ case UNW_X86_SS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break;
+
+ case UNW_X86_FCW:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_CW_OFF;
+ xmm_off = FREEBSD_UC_MCONTEXT_CW_XMM_OFF;
+ break;
+ case UNW_X86_FSW:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_SW_OFF;
+ xmm_off = FREEBSD_UC_MCONTEXT_SW_XMM_OFF;
+ break;
+ case UNW_X86_FTW:
+ is_fpstate = 1;
+ xmm_off = FREEBSD_UC_MCONTEXT_TAG_XMM_OFF;
+ off = FREEBSD_UC_MCONTEXT_TAG_OFF;
+ break;
+ case UNW_X86_FCS:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_CSSEL_OFF;
+ xmm_off = FREEBSD_UC_MCONTEXT_CSSEL_XMM_OFF;
+ break;
+ case UNW_X86_FIP:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_IPOFF_OFF;
+ xmm_off = FREEBSD_UC_MCONTEXT_IPOFF_XMM_OFF;
+ break;
+ case UNW_X86_FEA:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_DATAOFF_OFF;
+ xmm_off = FREEBSD_UC_MCONTEXT_DATAOFF_XMM_OFF;
+ break;
+ case UNW_X86_FDS:
+ is_fpstate = 1;
+ off = FREEBSD_US_MCONTEXT_DATASEL_OFF;
+ xmm_off = FREEBSD_US_MCONTEXT_DATASEL_XMM_OFF;
+ break;
+ case UNW_X86_MXCSR:
+ is_fpstate = 1;
+ is_xmmstate = 1;
+ xmm_off = FREEBSD_UC_MCONTEXT_MXCSR_XMM_OFF;
+ break;
+
+ /* stacked fp registers */
+ case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3:
+ case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7:
+ is_fpstate = 1;
+ off = FREEBSD_UC_MCONTEXT_ST0_OFF + 10*(reg - UNW_X86_ST0);
+ xmm_off = FREEBSD_UC_MCONTEXT_ST0_XMM_OFF + 10*(reg - UNW_X86_ST0);
+ break;
+
+ /* SSE fp registers */
+ case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi:
+ case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi:
+ case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi:
+ case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi:
+ case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi:
+ case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi:
+ case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi:
+ case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi:
+ is_fpstate = 1;
+ is_xmmstate = 1;
+ xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo);
+ break;
+ case UNW_X86_XMM0:
+ case UNW_X86_XMM1:
+ case UNW_X86_XMM2:
+ case UNW_X86_XMM3:
+ case UNW_X86_XMM4:
+ case UNW_X86_XMM5:
+ case UNW_X86_XMM6:
+ case UNW_X86_XMM7:
+ is_fpstate = 1;
+ is_xmmstate = 1;
+ xmm_off = FREEBSD_UC_MCONTEXT_XMM0_OFF + 16*(reg - UNW_X86_XMM0);
+ break;
+
+ case UNW_X86_FOP:
+ case UNW_X86_TSS:
+ case UNW_X86_LDT:
+ default:
+ return DWARF_REG_LOC (&c->dwarf, reg);
+ }
+
+ if (is_fpstate)
+ {
+ if ((ret = dwarf_get (&c->dwarf,
+ DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPSTATE_OFF),
+ &fpstate)) < 0)
+ return DWARF_NULL_LOC;
+ if (fpstate == FREEBSD_UC_MCONTEXT_FPOWNED_NONE)
+ return DWARF_NULL_LOC;
+ if ((ret = dwarf_get (&c->dwarf,
+ DWARF_MEM_LOC (&c->dwarf, addr + FREEBSD_UC_MCONTEXT_FPFORMAT_OFF),
+ &fpformat)) < 0)
+ return DWARF_NULL_LOC;
+ if (fpformat == FREEBSD_UC_MCONTEXT_FPFMT_NODEV ||
+ (is_xmmstate && fpformat != FREEBSD_UC_MCONTEXT_FPFMT_XMM))
+ return DWARF_NULL_LOC;
+ if (is_xmmstate)
+ off = xmm_off;
+ }
+
+ return DWARF_MEM_LOC (c, addr + off);
+}
+
+#ifndef UNW_REMOTE_ONLY
+HIDDEN void *
+x86_r_uc_addr (ucontext_t *uc, int reg)
+{
+ void *addr;
+
+ switch (reg)
+ {
+ case UNW_X86_GS: addr = &uc->uc_mcontext.mc_gs; break;
+ case UNW_X86_FS: addr = &uc->uc_mcontext.mc_fs; break;
+ case UNW_X86_ES: addr = &uc->uc_mcontext.mc_es; break;
+ case UNW_X86_DS: addr = &uc->uc_mcontext.mc_ds; break;
+ case UNW_X86_EAX: addr = &uc->uc_mcontext.mc_eax; break;
+ case UNW_X86_EBX: addr = &uc->uc_mcontext.mc_ebx; break;
+ case UNW_X86_ECX: addr = &uc->uc_mcontext.mc_ecx; break;
+ case UNW_X86_EDX: addr = &uc->uc_mcontext.mc_edx; break;
+ case UNW_X86_ESI: addr = &uc->uc_mcontext.mc_esi; break;
+ case UNW_X86_EDI: addr = &uc->uc_mcontext.mc_edi; break;
+ case UNW_X86_EBP: addr = &uc->uc_mcontext.mc_ebp; break;
+ case UNW_X86_EIP: addr = &uc->uc_mcontext.mc_eip; break;
+ case UNW_X86_ESP: addr = &uc->uc_mcontext.mc_esp; break;
+ case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.mc_trapno; break;
+ case UNW_X86_CS: addr = &uc->uc_mcontext.mc_cs; break;
+ case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.mc_eflags; break;
+ case UNW_X86_SS: addr = &uc->uc_mcontext.mc_ss; break;
+
+ default:
+ addr = NULL;
+ }
+ return addr;
+}
+
+HIDDEN int
+x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ ucontext_t *uc = c->uc;
+
+ /* Ensure c->pi is up-to-date. On x86, it's relatively common to be
+ missing DWARF unwind info. We don't want to fail in that case,
+ because the frame-chain still would let us do a backtrace at
+ least. */
+ dwarf_make_proc_info (&c->dwarf);
+
+ if (c->sigcontext_format == X86_SCF_NONE) {
+ Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
+ setcontext (uc);
+ abort();
+ } else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
+ struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
+
+ Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
+ sigreturn((ucontext_t *)((const char *)sc + FREEBSD_SC_UCONTEXT_OFF));
+ abort();
+ } else {
+ Debug (8, "resuming at ip=%x for sigcontext format %d not implemented\n",
+ c->dwarf.ip, c->sigcontext_format);
+ abort();
+ }
+ return -UNW_EINVAL;
+}
+
+#endif

View File

@ -0,0 +1,10 @@
$NetBSD$
--- src/x86/Los-netbsd.c.orig 2018-09-05 10:31:53.499471982 +0000
+++ src/x86/Los-netbsd.c
@@ -0,0 +1,5 @@
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
+#include "Gos-netbsd.c"
+#endif

View File

@ -0,0 +1,163 @@
$NetBSD$
--- src/x86_64/Gos-netbsd.c.orig 2018-09-05 10:31:53.514510455 +0000
+++ src/x86_64/Gos-netbsd.c
@@ -0,0 +1,158 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2002-2003 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
+
+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 "unwind_i.h"
+#include "ucontext_i.h"
+
+#include <sys/syscall.h>
+
+HIDDEN void
+tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info)
+{
+ struct cursor *c = (struct cursor *) dw;
+ assert(! need_unwind_info || dw->pi_valid);
+ assert(! need_unwind_info || dw->pi.unwind_info);
+ if (dw->pi_valid
+ && dw->pi.unwind_info
+ && ((struct dwarf_cie_info *) dw->pi.unwind_info)->signal_frame)
+ c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME;
+ else
+ c->sigcontext_format = X86_64_SCF_NONE;
+
+ Debug(5, "fetch frame ip=0x%lx cfa=0x%lx format=%d\n",
+ dw->ip, dw->cfa, c->sigcontext_format);
+}
+
+HIDDEN int
+tdep_cache_frame (struct dwarf_cursor *dw)
+{
+ struct cursor *c = (struct cursor *) dw;
+
+ Debug(5, "cache frame ip=0x%lx cfa=0x%lx format=%d\n",
+ dw->ip, dw->cfa, c->sigcontext_format);
+ return c->sigcontext_format;
+}
+
+HIDDEN void
+tdep_reuse_frame (struct dwarf_cursor *dw, int frame)
+{
+ struct cursor *c = (struct cursor *) dw;
+ c->sigcontext_format = frame;
+ if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME)
+ {
+ c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN;
+ /* Offset from cfa to ucontext_t in signal frame. */
+ c->frame_info.cfa_reg_offset = 0;
+ c->sigcontext_addr = dw->cfa;
+ }
+
+ Debug(5, "reuse frame ip=0x%lx cfa=0x%lx format=%d addr=0x%lx offset=%+d\n",
+ dw->ip, dw->cfa, c->sigcontext_format, c->sigcontext_addr,
+ (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME
+ ? c->frame_info.cfa_reg_offset : 0));
+}
+
+int
+unw_is_signal_frame (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ return c->sigcontext_format != X86_64_SCF_NONE;
+}
+
+HIDDEN int
+x86_64_handle_signal_frame (unw_cursor_t *cursor)
+{
+#if UNW_DEBUG /* To silence compiler warnings */
+ /* Should not get here because we now use kernel-provided dwarf
+ information for the signal trampoline and dwarf_step() works.
+ Hence unw_step() should never call this function. Maybe
+ restore old non-dwarf signal handling here, but then the
+ gating on unw_is_signal_frame() needs to be removed. */
+ struct cursor *c = (struct cursor *) cursor;
+ Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n",
+ c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa);
+#endif
+ 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.__gregs[_REG_R8]; break;
+ case UNW_X86_64_R9: addr = &uc->uc_mcontext.__gregs[_REG_R9]; break;
+ case UNW_X86_64_R10: addr = &uc->uc_mcontext.__gregs[_REG_R10]; break;
+ case UNW_X86_64_R11: addr = &uc->uc_mcontext.__gregs[_REG_R11]; break;
+ case UNW_X86_64_R12: addr = &uc->uc_mcontext.__gregs[_REG_R12]; break;
+ case UNW_X86_64_R13: addr = &uc->uc_mcontext.__gregs[_REG_R13]; break;
+ case UNW_X86_64_R14: addr = &uc->uc_mcontext.__gregs[_REG_R14]; break;
+ case UNW_X86_64_R15: addr = &uc->uc_mcontext.__gregs[_REG_R15]; break;
+ case UNW_X86_64_RDI: addr = &uc->uc_mcontext.__gregs[_REG_RDI]; break;
+ case UNW_X86_64_RSI: addr = &uc->uc_mcontext.__gregs[_REG_RSI]; break;
+ case UNW_X86_64_RBP: addr = &uc->uc_mcontext.__gregs[_REG_RBP]; break;
+ case UNW_X86_64_RBX: addr = &uc->uc_mcontext.__gregs[_REG_RBX]; break;
+ case UNW_X86_64_RDX: addr = &uc->uc_mcontext.__gregs[_REG_RDX]; break;
+ case UNW_X86_64_RAX: addr = &uc->uc_mcontext.__gregs[_REG_RAX]; break;
+ case UNW_X86_64_RCX: addr = &uc->uc_mcontext.__gregs[_REG_RCX]; break;
+ case UNW_X86_64_RSP: addr = &uc->uc_mcontext.__gregs[_REG_RSP]; break;
+ case UNW_X86_64_RIP: addr = &uc->uc_mcontext.__gregs[_REG_RIP]; break;
+
+ default:
+ addr = NULL;
+ }
+ return addr;
+}
+
+/* sigreturn() is a no-op on x86_64 glibc. */
+HIDDEN NORETURN void
+x86_64_sigreturn (unw_cursor_t *cursor)
+{
+ struct cursor *c = (struct cursor *) cursor;
+ struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
+ mcontext_t *sc_mcontext = &((ucontext_t*)sc)->uc_mcontext;
+ /* Copy in saved uc - all preserved regs are at the start of sigcontext */
+ memcpy(sc_mcontext, &c->uc->uc_mcontext,
+ DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t));
+
+ Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
+ (unsigned long long) c->dwarf.ip, sc);
+#if 0
+ __asm__ __volatile__ ("mov %0, %%rsp;"
+ "mov %1, %%rax;"
+ "syscall"
+ :: "r"(sc), "i"(SYS_rt_sigreturn)
+ : "memory");
+#endif
+ abort();
+}
+
+#endif

View File

@ -0,0 +1,10 @@
$NetBSD$
--- src/x86_64/Los-netbsd.c.orig 2018-09-05 10:31:53.522195751 +0000
+++ src/x86_64/Los-netbsd.c
@@ -0,0 +1,5 @@
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
+#include "Gos-netbsd.c"
+#endif

View File

@ -0,0 +1,29 @@
$NetBSD$
--- src/x86_64/getcontext.S.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/x86_64/getcontext.S
@@ -2,6 +2,7 @@
Copyright (C) 2008 Google, Inc
Contributed by Paul Pluzhnikov <ppluzhnikov@google.com>
Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
+ Copyright (C) 2018 Kamil Rytarowski <n54@gmx.com>
This file is part of libunwind.
@@ -86,6 +87,8 @@ _Ux86_64_getcontext:
movw %gs, UC_MCONTEXT_GS(%rdi)
#endif
movq $UC_MCONTEXT_MC_LEN_VAL, UC_MCONTEXT_MC_LEN(%rdi)
+#elif defined __NetBSD__
+ fxsave UC_MCONTEXT_FPREGS(%rdi)
#else
#error Port me
#endif
@@ -130,5 +133,7 @@ _Ux86_64_getcontext_trace:
.cfi_endproc
.size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace
+#ifndef __NetBSD__
/* We do not need executable stack. */
.section .note.GNU-stack,"",@progbits
+#endif

View File

@ -0,0 +1,29 @@
$NetBSD$
--- src/x86_64/setcontext.S.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/x86_64/setcontext.S
@@ -2,6 +2,7 @@
Copyright (C) 2007 Google, Inc
Contributed by Arun Sharma <arun.sharma@google.com>
Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
+ Copyright (C) 2018 Kamil Rytarowski <n54@gmx.com>
This file is part of libunwind.
@@ -50,6 +51,8 @@ _Ux86_64_setcontext:
jne 1f
fxrstor UC_MCONTEXT_FPSTATE(%rdi)
1:
+#elif defined __NetBSD__
+ fxrstor UC_MCONTEXT_FPREGS(%rdi)
#else
#error Port me
#endif
@@ -79,5 +82,7 @@ _Ux86_64_setcontext:
.size _Ux86_64_setcontext, . - _Ux86_64_setcontext
+#ifndef __NetBSD__
/* We do not need executable stack. */
.section .note.GNU-stack,"",@progbits
+#endif

View File

@ -0,0 +1,52 @@
$NetBSD$
--- src/x86_64/ucontext_i.h.orig 2018-09-04 09:38:02.000000000 +0000
+++ src/x86_64/ucontext_i.h
@@ -1,5 +1,6 @@
/* Copyright (C) 2004 Hewlett-Packard Co.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+ Copyright (C) 2018 Kamil Rytarowski <n54@gmx.com>
This file is part of libunwind.
@@ -78,5 +79,40 @@ WITH THE SOFTWARE OR THE USE OR OTHER DE
#define UC_MCONTEXT_FPOWNED_FPU 0x20001
#define UC_MCONTEXT_FPFMT_XMM 0x10002
#define UC_MCONTEXT_MC_LEN_VAL 0x320
+#elif defined __NetBSD__
+#define UC_SIGMASK 0x10
+#define UC_MCONTEXT_GREGS_RDI 0x38
+#define UC_MCONTEXT_GREGS_RSI 0x40
+#define UC_MCONTEXT_GREGS_RDX 0x48
+#define UC_MCONTEXT_GREGS_R10 0x68
+#define UC_MCONTEXT_GREGS_R8 0x58
+#define UC_MCONTEXT_GREGS_R9 0x60
+#define UC_MCONTEXT_GREGS_RCX 0x50
+#define UC_MCONTEXT_GREGS_R11 0x70
+#define UC_MCONTEXT_GREGS_R12 0x78
+#define UC_MCONTEXT_GREGS_R13 0x80
+#define UC_MCONTEXT_GREGS_R14 0x88
+#define UC_MCONTEXT_GREGS_R15 0x90
+#define UC_MCONTEXT_GREGS_RBP 0x98
+#define UC_MCONTEXT_GREGS_RBX 0xa0
+#define UC_MCONTEXT_GREGS_RAX 0xa8
+#define UC_MCONTEXT_GREGS_GS 0xb0 /* zeroed */
+#define UC_MCONTEXT_GREGS_FS 0xb8 /* zeroed */
+#define UC_MCONTEXT_GREGS_ES 0xc0
+#define UC_MCONTEXT_GREGS_DS 0xc8
+#define UC_MCONTEXT_GREGS_TRAPNO 0xd0 /* not used */
+#define UC_MCONTEXT_GREGS_ERR 0xd8 /* not used */
+#define UC_MCONTEXT_GREGS_RIP 0xe0
+#define UC_MCONTEXT_GREGS_CS 0xe8
+#define UC_MCONTEXT_GREGS_RFLAGS 0xf0
+#define UC_MCONTEXT_GREGS_RSP 0xf8
+#define UC_MCONTEXT_GREGS_SS 0x100
+#define UC_MCONTEXT_FPREGS 0x110 /* FXSAVE layout */
+#define UC_MCONTEXT_MC_TLSBASE 0x108
+#define UC_FLAGS_SIGMASK 0x1
+#define UC_FLAGS_STACK 0x2
+#define UC_FLAGS_CPU 0x4
+#define UC_FLAGS_FPU 0x8
+#define UC_FLAGS_TLSBASE 0x80000
#endif

View File

@ -0,0 +1,117 @@
$NetBSD$
--- src/x86/getcontext-netbsd.S.orig 2018-09-05 10:31:53.543786767 +0000
+++ src/x86/getcontext-netbsd.S
@@ -0,0 +1,112 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2010 Kamil Rytarowski <n54@gmx.com>
+
+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 "offsets.h"
+
+ .global _Ux86_getcontext
+ .type _Ux86_getcontext, @function
+_Ux86_getcontext:
+ .cfi_startproc
+ pushl %eax
+ .cfi_adjust_cfa_offset 4
+ mov 8(%esp),%eax /* ucontext_t* */
+ popl FREEBSD_UC_MCONTEXT_EAX_OFF(%eax)
+ .cfi_adjust_cfa_offset 4
+ movl %ebx, FREEBSD_UC_MCONTEXT_EBX_OFF(%eax)
+ movl %ecx, FREEBSD_UC_MCONTEXT_ECX_OFF(%eax)
+ movl %edx, FREEBSD_UC_MCONTEXT_EDX_OFF(%eax)
+ movl %edi, FREEBSD_UC_MCONTEXT_EDI_OFF(%eax)
+ movl %esi, FREEBSD_UC_MCONTEXT_ESI_OFF(%eax)
+ movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax)
+
+ movl (%esp), %ecx
+ movl %ecx, FREEBSD_UC_MCONTEXT_EIP_OFF(%eax)
+
+ leal 4(%esp), %ecx /* Exclude the return address. */
+ movl %ecx, FREEBSD_UC_MCONTEXT_ESP_OFF(%eax)
+
+ xorl %ecx, %ecx
+ movw %fs, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_FS_OFF(%eax)
+ movw %gs, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_GS_OFF(%eax)
+ movw %ds, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_DS_OFF(%eax)
+ movw %es, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_ES_OFF(%eax)
+ movw %ss, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_SS_OFF(%eax)
+ movw %cs, %cx
+ movl %ecx, FREEBSD_UC_MCONTEXT_CS_OFF(%eax)
+
+ pushfl
+ .cfi_adjust_cfa_offset 4
+ popl FREEBSD_UC_MCONTEXT_EFLAGS_OFF(%eax)
+ .cfi_adjust_cfa_offset -4
+
+ movl $0, FREEBSD_UC_MCONTEXT_TRAPNO_OFF(%eax)
+
+ movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,\
+ FREEBSD_UC_MCONTEXT_OWNEDFP_OFF(%eax)
+ movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,\
+ FREEBSD_UC_MCONTEXT_FPFORMAT_OFF(%eax)
+
+ /*
+ * Require CPU with fxsave implemented, and enabled by OS.
+ *
+ * If passed ucontext is not aligned to 16-byte boundary,
+ * save fpu context into temporary aligned location on stack
+ * and then copy.
+ */
+ leal FREEBSD_UC_MCONTEXT_FPSTATE_OFF(%eax), %edx
+ testl $0xf, %edx
+ jne 2f
+ fxsave (%edx) /* fast path, passed ucontext save area was aligned */
+1: movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL,\
+ FREEBSD_UC_MCONTEXT_MC_LEN_OFF(%eax)
+
+ xorl %eax, %eax
+ ret
+
+2: movl %edx, %edi /* not aligned, do the dance */
+ subl $512 + 16, %esp /* save area and 16 bytes for alignment */
+ .cfi_adjust_cfa_offset 512 + 16
+ movl %esp, %edx
+ orl $0xf, %edx /* align *%edx to 16-byte up */
+ incl %edx
+ fxsave (%edx)
+ movl %edx, %esi /* copy to the final destination */
+ movl $512/4,%ecx
+ rep; movsl
+ addl $512 + 16, %esp /* restore the stack */
+ .cfi_adjust_cfa_offset -512 - 16
+ movl FREEBSD_UC_MCONTEXT_ESI_OFF(%eax), %esi
+ movl FREEBSD_UC_MCONTEXT_EDI_OFF(%eax), %edi
+ jmp 1b
+
+ .cfi_endproc
+ .size _Ux86_getcontext, . - _Ux86_getcontext
+
+ /* We do not need executable stack. */
+ .section .note.GNU-stack,"",@progbits