|
diff --git a/configure.ac b/configure.ac |
|
index 85d78f8..e93be1c 100644 |
|
--- a/configure.ac |
|
+++ b/configure.ac |
|
@@ -35,7 +35,7 @@ CHECK_ATOMIC_OPS |
|
|
|
dnl Checks for header files. |
|
AC_HEADER_STDC |
|
-AC_CHECK_HEADERS(asm/ptrace_offsets.h endian.h sys/endian.h execinfo.h \ |
|
+AC_CHECK_HEADERS(asm/ptrace_offsets.h endian.h sys/endian.h execinfo.h sys/isa_defs.h \ |
|
ia64intrin.h sys/uc_access.h unistd.h signal.h sys/types.h \ |
|
sys/procfs.h sys/ptrace.h byteswap.h elf.h sys/elf.h link.h sys/link.h) |
|
|
|
diff --git a/include/libunwind_i.h b/include/libunwind_i.h |
|
index ee2ea2f..5bb19d7 100644 |
|
--- a/include/libunwind_i.h |
|
+++ b/include/libunwind_i.h |
|
@@ -69,6 +69,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
# include <endian.h> |
|
#elif defined(HAVE_SYS_ENDIAN_H) |
|
# include <sys/endian.h> |
|
+#elif defined(HAVE_SYS_ISA_DEFS_H) |
|
+# include <sys/isa_defs.h> |
|
+# if defined(_LITTLE_ENDIAN) |
|
+# define __BYTE_ORDER __LITTLE_ENDIAN |
|
+# elif defined(_BIG_ENDIAN) |
|
+# define __BYTE_ORDER __BIG_ENDIAN |
|
+# else |
|
+# error Host has unknown byte-order. |
|
+# endif |
|
#else |
|
# define __LITTLE_ENDIAN 1234 |
|
# define __BIG_ENDIAN 4321 |
|
diff --git a/src/x86_64/Gtrace.c b/src/x86_64/Gtrace.c |
|
index 833d7a7..eb1a585 100644 |
|
--- a/src/x86_64/Gtrace.c |
|
+++ b/src/x86_64/Gtrace.c |
|
@@ -35,6 +35,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
/* Initial hash table size. Table expands by 2 bits (times four). */ |
|
#define HASH_MIN_BITS 14 |
|
|
|
+#ifndef PTHREAD_DESTRUCTOR_ITERATIONS |
|
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4 |
|
+#endif |
|
+ |
|
typedef struct |
|
{ |
|
unw_tdep_frame_t *frames; |
|
@@ -68,7 +72,7 @@ trace_cache_free (void *arg) |
|
} |
|
tls_cache_destroyed = 1; |
|
tls_cache = NULL; |
|
- munmap (cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); |
|
+ munmap ((caddr_t)cache->frames, (1u << cache->log_size) * sizeof(unw_tdep_frame_t)); |
|
mempool_free (&trace_cache_pool, cache); |
|
Debug(5, "freed cache %p\n", cache); |
|
} |
|
@@ -150,7 +154,7 @@ trace_cache_expand (unw_trace_cache_t *cache) |
|
} |
|
|
|
Debug(5, "expanded cache from 2^%lu to 2^%lu buckets\n", cache->log_size, new_log_size); |
|
- munmap(cache->frames, old_size * sizeof(unw_tdep_frame_t)); |
|
+ munmap((caddr_t)cache->frames, old_size * sizeof(unw_tdep_frame_t)); |
|
cache->frames = new_frames; |
|
cache->log_size = new_log_size; |
|
cache->used = 0; |
|
diff --git a/src/x86_64/getcontext.S b/src/x86_64/getcontext.S |
|
index 7a8b566..5e5314f 100644 |
|
--- a/src/x86_64/getcontext.S |
|
+++ b/src/x86_64/getcontext.S |
|
@@ -57,11 +57,13 @@ _Ux86_64_getcontext: |
|
movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) |
|
movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) |
|
|
|
-#if defined __linux__ |
|
+#if defined(__linux__) || defined(__sun__) |
|
/* Save fp state (not needed, except for setcontext not |
|
restoring garbage). */ |
|
leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 |
|
+#ifdef UC_MCONTEXT_FPREGS_PTR |
|
movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) |
|
+#endif |
|
fnstenv (%r8) |
|
stmxcsr FPREGS_OFFSET_MXCSR(%r8) |
|
#elif defined __FreeBSD__ |
|
diff --git a/src/x86_64/setcontext.S b/src/x86_64/setcontext.S |
|
index 1af8b67..4eb2532 100644 |
|
--- a/src/x86_64/setcontext.S |
|
+++ b/src/x86_64/setcontext.S |
|
@@ -29,6 +29,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
#include <asm/unistd.h> |
|
#define SIG_SETMASK 2 |
|
#define SIGSET_BYTE_SIZE (64/8) |
|
+#elif defined __sun__ |
|
+#define SYS_sigprocmask 95 |
|
+#define SIG_SETMASK 3 |
|
+#define SIGSET_BYTE_SIZE (8) |
|
#elif defined __FreeBSD__ |
|
#include <sys/syscall.h> |
|
#endif |
|
@@ -44,11 +48,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
|
|
_Ux86_64_setcontext: |
|
|
|
-#if defined __linux__ |
|
+#if defined(__linux__) || defined(__sun__) |
|
/* restore signal mask |
|
sigprocmask(SIG_SETMASK, ucp->uc_sigmask, NULL, sizeof(sigset_t)) */ |
|
push %rdi |
|
+#if defined(__sun__) |
|
+ mov $SYS_sigprocmask, %rax |
|
+#else |
|
mov $__NR_rt_sigprocmask, %rax |
|
+#endif |
|
lea UC_SIGMASK(%rdi), %rsi |
|
mov $SIG_SETMASK, %rdi |
|
xor %rdx, %rdx |
|
@@ -57,8 +65,11 @@ _Ux86_64_setcontext: |
|
pop %rdi |
|
|
|
/* restore fp state */ |
|
+#ifdef UC_MCONTEXT_FPREGS_PTR |
|
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 |
|
+#else |
|
fldenv (%r8) |
|
+#endif |
|
ldmxcsr FPREGS_OFFSET_MXCSR(%r8) |
|
#elif defined __FreeBSD__ |
|
/* restore signal mask */ |
|
diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h |
|
index aded941..574c276 100644 |
|
--- a/src/x86_64/ucontext_i.h |
|
+++ b/src/x86_64/ucontext_i.h |
|
@@ -78,5 +78,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
#define UC_MCONTEXT_FPOWNED_FPU 0x20001 |
|
#define UC_MCONTEXT_FPFMT_XMM 0x10002 |
|
#define UC_MCONTEXT_MC_LEN_VAL 0x320 |
|
+#elif defined(__sun__) |
|
+#define UC_MCONTEXT_GREGS_R8 0x78 |
|
+#define UC_MCONTEXT_GREGS_R9 0x70 |
|
+#define UC_MCONTEXT_GREGS_R10 0x68 |
|
+#define UC_MCONTEXT_GREGS_R11 0x60 |
|
+#define UC_MCONTEXT_GREGS_R12 0x58 |
|
+#define UC_MCONTEXT_GREGS_R13 0x50 |
|
+#define UC_MCONTEXT_GREGS_R14 0x48 |
|
+#define UC_MCONTEXT_GREGS_R15 0x40 |
|
+#define UC_MCONTEXT_GREGS_RDI 0x80 |
|
+#define UC_MCONTEXT_GREGS_RSI 0x88 |
|
+#define UC_MCONTEXT_GREGS_RBP 0x90 |
|
+#define UC_MCONTEXT_GREGS_RBX 0x98 |
|
+#define UC_MCONTEXT_GREGS_RDX 0xa0 |
|
+#define UC_MCONTEXT_GREGS_RAX 0xb0 |
|
+#define UC_MCONTEXT_GREGS_RCX 0xa8 |
|
+#define UC_MCONTEXT_GREGS_RSP 0xe0 |
|
+#define UC_MCONTEXT_GREGS_RIP 0xc8 |
|
+#define UC_MCONTEXT_FPREGS_MEM 0x120 |
|
+#define FPREGS_OFFSET_MXCSR 0x18 |
|
+#define UC_SIGMASK 0x128 |
|
|
|
#endif |
|
|