diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/dwarf/Gfind_proc_info-lsb.c | 48 | ||||
-rw-r--r-- | src/elfxx.c | 1 | ||||
-rw-r--r-- | src/os-solaris.c | 73 | ||||
-rw-r--r-- | src/setjmp/siglongjmp.c | 10 | ||||
-rw-r--r-- | src/x86_64/Gos-solaris.c | 16 | ||||
-rw-r--r-- | src/x86_64/getcontext.S | 2 | ||||
-rw-r--r-- | src/x86_64/setcontext.S | 17 | ||||
-rw-r--r-- | src/x86_64/ucontext_i.h | 4 |
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 |