summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am9
-rw-r--r--src/dwarf/Gfind_proc_info-lsb.c48
-rw-r--r--src/elfxx.c1
-rw-r--r--src/os-solaris.c73
-rw-r--r--src/setjmp/siglongjmp.c10
-rw-r--r--src/x86_64/Gos-solaris.c16
-rw-r--r--src/x86_64/getcontext.S2
-rw-r--r--src/x86_64/setcontext.S17
-rw-r--r--src/x86_64/ucontext_i.h4
9 files changed, 102 insertions, 78 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8d72ef0b..bc37b123 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -154,6 +154,8 @@ libunwind_la_SOURCES_os_freebsd = os-freebsd.c
libunwind_la_SOURCES_os_qnx = os-qnx.c
+libunwind_la_SOURCES_os_solaris = os-solaris.c
+
libunwind_dwarf_common_la_SOURCES = dwarf/global.c
libunwind_dwarf_local_la_SOURCES = \
@@ -538,6 +540,12 @@ if OS_FREEBSD
libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c
endif
+if OS_SOLARIS
+ libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_solaris)
+ libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c
+ libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.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)
@@ -741,6 +749,7 @@ EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \
$(libunwind_la_SOURCES_os_linux) \
$(libunwind_la_SOURCES_os_hpux) \
$(libunwind_la_SOURCES_os_qnx) \
+ $(libunwind_la_SOURCES_os_solaris) \
$(libunwind_la_SOURCES_common) \
$(libunwind_la_SOURCES_local) \
$(libunwind_la_SOURCES_generic) \
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index 4edea668..7d0c70f2 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -480,8 +480,6 @@ struct dwarf_callback_data
unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
};
-#ifdef HAVE_DL_ITERATE_PHDR
-
/* ptr is a pointer to a dwarf_callback_data structure and, on entry,
member ip contains the instruction-pointer we're looking
for. */
@@ -698,52 +696,6 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
return found;
}
-#else // HAVE_DL_ITERATE_PHDR
-
-static int
-find_proc_fde(unw_word_t ip, unw_word_t *fde_addr,
- unw_word_t *gp, unw_word_t *fde_base,
- unw_word_t *ip_offset, void *arg) {
- Dl_amd64_unwindinfo dlef;
- void* data;
- void* data_end;
- int fp_enc, fc_enc, ft_enc;
- unsigned char *pi, *pj;
- ptrdiff_t reloc;
- uintptr_t base;
- int ret;
-
- dlef.dlui_version = 1;
-
- /* Locate the appropiate exception_range_entry table first */
- if (0 == dlamd64getunwind((void*)ip, &dlef)) {
- return -UNW_ENOINFO;
- }
-
- /*
- * you now know size and position of block of data needed for
- * binary search ??REMOTE??
- */
- data = dlef.dlui_unwindstart;
- if (0 == data)
- return -UNW_ENOINFO;
-
- base = (uintptr_t)data;
- data_end = dlef.dlui_unwindend;
- reloc = 0;
- /* ??REMOTE?? */
-
- *gp = 0;
- *fde_base = 0;
- *ip_offset = 0;
-
- return search_fde_in_eh_frame(ip, (unw_word_t)data, 0,
- (unw_word_t)data_end, fde_addr, arg, 0,
- dlef.dlui_objname);
-}
-
-#endif // HAVE_DL_ITERATE_PHDR
-
HIDDEN int
dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
unw_proc_info_t *pi, int need_unwind_info, void *arg)
diff --git a/src/elfxx.c b/src/elfxx.c
index b03dfcb7..2589a3d4 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -28,6 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <stdio.h>
#include <sys/param.h>
+#include <limits.h>
#ifdef HAVE_LZMA
#include <lzma.h>
diff --git a/src/os-solaris.c b/src/os-solaris.c
new file mode 100644
index 00000000..3c140ef2
--- /dev/null
+++ b/src/os-solaris.c
@@ -0,0 +1,73 @@
+/* libunwind - a platform-independent unwind library
+ Copyright (C) 2003-2005 Hewlett-Packard Co
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 <limits.h>
+#include <stdio.h>
+
+#include "libunwind_i.h"
+#include "os-linux.h" // using linux header for map_iterator implementation
+
+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)
+{
+ struct map_iterator mi;
+ int found = 0, rc;
+ unsigned long hi;
+
+ if (maps_init (&mi, pid) < 0)
+ return -1;
+
+ while (maps_next (&mi, segbase, &hi, mapoff))
+ if (ip >= *segbase && ip < hi)
+ {
+ found = 1;
+ break;
+ }
+
+ if (!found)
+ {
+ maps_close (&mi);
+ return -1;
+ }
+ if (path)
+ {
+ strncpy(path, mi.path, pathlen);
+ }
+ rc = elf_map_image (ei, mi.path);
+ maps_close (&mi);
+ return rc;
+}
+
+#ifndef UNW_REMOTE_ONLY
+
+void
+tdep_get_exe_image_path (char *path)
+{
+ strcpy(path, getexecname());
+}
+
+#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/setjmp/siglongjmp.c b/src/setjmp/siglongjmp.c
index 0e286f6f..dd330ce9 100644
--- a/src/setjmp/siglongjmp.c
+++ b/src/setjmp/siglongjmp.c
@@ -31,8 +31,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "jmpbuf.h"
#include "setjmp_i.h"
-#if !defined(_NSIG) && defined(_SIG_MAXSIG)
-# define _NSIG (_SIG_MAXSIG - 1)
+#if !defined(_NSIG)
+# if defined(_SIG_MAXSIG)
+# define _NSIG (_SIG_MAXSIG - 1)
+# elif defined(NSIG)
+# define _NSIG NSIG
+# endif
#endif
#if defined(__GLIBC__)
@@ -92,7 +96,7 @@ siglongjmp (sigjmp_buf env, int val)
if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED])
{
/* sigmask was saved */
-#if defined(__linux__)
+#if defined(__linux__) || defined(__sun)
if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t))
/* signal mask doesn't fit into EH arguments and we can't
put it on the stack without overwriting something
diff --git a/src/x86_64/Gos-solaris.c b/src/x86_64/Gos-solaris.c
index 6e764463..10e15230 100644
--- a/src/x86_64/Gos-solaris.c
+++ b/src/x86_64/Gos-solaris.c
@@ -47,21 +47,21 @@ tdep_fetch_frame (struct dwarf_cursor *dw, unw_word_t ip, int need_unwind_info)
dw->ip, dw->cfa, c->sigcontext_format);
}
-HIDDEN void
-tdep_cache_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs)
+HIDDEN int
+tdep_cache_frame (struct dwarf_cursor *dw)
{
struct cursor *c = (struct cursor *) dw;
- rs->signal_frame = c->sigcontext_format;
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, struct dwarf_reg_state *rs)
+tdep_reuse_frame (struct dwarf_cursor *dw, int frame)
{
struct cursor *c = (struct cursor *) dw;
- c->sigcontext_format = rs->signal_frame;
+ c->sigcontext_format = frame;
if (c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME)
{
c->frame_info.frame_type = UNW_X86_64_FRAME_SIGRETURN;
@@ -78,15 +78,15 @@ tdep_reuse_frame (struct dwarf_cursor *dw, struct dwarf_reg_state *rs)
? c->frame_info.cfa_reg_offset : 0));
}
-PROTECTED int
+int
unw_is_signal_frame (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
return c->sigcontext_format != X86_64_SCF_NONE;
}
-PROTECTED int
-unw_handle_signal_frame (unw_cursor_t *cursor)
+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
diff --git a/src/x86_64/getcontext.S b/src/x86_64/getcontext.S
index 6f5d0a14..e1450719 100644
--- a/src/x86_64/getcontext.S
+++ b/src/x86_64/getcontext.S
@@ -57,7 +57,7 @@ _Ux86_64_getcontext:
movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi)
movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi)
-#if defined(__linux__) || defined(__sun__)
+#if defined __linux__ || defined __sun
/* Save fp state (not needed, except for setcontext not
restoring garbage). */
leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8
diff --git a/src/x86_64/setcontext.S b/src/x86_64/setcontext.S
index 4cbefe08..17e5ae12 100644
--- a/src/x86_64/setcontext.S
+++ b/src/x86_64/setcontext.S
@@ -37,22 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
_Ux86_64_setcontext:
-#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
- mov $SIGSET_BYTE_SIZE, %r10
- syscall
- pop %rdi
-
+#if defined __linux__ || defined __sun
/* restore fp state */
#ifdef UC_MCONTEXT_FPREGS_PTR
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h
index e41e5629..e886c948 100644
--- a/src/x86_64/ucontext_i.h
+++ b/src/x86_64/ucontext_i.h
@@ -78,7 +78,7 @@ 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)
+#elif defined __sun
#define UC_MCONTEXT_GREGS_R8 0x78
#define UC_MCONTEXT_GREGS_R9 0x70
#define UC_MCONTEXT_GREGS_R10 0x68
@@ -98,5 +98,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define UC_MCONTEXT_GREGS_RIP 0xc8
#define UC_MCONTEXT_FPREGS_MEM 0x120
#define FPREGS_OFFSET_MXCSR 0x18
-#define UC_SIGMASK 0x128
+
#endif