diff --git a/contrib/libunwind/CMakeLists.txt b/contrib/libunwind/CMakeLists.txt index 1a1b1e79bc3..47032be92bb 100644 --- a/contrib/libunwind/CMakeLists.txt +++ b/contrib/libunwind/CMakeLists.txt @@ -45,7 +45,6 @@ src/dwarf/Lfde.c src/dwarf/Lfind_proc_info-lsb.c src/dwarf/Lparser.c src/dwarf/Lpe.c -src/dwarf/Lstep.c src/dwarf/global.c src/elf64.c @@ -53,9 +52,17 @@ src/os-linux.c src/x86_64/Los-linux.c ) +find_file (HAVE_ATOMIC_OPS_H "atomic_ops.h") +configure_file (config/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/config.h) +configure_file (config/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/libunwind.h) +configure_file (config/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/libunwind-common.h) +configure_file (config/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/tdep/libunwind_i.h) + target_compile_definitions (unwind PRIVATE HAVE_CONFIG_H=1 _XOPEN_SOURCE _GNU_SOURCE) target_compile_options (unwind PRIVATE -Wno-visibility -Wno-header-guard) target_include_directories (unwind PUBLIC include) target_include_directories (unwind PRIVATE include/tdep) +target_include_directories (unwind PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/config) +target_include_directories (unwind PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config/tdep) target_include_directories (unwind PRIVATE src) diff --git a/contrib/libunwind/README b/contrib/libunwind/README index 08df15b5621..9687c3c0338 100644 --- a/contrib/libunwind/README +++ b/contrib/libunwind/README @@ -1,2 +1,2 @@ Source: https://github.com/libunwind/libunwind -Revision: 2934cf40529e0261801a4142fabae449a65effd0 +Revision: 60ddc67196eafb5cafd0d89e461c9d700a697d6d diff --git a/contrib/libunwind/include/config.h b/contrib/libunwind/config/config.h.in similarity index 96% rename from contrib/libunwind/include/config.h rename to contrib/libunwind/config/config.h.in index 672aa4ada7f..7dcf38ed012 100644 --- a/contrib/libunwind/include/config.h +++ b/contrib/libunwind/config/config.h.in @@ -17,7 +17,7 @@ /* #undef HAVE_ASM_PTRACE_OFFSETS_H */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_ATOMIC_OPS_H */ +#cmakedefine HAVE_ATOMIC_OPS_H /* Define to 1 if you have the header file. */ #define HAVE_BYTESWAP_H 1 @@ -34,6 +34,10 @@ you don't. */ #define HAVE_DECL_PTRACE_POKEUSER 1 +/* Define to 1 if you have the declaration of `PTRACE_SETREGSET', and to 0 if + you don't. */ +#define HAVE_DECL_PTRACE_SETREGSET 1 + /* Define to 1 if you have the declaration of `PTRACE_SINGLESTEP', and to 0 if you don't. */ #define HAVE_DECL_PTRACE_SINGLESTEP 1 @@ -183,9 +187,10 @@ #define HAVE__BUILTIN___CLEAR_CACHE 1 /* Define to 1 if __thread keyword is supported by the C compiler. */ -#define HAVE___THREAD 1 +/* #undef HAVE___THREAD */ -/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ #define LT_OBJDIR ".libs/" /* Name of package */ diff --git a/contrib/libunwind/include/libunwind-common.h b/contrib/libunwind/config/libunwind-common.h.in similarity index 97% rename from contrib/libunwind/include/libunwind-common.h rename to contrib/libunwind/config/libunwind-common.h.in index d4fbf270a28..ceacdb42128 100644 --- a/contrib/libunwind/include/libunwind-common.h +++ b/contrib/libunwind/config/libunwind-common.h.in @@ -86,6 +86,12 @@ typedef enum } unw_caching_policy_t; +typedef enum + { + UNW_INIT_SIGNAL_FRAME = 1, /* We know this is a signal frame */ + } +unw_init_local2_flags_t; + typedef int unw_regnum_t; /* The unwind cursor starts at the youngest (most deeply nested) frame @@ -219,7 +225,7 @@ unw_save_loc_t; #define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) #define unw_get_accessors UNW_ARCH_OBJ(get_accessors) #define unw_init_local UNW_OBJ(init_local) -#define unw_init_local_signal UNW_OBJ(init_local_signal) +#define unw_init_local2 UNW_OBJ(init_local2) #define unw_init_remote UNW_OBJ(init_remote) #define unw_step UNW_OBJ(step) #define unw_resume UNW_OBJ(resume) @@ -250,7 +256,7 @@ extern int unw_set_cache_size (unw_addr_space_t, size_t, int); extern const char *unw_regname (unw_regnum_t); extern int unw_init_local (unw_cursor_t *, unw_context_t *); -extern int unw_init_local_signal (unw_cursor_t *, unw_context_t *); +extern int unw_init_local2 (unw_cursor_t *, unw_context_t *, int); extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); extern int unw_step (unw_cursor_t *); extern int unw_resume (unw_cursor_t *); diff --git a/contrib/libunwind/include/libunwind.h b/contrib/libunwind/config/libunwind.h.in similarity index 100% rename from contrib/libunwind/include/libunwind.h rename to contrib/libunwind/config/libunwind.h.in diff --git a/contrib/libunwind/include/tdep/libunwind_i.h b/contrib/libunwind/config/tdep/libunwind_i.h.in similarity index 100% rename from contrib/libunwind/include/tdep/libunwind_i.h rename to contrib/libunwind/config/tdep/libunwind_i.h.in diff --git a/contrib/libunwind/include/config.h.in b/contrib/libunwind/include/config.h.in deleted file mode 100644 index 5eb05c90784..00000000000 --- a/contrib/libunwind/include/config.h.in +++ /dev/null @@ -1,230 +0,0 @@ -/* include/config.h.in. Generated from configure.ac by autoheader. */ - -/* Block signals before mutex operations */ -#undef CONFIG_BLOCK_SIGNALS - -/* Enable Debug Frame */ -#undef CONFIG_DEBUG_FRAME - -/* Support for Microsoft ABI extensions */ -#undef CONFIG_MSABI_SUPPORT - -/* Define to 1 if you want every memory access validated */ -#undef CONSERVATIVE_CHECKS - -/* Define to 1 if you have the header file. */ -#undef HAVE_ASM_PTRACE_OFFSETS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ATOMIC_OPS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_BYTESWAP_H - -/* Define to 1 if you have the declaration of `PTRACE_CONT', and to 0 if you - don't. */ -#undef HAVE_DECL_PTRACE_CONT - -/* Define to 1 if you have the declaration of `PTRACE_POKEDATA', and to 0 if - you don't. */ -#undef HAVE_DECL_PTRACE_POKEDATA - -/* Define to 1 if you have the declaration of `PTRACE_POKEUSER', and to 0 if - you don't. */ -#undef HAVE_DECL_PTRACE_POKEUSER - -/* Define to 1 if you have the declaration of `PTRACE_SINGLESTEP', and to 0 if - you don't. */ -#undef HAVE_DECL_PTRACE_SINGLESTEP - -/* Define to 1 if you have the declaration of `PTRACE_SYSCALL', and to 0 if - you don't. */ -#undef HAVE_DECL_PTRACE_SYSCALL - -/* Define to 1 if you have the declaration of `PTRACE_TRACEME', and to 0 if - you don't. */ -#undef HAVE_DECL_PTRACE_TRACEME - -/* Define to 1 if you have the declaration of `PT_CONTINUE', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_CONTINUE - -/* Define to 1 if you have the declaration of `PT_GETFPREGS', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_GETFPREGS - -/* Define to 1 if you have the declaration of `PT_GETREGS', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_GETREGS - -/* Define to 1 if you have the declaration of `PT_IO', and to 0 if you don't. - */ -#undef HAVE_DECL_PT_IO - -/* Define to 1 if you have the declaration of `PT_STEP', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_STEP - -/* Define to 1 if you have the declaration of `PT_SYSCALL', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_SYSCALL - -/* Define to 1 if you have the declaration of `PT_TRACE_ME', and to 0 if you - don't. */ -#undef HAVE_DECL_PT_TRACE_ME - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `dlmodinfo' function. */ -#undef HAVE_DLMODINFO - -/* Define to 1 if you have the `dl_iterate_phdr' function. */ -#undef HAVE_DL_ITERATE_PHDR - -/* Define to 1 if you have the `dl_phdr_removals_counter' function. */ -#undef HAVE_DL_PHDR_REMOVALS_COUNTER - -/* Define to 1 if you have the header file. */ -#undef HAVE_ELF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ENDIAN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have the `getunwind' function. */ -#undef HAVE_GETUNWIND - -/* Define to 1 if you have the header file. */ -#undef HAVE_IA64INTRIN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `uca' library (-luca). */ -#undef HAVE_LIBUCA - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINK_H - -/* Define if you have liblzma */ -#undef HAVE_LZMA - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mincore' function. */ -#undef HAVE_MINCORE - -/* Define to 1 if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if `dlpi_subs' is a member of `struct dl_phdr_info'. */ -#undef HAVE_STRUCT_DL_PHDR_INFO_DLPI_SUBS - -/* Define to 1 if the system has the type `struct elf_prstatus'. */ -#undef HAVE_STRUCT_ELF_PRSTATUS - -/* Define to 1 if the system has the type `struct prstatus'. */ -#undef HAVE_STRUCT_PRSTATUS - -/* Defined if __sync atomics are available */ -#undef HAVE_SYNC_ATOMICS - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_ELF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_ENDIAN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_LINK_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PROCFS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PTRACE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UC_ACCESS_H - -/* Define to 1 if you have the `ttrace' function. */ -#undef HAVE_TTRACE - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Defined if __builtin_unreachable() is available */ -#undef HAVE__BUILTIN_UNREACHABLE - -/* Defined if __builtin___clear_cache() is available */ -#undef HAVE__BUILTIN___CLEAR_CACHE - -/* Define to 1 if __thread keyword is supported by the C compiler. */ -#undef HAVE___THREAD - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* The size of `off_t', as computed by sizeof. */ -#undef SIZEOF_OFF_T - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `unsigned int' if does not define. */ -#undef size_t diff --git a/contrib/libunwind/include/dwarf-eh.h b/contrib/libunwind/include/dwarf-eh.h index e81aaef88ad..e03750760c5 100644 --- a/contrib/libunwind/include/dwarf-eh.h +++ b/contrib/libunwind/include/dwarf-eh.h @@ -106,16 +106,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define DW_EH_VERSION 1 /* The version we're implementing */ -struct dwarf_eh_frame_hdr +struct __attribute__((packed)) dwarf_eh_frame_hdr { unsigned char version; unsigned char eh_frame_ptr_enc; unsigned char fde_count_enc; unsigned char table_enc; + Elf_W (Addr) eh_frame; /* The rest of the header is variable-length and consists of the following members: - encoded_t eh_frame_ptr; encoded_t fde_count; struct { diff --git a/contrib/libunwind/include/dwarf.h b/contrib/libunwind/include/dwarf.h index e8ffa66cb48..db2a76972d1 100644 --- a/contrib/libunwind/include/dwarf.h +++ b/contrib/libunwind/include/dwarf.h @@ -37,13 +37,6 @@ struct elf_dyn_info; # include "config.h" #endif -#ifdef HAVE___THREAD - /* For now, turn off per-thread caching. It uses up too much TLS - memory per thread even when the thread never uses libunwind at - all. */ -# undef HAVE___THREAD -#endif - #ifndef UNW_REMOTE_ONLY #if defined(HAVE_LINK_H) #include diff --git a/contrib/libunwind/include/libunwind-arm.h b/contrib/libunwind/include/libunwind-arm.h index f208487a999..6709b7abaee 100644 --- a/contrib/libunwind/include/libunwind-arm.h +++ b/contrib/libunwind/include/libunwind-arm.h @@ -265,7 +265,7 @@ unw_tdep_context_t; #ifndef __thumb__ #define unw_tdep_getcontext(uc) (({ \ unw_tdep_context_t *unw_ctx = (uc); \ - register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ + register unsigned long *unw_base __asm__ ("r0") = unw_ctx->regs; \ __asm__ __volatile__ ( \ "stmia %[base], {r0-r15}" \ : : [base] "r" (unw_base) : "memory"); \ @@ -273,11 +273,12 @@ unw_tdep_context_t; #else /* __thumb__ */ #define unw_tdep_getcontext(uc) (({ \ unw_tdep_context_t *unw_ctx = (uc); \ - register unsigned long *unw_base asm ("r0") = unw_ctx->regs; \ + register unsigned long *unw_base __asm__ ("r0") = unw_ctx->regs; \ __asm__ __volatile__ ( \ ".align 2\nbx pc\nnop\n.code 32\n" \ "stmia %[base], {r0-r15}\n" \ - "orr %[base], pc, #1\nbx %[base]" \ + "orr %[base], pc, #1\nbx %[base]\n" \ + ".code 16\n" \ : [base] "+r" (unw_base) : : "memory", "cc"); \ }), 0) #endif diff --git a/contrib/libunwind/include/libunwind-common.h.in b/contrib/libunwind/include/libunwind-common.h.in index 0a9537ebf1d..9811f4915e6 100644 --- a/contrib/libunwind/include/libunwind-common.h.in +++ b/contrib/libunwind/include/libunwind-common.h.in @@ -86,6 +86,12 @@ typedef enum } unw_caching_policy_t; +typedef enum + { + UNW_INIT_SIGNAL_FRAME = 1, /* We know this is a signal frame */ + } +unw_init_local2_flags_t; + typedef int unw_regnum_t; /* The unwind cursor starts at the youngest (most deeply nested) frame @@ -219,7 +225,7 @@ unw_save_loc_t; #define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) #define unw_get_accessors UNW_ARCH_OBJ(get_accessors) #define unw_init_local UNW_OBJ(init_local) -#define unw_init_local_signal UNW_OBJ(init_local_signal) +#define unw_init_local2 UNW_OBJ(init_local2) #define unw_init_remote UNW_OBJ(init_remote) #define unw_step UNW_OBJ(step) #define unw_resume UNW_OBJ(resume) @@ -250,7 +256,7 @@ extern int unw_set_cache_size (unw_addr_space_t, size_t, int); extern const char *unw_regname (unw_regnum_t); extern int unw_init_local (unw_cursor_t *, unw_context_t *); -extern int unw_init_local_signal (unw_cursor_t *, unw_context_t *); +extern int unw_init_local2 (unw_cursor_t *, unw_context_t *, int); extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); extern int unw_step (unw_cursor_t *); extern int unw_resume (unw_cursor_t *); diff --git a/contrib/libunwind/include/libunwind_i.h b/contrib/libunwind/include/libunwind_i.h index ee2ea2fbec3..36cf7a14de7 100644 --- a/contrib/libunwind/include/libunwind_i.h +++ b/contrib/libunwind/include/libunwind_i.h @@ -37,11 +37,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "compiler.h" -#ifdef HAVE___THREAD - /* For now, turn off per-thread caching. It uses up too much TLS - memory per thread even when the thread never uses libunwind at - all. */ -# undef HAVE___THREAD +#if defined(HAVE___THREAD) && HAVE___THREAD +#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_PER_THREAD +#else +#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_GLOBAL #endif /* Platform-independent libunwind-internal declarations. */ @@ -69,6 +68,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include #elif defined(HAVE_SYS_ENDIAN_H) # include +# if defined(_LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN) +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# endif +# if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) +# define __BIG_ENDIAN _BIG_ENDIAN +# endif +# if defined(_BYTE_ORDER) && !defined(__BYTE_ORDER) +# define __BYTE_ORDER _BYTE_ORDER +# endif #else # define __LITTLE_ENDIAN 1234 # define __BIG_ENDIAN 4321 diff --git a/contrib/libunwind/include/stamp-h1 b/contrib/libunwind/include/stamp-h1 deleted file mode 100644 index b330768e9bf..00000000000 --- a/contrib/libunwind/include/stamp-h1 +++ /dev/null @@ -1 +0,0 @@ -timestamp for include/config.h diff --git a/contrib/libunwind/include/tdep-arm/libunwind_i.h b/contrib/libunwind/include/tdep-arm/libunwind_i.h index 9996b2f2cf2..2602f41c4f7 100644 --- a/contrib/libunwind/include/tdep-arm/libunwind_i.h +++ b/contrib/libunwind/include/tdep-arm/libunwind_i.h @@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ typedef enum { + UNW_ARM_FRAME_SYSCALL = -3, /* r7 saved in r12, sp offset zero */ UNW_ARM_FRAME_STANDARD = -2, /* regular r7, sp +/- offset */ UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */ UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */ @@ -48,7 +49,7 @@ unw_tdep_frame_type_t; typedef struct { uint32_t virtual_address; - int32_t frame_type : 2; /* unw_tdep_frame_type_t classification */ + int32_t frame_type : 3; /* unw_tdep_frame_type_t classification */ int32_t last_frame : 1; /* non-zero if last frame in chain */ int32_t cfa_reg_sp : 1; /* cfa dwarf base register is sp vs. r7 */ int32_t cfa_reg_offset : 30; /* cfa is at this offset from base register value */ @@ -86,7 +87,9 @@ struct cursor ARM_SCF_LINUX_SIGFRAME, /* non-RT signal frame, kernel >=2.6.18 */ ARM_SCF_LINUX_RT_SIGFRAME, /* RT signal frame, kernel >=2.6.18 */ ARM_SCF_LINUX_OLD_SIGFRAME, /* non-RT signal frame, kernel < 2.6.18 */ - ARM_SCF_LINUX_OLD_RT_SIGFRAME /* RT signal frame, kernel < 2.6.18 */ + ARM_SCF_LINUX_OLD_RT_SIGFRAME, /* RT signal frame, kernel < 2.6.18 */ + ARM_SCF_FREEBSD_SIGFRAME, /* FreeBSD sigframe */ + ARM_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall stub */ } sigcontext_format; unw_word_t sigcontext_addr; diff --git a/contrib/libunwind/include/tdep-tilegx/libunwind_i.h b/contrib/libunwind/include/tdep-tilegx/libunwind_i.h index 4a598f84700..2cfed456a70 100644 --- a/contrib/libunwind/include/tdep-tilegx/libunwind_i.h +++ b/contrib/libunwind/include/tdep-tilegx/libunwind_i.h @@ -36,10 +36,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "mempool.h" #include "dwarf.h" -#ifdef HAVE___THREAD -# undef HAVE___THREAD -#endif - typedef struct { /* no Tilegx-specific fast trace */ diff --git a/contrib/libunwind/include/tdep/jmpbuf.h b/contrib/libunwind/include/tdep/jmpbuf.h index 4eae183e5bd..13093a0cdc3 100644 --- a/contrib/libunwind/include/tdep/jmpbuf.h +++ b/contrib/libunwind/include/tdep/jmpbuf.h @@ -5,7 +5,7 @@ #if defined __aarch64__ # include "tdep-aarch64/jmpbuf.h" -#if defined __arm__ +#elif defined __arm__ # include "tdep-arm/jmpbuf.h" #elif defined __hppa__ # include "tdep-hppa/jmpbuf.h" diff --git a/contrib/libunwind/src/Makefile.am b/contrib/libunwind/src/Makefile.am new file mode 100644 index 00000000000..7514ab551aa --- /dev/null +++ b/contrib/libunwind/src/Makefile.am @@ -0,0 +1,749 @@ +SOVERSION=8:1:0 # See comments at end of file. +SETJMP_SO_VERSION=0:0:0 +COREDUMP_SO_VERSION=0:0:0 +# +# Don't link with start-files since we don't use any constructors/destructors: +# +COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES) + +lib_LIBRARIES = +lib_LTLIBRARIES = +if !REMOTE_ONLY +lib_LTLIBRARIES += libunwind.la +if BUILD_PTRACE +lib_LTLIBRARIES += libunwind-ptrace.la +endif +if BUILD_COREDUMP +lib_LTLIBRARIES += libunwind-coredump.la +endif +endif + +noinst_HEADERS = +noinst_LTLIBRARIES = + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libunwind-generic.pc + +if !REMOTE_ONLY +pkgconfig_DATA += unwind/libunwind.pc +endif + +if BUILD_PTRACE +pkgconfig_DATA += ptrace/libunwind-ptrace.pc +endif + +if BUILD_SETJMP +pkgconfig_DATA += setjmp/libunwind-setjmp.pc +endif + +if BUILD_COREDUMP +pkgconfig_DATA += coredump/libunwind-coredump.pc +endif + +### libunwind-ptrace: +libunwind_ptrace_la_SOURCES = \ + ptrace/_UPT_elf.c \ + ptrace/_UPT_accessors.c ptrace/_UPT_access_fpreg.c \ + ptrace/_UPT_access_mem.c ptrace/_UPT_access_reg.c \ + ptrace/_UPT_create.c ptrace/_UPT_destroy.c \ + ptrace/_UPT_find_proc_info.c ptrace/_UPT_get_dyn_info_list_addr.c \ + ptrace/_UPT_put_unwind_info.c ptrace/_UPT_get_proc_name.c \ + ptrace/_UPT_reg_offset.c ptrace/_UPT_resume.c +noinst_HEADERS += ptrace/_UPT_internal.h + +### libunwind-coredump: +libunwind_coredump_la_SOURCES = \ + coredump/_UCD_accessors.c \ + coredump/_UCD_create.c \ + coredump/_UCD_destroy.c \ + coredump/_UCD_access_mem.c \ + coredump/_UCD_elf_map_image.c \ + coredump/_UCD_find_proc_info.c \ + coredump/_UCD_get_proc_name.c \ + \ + coredump/_UPT_elf.c \ + coredump/_UPT_access_fpreg.c \ + coredump/_UPT_get_dyn_info_list_addr.c \ + coredump/_UPT_put_unwind_info.c \ + coredump/_UPT_resume.c +libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(COREDUMP_SO_VERSION) +libunwind_coredump_la_LIBADD = $(LIBLZMA) +noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h + +### libunwind-setjmp: +libunwind_setjmp_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ + -version-info $(SETJMP_SO_VERSION) + +if USE_ELF32 +LIBUNWIND_ELF = libunwind-elf32.la +endif +if USE_ELF64 +LIBUNWIND_ELF = libunwind-elf64.la +endif +if USE_ELFXX +LIBUNWIND_ELF = libunwind-elfxx.la +endif + +libunwind_setjmp_la_LIBADD = $(LIBUNWIND_ELF) \ + libunwind-$(arch).la \ + libunwind.la -lc +libunwind_setjmp_la_SOURCES = setjmp/longjmp.c \ + setjmp/siglongjmp.c +noinst_HEADERS += setjmp/setjmp_i.h + +### libunwind: +libunwind_la_LIBADD = + +# List of arch-independent files needed by both local-only and generic +# libraries: +libunwind_la_SOURCES_common = \ + $(libunwind_la_SOURCES_os) \ + mi/init.c mi/flush_cache.c mi/mempool.c mi/strerror.c + +# List of arch-independent files needed by generic library (libunwind-$ARCH): +libunwind_la_SOURCES_generic = \ + mi/Gdyn-extract.c mi/Gdyn-remote.c mi/Gfind_dynamic_proc_info.c \ + mi/Gget_accessors.c \ + mi/Gget_proc_info_by_ip.c mi/Gget_proc_name.c \ + mi/Gput_dynamic_unwind_info.c mi/Gdestroy_addr_space.c \ + mi/Gget_reg.c mi/Gset_reg.c \ + mi/Gget_fpreg.c mi/Gset_fpreg.c \ + mi/Gset_caching_policy.c \ + mi/Gset_cache_size.c + +if SUPPORT_CXX_EXCEPTIONS +libunwind_la_SOURCES_local_unwind = \ + unwind/Backtrace.c unwind/DeleteException.c \ + unwind/FindEnclosingFunction.c unwind/ForcedUnwind.c \ + unwind/GetBSP.c unwind/GetCFA.c unwind/GetDataRelBase.c \ + unwind/GetGR.c unwind/GetIP.c unwind/GetLanguageSpecificData.c \ + unwind/GetRegionStart.c unwind/GetTextRelBase.c \ + unwind/RaiseException.c unwind/Resume.c \ + unwind/Resume_or_Rethrow.c unwind/SetGR.c unwind/SetIP.c \ + unwind/GetIPInfo.c + +# _ReadULEB()/_ReadSLEB() are needed for Intel C++ 8.0 compatibility +libunwind_la_SOURCES_os_linux_local = mi/_ReadULEB.c mi/_ReadSLEB.c +endif + +# List of arch-independent files needed by local-only library (libunwind): +libunwind_la_SOURCES_local_nounwind = \ + $(libunwind_la_SOURCES_os_local) \ + mi/backtrace.c \ + mi/dyn-cancel.c mi/dyn-info-list.c mi/dyn-register.c \ + mi/Ldyn-extract.c mi/Lfind_dynamic_proc_info.c \ + mi/Lget_accessors.c \ + mi/Lget_proc_info_by_ip.c mi/Lget_proc_name.c \ + mi/Lput_dynamic_unwind_info.c mi/Ldestroy_addr_space.c \ + mi/Lget_reg.c mi/Lset_reg.c \ + mi/Lget_fpreg.c mi/Lset_fpreg.c \ + mi/Lset_caching_policy.c \ + mi/Lset_cache_size.c + +libunwind_la_SOURCES_local = \ + $(libunwind_la_SOURCES_local_nounwind) \ + $(libunwind_la_SOURCES_local_unwind) + +noinst_HEADERS += os-linux.h +libunwind_la_SOURCES_os_linux = os-linux.c + +libunwind_la_SOURCES_os_hpux = os-hpux.c + +libunwind_la_SOURCES_os_freebsd = os-freebsd.c + +libunwind_la_SOURCES_os_qnx = os-qnx.c + +libunwind_dwarf_common_la_SOURCES = dwarf/global.c + +libunwind_dwarf_local_la_SOURCES = \ + dwarf/Lexpr.c dwarf/Lfde.c dwarf/Lparser.c dwarf/Lpe.c \ + dwarf/Lfind_proc_info-lsb.c \ + dwarf/Lfind_unwind_table.c +libunwind_dwarf_local_la_LIBADD = libunwind-dwarf-common.la + +libunwind_dwarf_generic_la_SOURCES = \ + dwarf/Gexpr.c dwarf/Gfde.c dwarf/Gparser.c dwarf/Gpe.c \ + dwarf/Gfind_proc_info-lsb.c \ + dwarf/Gfind_unwind_table.c +libunwind_dwarf_generic_la_LIBADD = libunwind-dwarf-common.la + +if USE_DWARF + noinst_LTLIBRARIES += libunwind-dwarf-common.la libunwind-dwarf-generic.la +if !REMOTE_ONLY + noinst_LTLIBRARIES += libunwind-dwarf-local.la +endif + libunwind_la_LIBADD += libunwind-dwarf-local.la +endif + +noinst_HEADERS += elf32.h elf64.h elfxx.h + +libunwind_elf32_la_SOURCES = elf32.c +libunwind_elf64_la_SOURCES = elf64.c +libunwind_elfxx_la_SOURCES = elfxx.c +libunwind_elf32_la_LIBADD = $(LIBLZMA) +libunwind_elf64_la_LIBADD = $(LIBLZMA) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) + +noinst_LTLIBRARIES += $(LIBUNWIND_ELF) +libunwind_la_LIBADD += $(LIBUNWIND_ELF) + +# The list of files that go into libunwind and libunwind-aarch64: +noinst_HEADERS += aarch64/init.h aarch64/offsets.h aarch64/unwind_i.h +libunwind_la_SOURCES_aarch64_common = $(libunwind_la_SOURCES_common) \ + aarch64/is_fpreg.c aarch64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_local) \ + aarch64/Lapply_reg_state.c aarch64/Lreg_states_iterate.c \ + aarch64/Lcreate_addr_space.c aarch64/Lget_proc_info.c \ + aarch64/Lget_save_loc.c aarch64/Lglobal.c aarch64/Linit.c \ + aarch64/Linit_local.c aarch64/Linit_remote.c \ + aarch64/Lis_signal_frame.c aarch64/Lregs.c aarch64/Lresume.c \ + aarch64/Lstash_frame.c aarch64/Lstep.c aarch64/Ltrace.c \ + aarch64/getcontext.S + +libunwind_aarch64_la_SOURCES_aarch64 = $(libunwind_la_SOURCES_aarch64_common) \ + $(libunwind_la_SOURCES_generic) \ + aarch64/Gapply_reg_state.c aarch64/Greg_states_iterate.c \ + aarch64/Gcreate_addr_space.c aarch64/Gget_proc_info.c \ + aarch64/Gget_save_loc.c aarch64/Gglobal.c aarch64/Ginit.c \ + aarch64/Ginit_local.c aarch64/Ginit_remote.c \ + aarch64/Gis_signal_frame.c aarch64/Gregs.c aarch64/Gresume.c \ + aarch64/Gstash_frame.c aarch64/Gstep.c aarch64/Gtrace.c + +# The list of files that go into libunwind and libunwind-arm: +noinst_HEADERS += arm/init.h arm/offsets.h arm/unwind_i.h +libunwind_la_SOURCES_arm_common = $(libunwind_la_SOURCES_common) \ + arm/is_fpreg.c arm/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os_local) \ + $(libunwind_la_SOURCES_local) \ + arm/getcontext.S \ + arm/Lapply_reg_state.c arm/Lreg_states_iterate.c \ + arm/Lcreate_addr_space.c arm/Lget_proc_info.c arm/Lget_save_loc.c \ + arm/Lglobal.c arm/Linit.c arm/Linit_local.c arm/Linit_remote.c \ + arm/Lregs.c arm/Lresume.c arm/Lstep.c \ + arm/Lex_tables.c arm/Lstash_frame.c arm/Ltrace.c + +# The list of files that go into libunwind-arm: +libunwind_arm_la_SOURCES_arm = $(libunwind_la_SOURCES_arm_common) \ + $(libunwind_la_SOURCES_arm_os) \ + $(libunwind_la_SOURCES_generic) \ + arm/Gapply_reg_state.c arm/Greg_states_iterate.c \ + arm/Gcreate_addr_space.c arm/Gget_proc_info.c arm/Gget_save_loc.c \ + arm/Gglobal.c arm/Ginit.c arm/Ginit_local.c arm/Ginit_remote.c \ + arm/Gregs.c arm/Gresume.c arm/Gstep.c \ + arm/Gex_tables.c arm/Gstash_frame.c arm/Gtrace.c + +# The list of files that go both into libunwind and libunwind-ia64: +noinst_HEADERS += ia64/init.h ia64/offsets.h ia64/regs.h \ + ia64/ucontext_i.h ia64/unwind_decoder.h ia64/unwind_i.h +libunwind_la_SOURCES_ia64_common = $(libunwind_la_SOURCES_common) \ + ia64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_local) \ + \ + ia64/dyn_info_list.S ia64/getcontext.S \ + \ + ia64/Lapply_reg_state.c ia64/Lreg_states_iterate.c \ + ia64/Lcreate_addr_space.c ia64/Lget_proc_info.c ia64/Lget_save_loc.c \ + ia64/Lglobal.c ia64/Linit.c ia64/Linit_local.c ia64/Linit_remote.c \ + ia64/Linstall_cursor.S ia64/Lis_signal_frame.c ia64/Lparser.c \ + ia64/Lrbs.c ia64/Lregs.c ia64/Lresume.c ia64/Lscript.c ia64/Lstep.c \ + ia64/Ltables.c ia64/Lfind_unwind_table.c + +# The list of files that go into libunwind-ia64: +libunwind_ia64_la_SOURCES_ia64 = $(libunwind_la_SOURCES_ia64_common) \ + $(libunwind_la_SOURCES_generic) \ + ia64/Gapply_reg_state.c ia64/Greg_states_iterate.c \ + ia64/Gcreate_addr_space.c ia64/Gget_proc_info.c ia64/Gget_save_loc.c \ + ia64/Gglobal.c ia64/Ginit.c ia64/Ginit_local.c ia64/Ginit_remote.c \ + ia64/Ginstall_cursor.S ia64/Gis_signal_frame.c ia64/Gparser.c \ + ia64/Grbs.c ia64/Gregs.c ia64/Gresume.c ia64/Gscript.c ia64/Gstep.c \ + ia64/Gtables.c ia64/Gfind_unwind_table.c + +# The list of files that go both into libunwind and libunwind-hppa: +noinst_HEADERS += hppa/init.h hppa/offsets.h hppa/unwind_i.h +libunwind_la_SOURCES_hppa_common = $(libunwind_la_SOURCES_common) \ + hppa/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_local) \ + hppa/getcontext.S hppa/setcontext.S \ + hppa/Lapply_reg_state.c hppa/Lreg_states_iterate.c \ + hppa/Lcreate_addr_space.c hppa/Lget_save_loc.c hppa/Lglobal.c \ + hppa/Linit.c hppa/Linit_local.c hppa/Linit_remote.c \ + hppa/Lis_signal_frame.c hppa/Lget_proc_info.c hppa/Lregs.c \ + hppa/Lresume.c hppa/Lstep.c + +# The list of files that go into libunwind-hppa: +libunwind_hppa_la_SOURCES_hppa = $(libunwind_la_SOURCES_hppa_common) \ + $(libunwind_la_SOURCES_generic) \ + hppa/Gapply_reg_state.c hppa/Greg_states_iterate.c \ + hppa/Gcreate_addr_space.c hppa/Gget_save_loc.c hppa/Gglobal.c \ + hppa/Ginit.c hppa/Ginit_local.c hppa/Ginit_remote.c \ + hppa/Gis_signal_frame.c hppa/Gget_proc_info.c hppa/Gregs.c \ + hppa/Gresume.c hppa/Gstep.c + +# The list of files that go info libunwind and libunwind-mips: +noinst_HEADERS += mips/init.h mips/offsets.h mips/unwind_i.h +libunwind_la_SOURCES_mips_common = $(libunwind_la_SOURCES_common) \ + mips/is_fpreg.c mips/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_local) \ + mips/getcontext.S \ + mips/Lapply_reg_state.c mips/Lreg_states_iterate.c \ + mips/Lcreate_addr_space.c mips/Lget_proc_info.c mips/Lget_save_loc.c \ + mips/Lglobal.c mips/Linit.c mips/Linit_local.c mips/Linit_remote.c \ + mips/Lis_signal_frame.c mips/Lregs.c mips/Lresume.c mips/Lstep.c + +libunwind_mips_la_SOURCES_mips = $(libunwind_la_SOURCES_mips_common) \ + $(libunwind_la_SOURCES_generic) \ + mips/Gapply_reg_state.c mips/Greg_states_iterate.c \ + mips/Gcreate_addr_space.c mips/Gget_proc_info.c mips/Gget_save_loc.c \ + mips/Gglobal.c mips/Ginit.c mips/Ginit_local.c mips/Ginit_remote.c \ + mips/Gis_signal_frame.c mips/Gregs.c mips/Gresume.c mips/Gstep.c + +# The list of files that go info libunwind and libunwind-tilegx: +noinst_HEADERS += tilegx/init.h tilegx/offsets.h tilegx/unwind_i.h +libunwind_la_SOURCES_tilegx_common = $(libunwind_la_SOURCES_common) \ + tilegx/is_fpreg.c tilegx/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_local) \ + tilegx/getcontext.S \ + tilegx/Lapply_reg_state.c tilegx/Lreg_states_iterate.c \ + tilegx/Lcreate_addr_space.c tilegx/Lget_proc_info.c tilegx/Lget_save_loc.c \ + tilegx/Lglobal.c tilegx/Linit.c tilegx/Linit_local.c tilegx/Linit_remote.c \ + tilegx/Lis_signal_frame.c tilegx/Lregs.c tilegx/Lresume.c tilegx/Lstep.c + +libunwind_tilegx_la_SOURCES_tilegx = $(libunwind_la_SOURCES_tilegx_common) \ + $(libunwind_la_SOURCES_generic) \ + tilegx/Gapply_reg_state.c tilegx/Greg_states_iterate.c \ + tilegx/Gcreate_addr_space.c tilegx/Gget_proc_info.c tilegx/Gget_save_loc.c \ + tilegx/Gglobal.c tilegx/Ginit.c tilegx/Ginit_local.c tilegx/Ginit_remote.c \ + tilegx/Gis_signal_frame.c tilegx/Gregs.c tilegx/Gresume.c tilegx/Gstep.c + + +# The list of files that go both into libunwind and libunwind-x86: +noinst_HEADERS += x86/init.h x86/offsets.h x86/unwind_i.h +libunwind_la_SOURCES_x86_common = $(libunwind_la_SOURCES_common) \ + x86/is_fpreg.c x86/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86/Lapply_reg_state.c x86/Lreg_states_iterate.c \ + x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ + x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ + x86/Lget_proc_info.c x86/Lregs.c \ + x86/Lresume.c x86/Lstep.c + +# The list of files that go into libunwind-x86: +libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ + $(libunwind_la_SOURCES_x86_os) \ + $(libunwind_la_SOURCES_generic) \ + x86/Gapply_reg_state.c x86/Greg_states_iterate.c \ + x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c \ + x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c \ + x86/Gget_proc_info.c x86/Gregs.c \ + x86/Gresume.c x86/Gstep.c + +# The list of files that go both into libunwind and libunwind-x86_64: +noinst_HEADERS += x86_64/offsets.h \ + x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h +libunwind_la_SOURCES_x86_64_common = $(libunwind_la_SOURCES_common) \ + x86_64/is_fpreg.c x86_64/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os_local) \ + $(libunwind_la_SOURCES_local) \ + x86_64/setcontext.S \ + x86_64/Lapply_reg_state.c x86_64/Lreg_states_iterate.c \ + x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \ + x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c \ + x86_64/Lget_proc_info.c x86_64/Lregs.c x86_64/Lresume.c \ + x86_64/Lstash_frame.c x86_64/Lstep.c x86_64/Ltrace.c x86_64/getcontext.S + +# The list of files that go into libunwind-x86_64: +libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common) \ + $(libunwind_la_SOURCES_x86_64_os) \ + $(libunwind_la_SOURCES_generic) \ + x86_64/Gapply_reg_state.c x86_64/Greg_states_iterate.c \ + x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \ + x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c \ + x86_64/Gget_proc_info.c x86_64/Gregs.c x86_64/Gresume.c \ + x86_64/Gstash_frame.c x86_64/Gstep.c x86_64/Gtrace.c + +# The list of local files that go to Power 64 and 32: +libunwind_la_SOURCES_ppc = \ + ppc/Lget_proc_info.c ppc/Lget_save_loc.c ppc/Linit_local.c \ + ppc/Linit_remote.c ppc/Lis_signal_frame.c + +# The list of generic files that go to Power 64 and 32: +libunwind_ppc_la_SOURCES_ppc_generic = \ + ppc/Gget_proc_info.c ppc/Gget_save_loc.c ppc/Ginit_local.c \ + ppc/Ginit_remote.c ppc/Gis_signal_frame.c + +# The list of files that go both into libunwind and libunwind-ppc32: +noinst_HEADERS += ppc32/init.h ppc32/unwind_i.h ppc32/ucontext_i.h +libunwind_la_SOURCES_ppc32_common = $(libunwind_la_SOURCES_common) \ + ppc32/is_fpreg.c ppc32/regname.c ppc32/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc32/Lapply_reg_state.c ppc32/Lreg_states_iterate.c \ + ppc32/Lcreate_addr_space.c \ + ppc32/Lglobal.c ppc32/Linit.c \ + ppc32/Lregs.c ppc32/Lresume.c ppc32/Lstep.c + +# The list of files that go into libunwind-ppc32: +libunwind_ppc32_la_SOURCES_ppc32 = $(libunwind_la_SOURCES_ppc32_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc32/Gapply_reg_state.c ppc32/Greg_states_iterate.c \ + ppc32/Gcreate_addr_space.c \ + ppc32/Gglobal.c ppc32/Ginit.c \ + ppc32/Gregs.c ppc32/Gresume.c ppc32/Gstep.c + +# The list of files that go both into libunwind and libunwind-ppc64: +noinst_HEADERS += ppc64/init.h ppc64/unwind_i.h ppc64/ucontext_i.h +libunwind_la_SOURCES_ppc64_common = $(libunwind_la_SOURCES_common) \ + ppc64/is_fpreg.c ppc64/regname.c ppc64/get_func_addr.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_ppc) \ + ppc64/Lapply_reg_state.c ppc64/Lreg_states_iterate.c \ + ppc64/Lcreate_addr_space.c \ + ppc64/Lglobal.c ppc64/Linit.c \ + ppc64/Lregs.c ppc64/Lresume.c ppc64/Lstep.c + +# The list of files that go into libunwind-ppc64: +libunwind_ppc64_la_SOURCES_ppc64 = $(libunwind_la_SOURCES_ppc64_common) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_ppc_la_SOURCES_ppc_generic) \ + ppc64/Gapply_reg_state.c ppc64/Greg_states_iterate.c \ + ppc64/Gcreate_addr_space.c \ + ppc64/Gglobal.c ppc64/Ginit.c \ + ppc64/Gregs.c ppc64/Gresume.c ppc64/Gstep.c + +# The list of files that go into libunwind and libunwind-sh: +noinst_HEADERS += sh/init.h sh/offsets.h sh/unwind_i.h +libunwind_la_SOURCES_sh_common = $(libunwind_la_SOURCES_common) \ + sh/is_fpreg.c sh/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_local) \ + sh/Lapply_reg_state.c sh/Lreg_states_iterate.c \ + sh/Lcreate_addr_space.c sh/Lget_proc_info.c sh/Lget_save_loc.c \ + sh/Lglobal.c sh/Linit.c sh/Linit_local.c sh/Linit_remote.c \ + sh/Lis_signal_frame.c sh/Lregs.c sh/Lresume.c sh/Lstep.c + +libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ + $(libunwind_la_SOURCES_generic) \ + sh/Gapply_reg_state.c sh/Greg_states_iterate.c \ + sh/Gcreate_addr_space.c sh/Gget_proc_info.c sh/Gget_save_loc.c \ + sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ + sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c + +if REMOTE_ONLY +install-exec-hook: +# Nothing to do here.... +else +# +# This is not ideal, but I know of no other way to install an +# alias for a library. For the shared version, we have to do +# a file check before creating the link, because it isn't going +# to be there if the user configured with --disable-shared. +# +install-exec-hook: + if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).a; then \ + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).a libunwind-generic.a; \ + fi + if test -f $(DESTDIR)$(libdir)/libunwind-$(arch).so; then \ + cd $(DESTDIR)$(libdir) && $(LN_S) -f libunwind-$(arch).so \ + libunwind-generic.so; \ + fi +endif + +if OS_LINUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_linux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_linux_local) + libunwind_la_SOURCES_x86_os = x86/Gos-linux.c + libunwind_x86_la_SOURCES_os = x86/getcontext-linux.S + libunwind_la_SOURCES_x86_os_local = x86/Los-linux.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-linux.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c + libunwind_la_SOURCES_arm_os = arm/Gos-linux.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_linux.c +endif + +if OS_HPUX + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_hpux) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_hpux_local) +endif + +if OS_FREEBSD + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_freebsd) + libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_freebsd_local) + libunwind_la_SOURCES_x86_os = x86/Gos-freebsd.c + libunwind_x86_la_SOURCES_os = x86/getcontext-freebsd.S + libunwind_la_SOURCES_x86_os_local = x86/Los-freebsd.c + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-freebsd.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-freebsd.c + libunwind_la_SOURCES_arm_os = arm/Gos-freebsd.c + libunwind_la_SOURCES_arm_os_local = arm/Los-freebsd.c + libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.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) + libunwind_la_SOURCES_arm_os = arm/Gos-other.c + libunwind_la_SOURCES_arm_os_local = arm/Los-other.c +endif + +if ARCH_AARCH64 + lib_LTLIBRARIES += libunwind-aarch64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_aarch64) + libunwind_aarch64_la_SOURCES = $(libunwind_aarch64_la_SOURCES_aarch64) + libunwind_aarch64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_aarch64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_aarch64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_aarch64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += aarch64/siglongjmp.S +else +if ARCH_ARM + lib_LTLIBRARIES += libunwind-arm.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_arm) + libunwind_arm_la_SOURCES = $(libunwind_arm_la_SOURCES_arm) + libunwind_arm_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_arm_la_LIBADD = libunwind-dwarf-generic.la + libunwind_arm_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_arm_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += arm/siglongjmp.S +else +if ARCH_IA64 + BUILT_SOURCES = Gcursor_i.h Lcursor_i.h +mk_Gcursor_i.s: $(srcdir)/ia64/mk_Gcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Gcursor_i.c" -o mk_Gcursor_i.s +mk_Lcursor_i.s: $(srcdir)/ia64/mk_Lcursor_i.c + $(COMPILE) -S "$(srcdir)/ia64/mk_Lcursor_i.c" -o mk_Lcursor_i.s +Gcursor_i.h: mk_Gcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Gcursor_i.s > Gcursor_i.h +Lcursor_i.h: mk_Lcursor_i.s + "$(srcdir)/ia64/mk_cursor_i" mk_Lcursor_i.s > Lcursor_i.h + + lib_LTLIBRARIES += libunwind-ia64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ia64) + libunwind_ia64_la_SOURCES = $(libunwind_ia64_la_SOURCES_ia64) + libunwind_ia64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ia64_la_LIBADD = libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ia64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ia64/setjmp.S ia64/sigsetjmp.S \ + ia64/longjmp.S ia64/siglongjmp.S +else +if ARCH_HPPA + lib_LTLIBRARIES += libunwind-hppa.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_hppa) + libunwind_hppa_la_SOURCES = $(libunwind_hppa_la_SOURCES_hppa) + libunwind_hppa_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_hppa_la_LIBADD = libunwind-dwarf-generic.la + libunwind_hppa_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_hppa_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += hppa/siglongjmp.S +else +if ARCH_MIPS + lib_LTLIBRARIES += libunwind-mips.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_mips) + libunwind_mips_la_SOURCES = $(libunwind_mips_la_SOURCES_mips) + libunwind_mips_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_mips_la_LIBADD = libunwind-dwarf-generic.la + libunwind_mips_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_mips_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += mips/siglongjmp.S +else +if ARCH_TILEGX + lib_LTLIBRARIES += libunwind-tilegx.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_tilegx) + libunwind_tilegx_la_SOURCES = $(libunwind_tilegx_la_SOURCES_tilegx) + libunwind_tilegx_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_tilegx_la_LIBADD = libunwind-dwarf-generic.la + libunwind_tilegx_la_LIBADD += libunwind-elfxx.la +if !REMOTE_ONLY + libunwind_tilegx_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += tilegx/siglongjmp.S +else +if ARCH_X86 + lib_LTLIBRARIES += libunwind-x86.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86) $(libunwind_x86_la_SOURCES_os) + libunwind_x86_la_SOURCES = $(libunwind_x86_la_SOURCES_x86) + libunwind_x86_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_x86_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86/longjmp.S x86/siglongjmp.S +else +if ARCH_X86_64 + lib_LTLIBRARIES += libunwind-x86_64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_x86_64) + libunwind_x86_64_la_SOURCES = $(libunwind_x86_64_la_SOURCES_x86_64) + libunwind_x86_64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_x86_64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_x86_64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_x86_64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += x86_64/longjmp.S x86_64/siglongjmp.S +else +if ARCH_PPC32 + lib_LTLIBRARIES += libunwind-ppc32.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc32) + libunwind_ppc32_la_SOURCES = $(libunwind_ppc32_la_SOURCES_ppc32) + libunwind_ppc32_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc32_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc32_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_ppc32_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_PPC64 + lib_LTLIBRARIES += libunwind-ppc64.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_ppc64) + libunwind_ppc64_la_SOURCES = $(libunwind_ppc64_la_SOURCES_ppc64) + libunwind_ppc64_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_ppc64_la_LIBADD = libunwind-dwarf-generic.la + libunwind_ppc64_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_ppc64_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += ppc/longjmp.S ppc/siglongjmp.S +else +if ARCH_SH + lib_LTLIBRARIES += libunwind-sh.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_sh) + libunwind_sh_la_SOURCES = $(libunwind_sh_la_SOURCES_sh) + libunwind_sh_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_sh_la_LIBADD = libunwind-dwarf-generic.la + libunwind_sh_la_LIBADD += libunwind-elf32.la +if !REMOTE_ONLY + libunwind_sh_la_LIBADD += libunwind.la -lc +endif + libunwind_setjmp_la_SOURCES += sh/siglongjmp.S + +endif # ARCH_SH +endif # ARCH_PPC64 +endif # ARCH_PPC32 +endif # ARCH_X86_64 +endif # ARCH_X86 +endif # ARCH_TILEGX +endif # ARCH_MIPS +endif # ARCH_HPPA +endif # ARCH_IA64 +endif # ARCH_ARM +endif # ARCH_AARCH64 + +# libunwind-setjmp depends on libunwind-$(arch). Therefore must be added +# at the end. +if BUILD_SETJMP +lib_LTLIBRARIES += libunwind-setjmp.la +endif + +# +# Don't link with standard libraries, because those may mention +# libunwind already. +# +libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ + $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) +libunwind_la_LIBADD += -lc $(LIBCRTS) +libunwind_la_LIBADD += $(LIBLZMA) + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. +AM_CCASFLAGS = $(AM_CPPFLAGS) +noinst_HEADERS += unwind/unwind-internal.h + +EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ + $(libunwind_la_SOURCES_arm) \ + $(libunwind_la_SOURCES_hppa) \ + $(libunwind_la_SOURCES_ia64) \ + $(libunwind_la_SOURCES_mips) \ + $(libunwind_la_SOURCES_sh) \ + $(libunwind_la_SOURCES_x86) \ + $(libunwind_la_SOURCES_os_freebsd) \ + $(libunwind_la_SOURCES_os_linux) \ + $(libunwind_la_SOURCES_os_hpux) \ + $(libunwind_la_SOURCES_os_qnx) \ + $(libunwind_la_SOURCES_common) \ + $(libunwind_la_SOURCES_local) \ + $(libunwind_la_SOURCES_generic) \ + $(libunwind_aarch64_la_SOURCES_aarch64) \ + $(libunwind_arm_la_SOURCES_arm) \ + $(libunwind_hppa_la_SOURCES_hppa) \ + $(libunwind_ia64_la_SOURCES_ia64) \ + $(libunwind_mips_la_SOURCES_mips) \ + $(libunwind_sh_la_SOURCES_sh) \ + $(libunwind_x86_la_SOURCES_x86) \ + $(libunwind_x86_64_la_SOURCES_x86_64) + +MAINTAINERCLEANFILES = Makefile.in + +# The -version-info flag accepts an argument of the form +# `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets +# current to 3, revision to 12, and age to 1. + +# If either revision or age are omitted, they default to 0. Also note +# that age must be less than or equal to the current interface number. + +# Here are a set of rules to help you update your library version +# information: + +# 1. Start with version information of `0:0:0' for each libtool +# library. + +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. + +# 3. If the library source code has changed at all since the last +# update, then increment revision (`c:r:a' becomes `c:r+1:a'). + +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment current, and set revision to 0. + +# 5. If any interfaces have been added since the last public release, +# then increment age. + +# 6. If any interfaces have been removed since the last public +# release, then set age to 0. diff --git a/contrib/libunwind/src/aarch64/Ginit.c b/contrib/libunwind/src/aarch64/Ginit.c index b9181ef061f..ab3999f307c 100644 --- a/contrib/libunwind/src/aarch64/Ginit.c +++ b/contrib/libunwind/src/aarch64/Ginit.c @@ -43,8 +43,10 @@ PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; static inline void * uc_addr (ucontext_t *uc, int reg) { - if (reg >= UNW_AARCH64_X0 && reg <= UNW_AARCH64_V31) + if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) return &uc->uc_mcontext.regs[reg]; + else if (reg >= UNW_AARCH64_V0 && reg <= UNW_AARCH64_V31) + return &GET_FPCTX(uc)->vregs[reg - UNW_AARCH64_V0]; else return NULL; } @@ -172,7 +174,7 @@ HIDDEN void aarch64_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/aarch64/Ginit_local.c b/contrib/libunwind/src/aarch64/Ginit_local.c index 45b1b30083e..d284224a369 100644 --- a/contrib/libunwind/src/aarch64/Ginit_local.c +++ b/contrib/libunwind/src/aarch64/Ginit_local.c @@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/aarch64/Gregs.c b/contrib/libunwind/src/aarch64/Gregs.c index 6288275bcd9..a8843734459 100644 --- a/contrib/libunwind/src/aarch64/Gregs.c +++ b/contrib/libunwind/src/aarch64/Gregs.c @@ -55,6 +55,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, loc = c->dwarf.loc[reg]; break; + case UNW_AARCH64_X30: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ case UNW_AARCH64_X4: case UNW_AARCH64_X5: case UNW_AARCH64_X6: @@ -81,7 +84,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_AARCH64_X27: case UNW_AARCH64_X28: case UNW_AARCH64_X29: - case UNW_AARCH64_X30: case UNW_AARCH64_PC: case UNW_AARCH64_PSTATE: loc = c->dwarf.loc[reg]; @@ -108,6 +110,9 @@ HIDDEN int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, int write) { - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; + dwarf_loc_t loc = c->dwarf.loc[reg]; + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); } diff --git a/contrib/libunwind/src/aarch64/Gresume.c b/contrib/libunwind/src/aarch64/Gresume.c index d9acfa7ccc9..65517a252d1 100644 --- a/contrib/libunwind/src/aarch64/Gresume.c +++ b/contrib/libunwind/src/aarch64/Gresume.c @@ -40,7 +40,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) { /* Since there are no signals involved here we restore EH and non scratch registers only. */ - unsigned long regs[15]; + unsigned long regs[24]; regs[0] = uc->uc_mcontext.regs[0]; regs[1] = uc->uc_mcontext.regs[1]; regs[2] = uc->uc_mcontext.regs[2]; @@ -55,7 +55,16 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) regs[11] = uc->uc_mcontext.regs[26]; regs[12] = uc->uc_mcontext.regs[27]; regs[13] = uc->uc_mcontext.regs[28]; - regs[14] = uc->uc_mcontext.regs[30]; /* LR */ + regs[14] = uc->uc_mcontext.regs[29]; /* FP */ + regs[15] = uc->uc_mcontext.regs[30]; /* LR */ + regs[16] = GET_FPCTX(uc)->vregs[8]; + regs[17] = GET_FPCTX(uc)->vregs[9]; + regs[18] = GET_FPCTX(uc)->vregs[10]; + regs[19] = GET_FPCTX(uc)->vregs[11]; + regs[20] = GET_FPCTX(uc)->vregs[12]; + regs[21] = GET_FPCTX(uc)->vregs[13]; + regs[22] = GET_FPCTX(uc)->vregs[14]; + regs[23] = GET_FPCTX(uc)->vregs[15]; unsigned long sp = uc->uc_mcontext.sp; struct regs_overlay { @@ -72,7 +81,11 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) "ldp x23, x24, [x4,64]\n" "ldp x25, x26, [x4,80]\n" "ldp x27, x28, [x4,96]\n" - "ldr x30, [x4,112]\n" + "ldp x29, x30, [x4,112]\n" + "ldp d8, d9, [x4,128]\n" + "ldp d10, d11, [x4,144]\n" + "ldp d12, d13, [x4,160]\n" + "ldp d14, d15, [x4,176]\n" "mov sp, x5\n" "ret \n" : @@ -147,7 +160,7 @@ establish_machine_state (struct cursor *c) Debug (8, "copying out cursor state\n"); - for (reg = 0; reg <= UNW_AARCH64_PSTATE; ++reg) + for (reg = 0; reg <= UNW_AARCH64_V31; ++reg) { Debug (16, "copying %s %d\n", unw_regname (reg), reg); if (unw_is_fpreg (reg)) diff --git a/contrib/libunwind/src/aarch64/Gstep.c b/contrib/libunwind/src/aarch64/Gstep.c index 44fbb04c8c5..e38ff9794f5 100644 --- a/contrib/libunwind/src/aarch64/Gstep.c +++ b/contrib/libunwind/src/aarch64/Gstep.c @@ -27,6 +27,30 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "unwind_i.h" #include "offsets.h" +/* Recognise PLT entries such as: + 40ddf0: b0000570 adrp x16, 4ba000 <_GLOBAL_OFFSET_TABLE_+0x2a8> + 40ddf4: f9433611 ldr x17, [x16,#1640] + 40ddf8: 9119a210 add x16, x16, #0x668 + 40ddfc: d61f0220 br x17 */ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (c->as); + if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 + || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) + return 0; + + ret = (((w0 & 0xff0000009f000000) == 0xf900000090000000) + && ((w1 & 0xffffffffff000000) == 0xd61f022091000000)); + + Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); + return ret; +} + PROTECTED int unw_handle_signal_frame (unw_cursor_t *cursor) { @@ -101,6 +125,7 @@ unw_handle_signal_frame (unw_cursor_t *cursor) dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; return 1; } @@ -125,7 +150,40 @@ unw_step (unw_cursor_t *cursor) return ret; if (unlikely (ret < 0)) - return 0; + { + /* DWARF failed. */ + if (is_plt_entry (&c->dwarf)) + { + Debug (2, "found plt entry\n"); + c->frame_info.frame_type = UNW_AARCH64_FRAME_STANDARD; + } + else + { + Debug (2, "fallback\n"); + c->frame_info.frame_type = UNW_AARCH64_FRAME_GUESSED; + } + /* Use link register (X30). */ + c->frame_info.cfa_reg_offset = 0; + c->frame_info.cfa_reg_sp = 0; + c->frame_info.fp_cfa_offset = -1; + c->frame_info.lr_cfa_offset = -1; + c->frame_info.sp_cfa_offset = -1; + c->dwarf.loc[UNW_AARCH64_PC] = c->dwarf.loc[UNW_AARCH64_X30]; + c->dwarf.loc[UNW_AARCH64_X30] = DWARF_NULL_LOC; + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[UNW_AARCH64_PC])) + { + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip); + if (ret < 0) + { + Debug (2, "failed to get pc from link register: %d\n", ret); + return ret; + } + Debug (2, "link register (x30) = 0x%016lx\n", c->dwarf.ip); + ret = 1; + } + else + c->dwarf.ip = 0; + } return (c->dwarf.ip == 0) ? 0 : 1; } diff --git a/contrib/libunwind/src/aarch64/unwind_i.h b/contrib/libunwind/src/aarch64/unwind_i.h index 79b342cdab9..3d324c2b08b 100644 --- a/contrib/libunwind/src/aarch64/unwind_i.h +++ b/contrib/libunwind/src/aarch64/unwind_i.h @@ -59,4 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, } while (0) #endif +#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) + #endif /* unwind_i_h */ diff --git a/contrib/libunwind/src/arm/Ginit.c b/contrib/libunwind/src/arm/Ginit.c index 1ed3dbfc508..2d0b2ca8db1 100644 --- a/contrib/libunwind/src/arm/Ginit.c +++ b/contrib/libunwind/src/arm/Ginit.c @@ -126,6 +126,11 @@ static int access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, void *arg) { + /* validate address */ + const struct cursor *c = (const struct cursor *) arg; + if (c && validate_mem(addr)) + return -1; + if (write) { Debug (16, "mem[%x] <- %x\n", addr, *val); @@ -133,11 +138,6 @@ access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, } else { - /* validate address */ - const struct cursor *c = (const struct cursor *) arg; - if (c && validate_mem(addr)) - return -1; - *val = *(unw_word_t *) addr; Debug (16, "mem[%x] -> %x\n", addr, *val); } @@ -220,7 +220,7 @@ HIDDEN void arm_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = arm_find_proc_info; local_addr_space.acc.put_unwind_info = arm_put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/arm/Ginit_local.c b/contrib/libunwind/src/arm/Ginit_local.c index f74d55e7358..65941c369e4 100644 --- a/contrib/libunwind/src/arm/Ginit_local.c +++ b/contrib/libunwind/src/arm/Ginit_local.c @@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc) +unw_init_local2 (unw_cursor_t *cursor, unw_context_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/arm/Gis_signal_frame.c b/contrib/libunwind/src/arm/Gis_signal_frame.c deleted file mode 100644 index e8efe7f4a85..00000000000 --- a/contrib/libunwind/src/arm/Gis_signal_frame.c +++ /dev/null @@ -1,87 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 CodeSourcery - Copyright 2011 Linaro Limited - -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 -#include "unwind_i.h" - -#ifdef __linux__ -#define ARM_NR_sigreturn 119 -#define ARM_NR_rt_sigreturn 173 -#define ARM_NR_OABI_SYSCALL_BASE 0x900000 - -/* ARM EABI sigreturn (the syscall number is loaded into r7) */ -#define MOV_R7_SIGRETURN (0xe3a07000UL | ARM_NR_sigreturn) -#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | ARM_NR_rt_sigreturn) - -/* ARM OABI sigreturn (using SWI) */ -#define ARM_SIGRETURN \ - (0xef000000UL | ARM_NR_sigreturn | ARM_NR_OABI_SYSCALL_BASE) -#define ARM_RT_SIGRETURN \ - (0xef000000UL | ARM_NR_rt_sigreturn | ARM_NR_OABI_SYSCALL_BASE) - -/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ -#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_sigreturn) -#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_rt_sigreturn) -#endif /* __linux__ */ - -/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal - frame. */ -PROTECTED int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret; - - as = c->dwarf.as; - a = unw_get_accessors (as); - arg = c->dwarf.as_arg; - - ip = c->dwarf.ip; - - if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) - return ret; - - /* Return 1 if the IP points to a non-RT sigreturn sequence. */ - if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN) - return 1; - /* Return 2 if the IP points to a RT sigreturn sequence. */ - else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN - || w0 == THUMB_RT_SIGRETURN) - return 2; - - return 0; -#elif defined(__QNX__) - /* Not supported yet */ - return 0; -#else - printf ("%s: implement me\n", __FUNCTION__); - return -UNW_ENOINFO; -#endif -} diff --git a/contrib/libunwind/src/arm/Gos-freebsd.c b/contrib/libunwind/src/arm/Gos-freebsd.c new file mode 100644 index 00000000000..3b9d2c3eb52 --- /dev/null +++ b/contrib/libunwind/src/arm/Gos-freebsd.c @@ -0,0 +1,129 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + Copyright 2015 The FreeBSD Foundation + + Portions of this software were developed by Konstantin Belousov + under sponsorship from the FreeBSD Foundation. + +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 +#include +#include "unwind_i.h" +#include "offsets.h" +#include "ex_tables.h" + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, fmt; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + fmt = unw_is_signal_frame(cursor); + + c->dwarf.pi_valid = 0; + + if (fmt == UNW_ARM_FRAME_SYSCALL) + { + c->sigcontext_format = ARM_SCF_FREEBSD_SYSCALL; + c->frame_info.frame_type = UNW_ARM_FRAME_SYSCALL; + c->frame_info.cfa_reg_offset = 0; + c->dwarf.loc[UNW_ARM_R7] = c->dwarf.loc[UNW_ARM_R12]; + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R14], &c->dwarf.ip); + return 1; + } + + c->sigcontext_format = ARM_SCF_FREEBSD_SIGFRAME; + sc_addr = sp_addr; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ +#define ROFF(n) (FREEBSD_SC_UCONTEXT_OFF + FREEBSD_UC_MCONTEXT_OFF + \ + FREEBSD_MC_R0_OFF + (n) * 4) +#define SL(n) \ + c->dwarf.loc[UNW_ARM_R ## n] = DWARF_LOC (sc_addr + ROFF(n), 0); + SL(0); SL(1); SL(2); SL(3); SL(4); SL(5); SL(6); SL(7); + SL(8); SL(9); SL(10); SL(11); SL(12); SL(13); SL(14); SL(15); +#undef SL +#undef ROFF + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + + return 1; +} + +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 8, &w2, 0, arg)) < 0) + return ret; + if ((ret = (*a->access_mem) (as, ip + 12, &w3, 0, arg)) < 0) + return ret; + + if (w0 == 0xe1a0000d && w1 == 0xe2800040 && w2 == 0xe59f700c && + w3 == 0xef0001a1) + return UNW_ARM_FRAME_SIGRETURN; + + if ((ret = (*a->access_mem) (as, ip - 4, &w0, 0, arg)) < 0) + return ret; + if (w0 == 0xef000000) + return UNW_ARM_FRAME_SYSCALL; + + return 0; +} diff --git a/contrib/libunwind/src/arm/Gos-linux.c b/contrib/libunwind/src/arm/Gos-linux.c new file mode 100644 index 00000000000..585c2014fde --- /dev/null +++ b/contrib/libunwind/src/arm/Gos-linux.c @@ -0,0 +1,182 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +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 +#include +#include "unwind_i.h" +#include "offsets.h" + +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; + struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); + + if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) + return -UNW_EUNSPEC; + + /* Obtain signal frame type (non-RT or RT). */ + ret = unw_is_signal_frame (cursor); + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = c->dwarf.cfa; + c->sigcontext_pc = c->dwarf.ip; + + /* Since kernel version 2.6.18 the non-RT signal frame starts with a + ucontext while the RT signal frame starts with a siginfo, followed + by a sigframe whose first element is an ucontext. + Prior 2.6.18 the non-RT signal frame starts with a sigcontext while + the RT signal frame starts with two pointers followed by a siginfo + and an ucontext. The first pointer points to the start of the siginfo + structure and the second one to the ucontext structure. */ + + if (ret == 1) + { + /* Handle non-RT signal frames. Check if the first word on the stack + is the magic number. */ + if (sp == 0x5ac3c35a) + { + c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; + sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; + sc_addr = sp_addr; + } + } + else if (ret == 2) + { + /* Handle RT signal frames. Check if the first word on the stack is a + pointer to the siginfo structure. */ + if (sp == sp_addr + 8) + { + c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; + sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + else + { + c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; + sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; + } + } + else + return -UNW_EUNSPEC; + + c->sigcontext_addr = sc_addr; + c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; + c->frame_info.cfa_reg_offset = sc_addr - sp_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); + c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); + c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); + c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); + c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); + c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); + c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); + c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); + c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); + c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); + c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); + c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0); + c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0); + c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); + c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0); + c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); + + /* Set SP/CFA and PC/IP. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + + return 1; +} + +#define ARM_NR_sigreturn 119 +#define ARM_NR_rt_sigreturn 173 +#define ARM_NR_OABI_SYSCALL_BASE 0x900000 + +/* ARM EABI sigreturn (the syscall number is loaded into r7) */ +#define MOV_R7_SIGRETURN (0xe3a07000UL | ARM_NR_sigreturn) +#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | ARM_NR_rt_sigreturn) + +/* ARM OABI sigreturn (using SWI) */ +#define ARM_SIGRETURN \ + (0xef000000UL | ARM_NR_sigreturn | ARM_NR_OABI_SYSCALL_BASE) +#define ARM_RT_SIGRETURN \ + (0xef000000UL | ARM_NR_rt_sigreturn | ARM_NR_OABI_SYSCALL_BASE) + +/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ +#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_sigreturn) +#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | ARM_NR_rt_sigreturn) + +/* Thumb2 sigreturn (mov.w r7, $SYS_ify(rt_sigreturn/sigreturn)) */ +#define THUMB2_SIGRETURN (((0x0700 | ARM_NR_sigreturn) << 16) | \ + 0xf04f) +#define THUMB2_RT_SIGRETURN (((0x0700 | ARM_NR_rt_sigreturn) << 16) | \ + 0xf04f) +/* TODO: with different toolchains, there are a lot more possibilities */ + +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* The least bit denotes thumb/arm mode. Do not read there. */ + ip = c->dwarf.ip & ~0x1; + + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + + /* Return 1 if the IP points to a non-RT sigreturn sequence. */ + if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN + || w0 == THUMB2_SIGRETURN) + return 1; + /* Return 2 if the IP points to a RT sigreturn sequence. */ + else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN + || w0 == THUMB_RT_SIGRETURN || w0 == THUMB2_RT_SIGRETURN) + return 2; + + return 0; +} diff --git a/contrib/libunwind/src/ppc/Gcreate_addr_space.c b/contrib/libunwind/src/arm/Gos-other.c similarity index 65% rename from contrib/libunwind/src/ppc/Gcreate_addr_space.c rename to contrib/libunwind/src/arm/Gos-other.c index 21ec10fcd8c..66f38b1dace 100644 --- a/contrib/libunwind/src/ppc/Gcreate_addr_space.c +++ b/contrib/libunwind/src/arm/Gos-other.c @@ -1,8 +1,7 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2006-2007 IBM - Contributed by - Corey Ashford - Jose Flavio Aguilar Paulino + Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited + Copyright (C) 2012 Tommi Rantala This file is part of libunwind. @@ -25,30 +24,25 @@ 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 +#include +#include +#include "unwind_i.h" +#include "offsets.h" -#include - -PROTECTED unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) +PROTECTED int +unw_handle_signal_frame (unw_cursor_t *cursor) { -#ifdef UNW_LOCAL_ONLY - return NULL; + return -UNW_EUNSPEC; +} + +PROTECTED int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#if defined(__QNX__) + /* Not supported yet */ + return 0; #else - unw_addr_space_t as = malloc (sizeof (*as)); - - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - /* - * Linux ppc64 supports only big-endian. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - return as; + printf ("%s: implement me\n", __FUNCTION__); + return -UNW_ENOINFO; #endif } diff --git a/contrib/libunwind/src/arm/Gregs.c b/contrib/libunwind/src/arm/Gregs.c index 688771f31e4..0d52f0b2225 100644 --- a/contrib/libunwind/src/arm/Gregs.c +++ b/contrib/libunwind/src/arm/Gregs.c @@ -32,6 +32,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, switch (reg) { + case UNW_ARM_R15: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ case UNW_ARM_R0: case UNW_ARM_R1: case UNW_ARM_R2: @@ -46,7 +49,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_ARM_R11: case UNW_ARM_R12: case UNW_ARM_R14: - case UNW_ARM_R15: loc = c->dwarf.loc[reg - UNW_ARM_R0]; break; diff --git a/contrib/libunwind/src/arm/Gstep.c b/contrib/libunwind/src/arm/Gstep.c index 37e6c12f115..6679455ece2 100644 --- a/contrib/libunwind/src/arm/Gstep.c +++ b/contrib/libunwind/src/arm/Gstep.c @@ -45,8 +45,14 @@ arm_exidx_step (struct cursor *c) /* mark PC unsaved */ c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; - if ((ret = tdep_find_proc_info (&c->dwarf, c->dwarf.ip, 1)) < 0) - return ret; + /* check dynamic info first --- it overrides everything else */ + ret = unwi_find_dynamic_proc_info (c->dwarf.as, c->dwarf.ip, &c->dwarf.pi, 1, + c->dwarf.as_arg); + if (ret == -UNW_ENOINFO) + { + if ((ret = tdep_find_proc_info (&c->dwarf, c->dwarf.ip, 1)) < 0) + return ret; + } if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX) return -UNW_ENOINFO; @@ -73,99 +79,6 @@ arm_exidx_step (struct cursor *c) return (c->dwarf.ip == 0) ? 0 : 1; } -PROTECTED int -unw_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa; - struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0); - - if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0) - return -UNW_EUNSPEC; - - /* Obtain signal frame type (non-RT or RT). */ - ret = unw_is_signal_frame (cursor); - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = c->dwarf.cfa; - c->sigcontext_pc = c->dwarf.ip; - - /* Since kernel version 2.6.18 the non-RT signal frame starts with a - ucontext while the RT signal frame starts with a siginfo, followed - by a sigframe whose first element is an ucontext. - Prior 2.6.18 the non-RT signal frame starts with a sigcontext while - the RT signal frame starts with two pointers followed by a siginfo - and an ucontext. The first pointer points to the start of the siginfo - structure and the second one to the ucontext structure. */ - - if (ret == 1) - { - /* Handle non-RT signal frames. Check if the first word on the stack - is the magic number. */ - if (sp == 0x5ac3c35a) - { - c->sigcontext_format = ARM_SCF_LINUX_SIGFRAME; - sc_addr = sp_addr + LINUX_UC_MCONTEXT_OFF; - } - else - { - c->sigcontext_format = ARM_SCF_LINUX_OLD_SIGFRAME; - sc_addr = sp_addr; - } - } - else if (ret == 2) - { - /* Handle RT signal frames. Check if the first word on the stack is a - pointer to the siginfo structure. */ - if (sp == sp_addr + 8) - { - c->sigcontext_format = ARM_SCF_LINUX_OLD_RT_SIGFRAME; - sc_addr = sp_addr + 8 + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - else - { - c->sigcontext_format = ARM_SCF_LINUX_RT_SIGFRAME; - sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF; - } - } - else - return -UNW_EUNSPEC; - - c->sigcontext_addr = sc_addr; - c->frame_info.frame_type = UNW_ARM_FRAME_SIGRETURN; - c->frame_info.cfa_reg_offset = sc_addr - sp_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - c->dwarf.loc[UNW_ARM_R0] = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0); - c->dwarf.loc[UNW_ARM_R1] = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0); - c->dwarf.loc[UNW_ARM_R2] = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0); - c->dwarf.loc[UNW_ARM_R3] = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0); - c->dwarf.loc[UNW_ARM_R4] = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0); - c->dwarf.loc[UNW_ARM_R5] = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0); - c->dwarf.loc[UNW_ARM_R6] = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0); - c->dwarf.loc[UNW_ARM_R7] = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0); - c->dwarf.loc[UNW_ARM_R8] = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0); - c->dwarf.loc[UNW_ARM_R9] = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0); - c->dwarf.loc[UNW_ARM_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0); - c->dwarf.loc[UNW_ARM_R11] = DWARF_LOC (sc_addr + LINUX_SC_FP_OFF, 0); - c->dwarf.loc[UNW_ARM_R12] = DWARF_LOC (sc_addr + LINUX_SC_IP_OFF, 0); - c->dwarf.loc[UNW_ARM_R13] = DWARF_LOC (sc_addr + LINUX_SC_SP_OFF, 0); - c->dwarf.loc[UNW_ARM_R14] = DWARF_LOC (sc_addr + LINUX_SC_LR_OFF, 0); - c->dwarf.loc[UNW_ARM_R15] = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0); - - /* Set SP/CFA and PC/IP. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R13], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - - return 1; -} - PROTECTED int unw_step (unw_cursor_t *cursor) { @@ -210,14 +123,18 @@ unw_step (unw_cursor_t *cursor) /* Fall back on APCS frame parsing. Note: This won't work in case the ARM EABI is used. */ +#ifdef __FreeBSD__ + if (0) +#else if (unlikely (ret < 0)) +#endif { if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) { + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); ret = UNW_ESUCCESS; /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ unw_word_t instr, i; - Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); dwarf_loc_t ip_loc, fp_loc; unw_word_t frame; /* Mark all registers unsaved, since we don't know where @@ -260,7 +177,7 @@ unw_step (unw_cursor_t *cursor) c->dwarf.loc[UNW_ARM_R12] = ip_loc; c->dwarf.loc[UNW_ARM_R11] = fp_loc; c->dwarf.pi_valid = 0; - Debug(15, "ip=%lx\n", c->dwarf.ip); + Debug(15, "ip=%x\n", c->dwarf.ip); } else { @@ -268,5 +185,5 @@ unw_step (unw_cursor_t *cursor) } } } - return ret == -UNW_ENOINFO ? 0 : 1; + return ret == -UNW_ENOINFO ? 0 : ret; } diff --git a/contrib/libunwind/src/arm/Gtrace.c b/contrib/libunwind/src/arm/Gtrace.c index 135563a38f4..2f277520b36 100644 --- a/contrib/libunwind/src/arm/Gtrace.c +++ b/contrib/libunwind/src/arm/Gtrace.c @@ -503,7 +503,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) case UNW_ARM_FRAME_SIGRETURN: cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */ - +#if defined(__linux__) ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc); if (likely(ret >= 0)) ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_R7_OFF, r7); @@ -513,6 +513,9 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) doesn't save the link register in the prologue, e.g. kill. */ if (likely(ret >= 0)) ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr); +#elif defined(__FreeBSD__) + printf("XXX\n"); +#endif /* Resume stack at signal restoration point. The stack is not necessarily continuous here, especially with sigaltstack(). */ @@ -522,6 +525,10 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) d->use_prev_instr = 0; break; + case UNW_ARM_FRAME_SYSCALL: + printf("XXX1\n"); + break; + default: /* We cannot trace through this frame, give up and tell the caller we had to stop. Data collected so far may still be diff --git a/contrib/libunwind/src/x86_64/Lis_signal_frame.c b/contrib/libunwind/src/arm/Los-freebsd.c similarity index 78% rename from contrib/libunwind/src/x86_64/Lis_signal_frame.c rename to contrib/libunwind/src/arm/Los-freebsd.c index b9a7c4f51ad..a75a205df19 100644 --- a/contrib/libunwind/src/x86_64/Lis_signal_frame.c +++ b/contrib/libunwind/src/arm/Los-freebsd.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" +#include "Gos-freebsd.c" #endif diff --git a/contrib/libunwind/src/dwarf/Lstep.c b/contrib/libunwind/src/arm/Los-linux.c similarity index 82% rename from contrib/libunwind/src/dwarf/Lstep.c rename to contrib/libunwind/src/arm/Los-linux.c index c1ac3c7547f..3cc18aabcc3 100644 --- a/contrib/libunwind/src/dwarf/Lstep.c +++ b/contrib/libunwind/src/arm/Los-linux.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" +#include "Gos-linux.c" #endif diff --git a/contrib/libunwind/src/ppc/Lcreate_addr_space.c b/contrib/libunwind/src/arm/Los-other.c similarity index 77% rename from contrib/libunwind/src/ppc/Lcreate_addr_space.c rename to contrib/libunwind/src/arm/Los-other.c index 0f2dc6be901..a75a205df19 100644 --- a/contrib/libunwind/src/ppc/Lcreate_addr_space.c +++ b/contrib/libunwind/src/arm/Los-other.c @@ -1,5 +1,5 @@ #define UNW_LOCAL_ONLY #include #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" +#include "Gos-freebsd.c" #endif diff --git a/contrib/libunwind/src/arm/getcontext.S b/contrib/libunwind/src/arm/getcontext.S index c52992bfb92..7e18784477d 100644 --- a/contrib/libunwind/src/arm/getcontext.S +++ b/contrib/libunwind/src/arm/getcontext.S @@ -35,8 +35,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ _Uarm_getcontext: stmfd sp!, {r0, r1} @ store r0 +#if defined(__linux__) str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF] add r0, r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF +#elif defined(__FreeBSD__) + str r0, [r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF] + add r0, r0, #FREEBSD_UC_MCONTEXT_OFF + FREEBSD_MC_R0_OFF +#else +#error Fix me +#endif @ store r1 to r12 stmib r0, {r1-r12} @ reconstruct r13 at call site, then store @@ -50,7 +57,7 @@ _Uarm_getcontext: str r1, [r0, #15 * 4] ldmfd sp!, {r0, r1} bx lr -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) /* We do not need executable stack. */ .section .note.GNU-stack,"",%progbits #endif diff --git a/contrib/libunwind/src/arm/offsets.h b/contrib/libunwind/src/arm/offsets.h index a63847be417..621701106c4 100644 --- a/contrib/libunwind/src/arm/offsets.h +++ b/contrib/libunwind/src/arm/offsets.h @@ -34,3 +34,9 @@ #define LINUX_SC_PC_OFF 0x48 #define LINUX_SC_CPSR_OFF 0x4C #define LINUX_SC_FAULTADDR_OFF 0x50 + +/* FreeBSD-specific definitions: */ + +#define FREEBSD_SC_UCONTEXT_OFF 0x40 +#define FREEBSD_UC_MCONTEXT_OFF 0x10 +#define FREEBSD_MC_R0_OFF 0 diff --git a/contrib/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/contrib/libunwind/src/coredump/_UCD_access_reg_freebsd.c index 585b7e298b6..0e3a83bdc6c 100644 --- a/contrib/libunwind/src/coredump/_UCD_access_reg_freebsd.c +++ b/contrib/libunwind/src/coredump/_UCD_access_reg_freebsd.c @@ -76,7 +76,7 @@ _UCD_access_reg (unw_addr_space_t as, default: Debug(0, "bad regnum:%d\n", regnum); return -UNW_EINVAL; - }; + } #elif defined(UNW_TARGET_X86_64) switch (regnum) { case UNW_X86_64_RAX: @@ -109,7 +109,26 @@ _UCD_access_reg (unw_addr_space_t as, default: Debug(0, "bad regnum:%d\n", regnum); return -UNW_EINVAL; - }; + } +#elif defined(UNW_TARGET_ARM) + if (regnum >= UNW_ARM_R0 && regnum <= UNW_ARM_R12) { + *valp = ui->prstatus->pr_reg.r[regnum]; + } else { + switch (regnum) { + case UNW_ARM_R13: + *valp = ui->prstatus->pr_reg.r_sp; + break; + case UNW_ARM_R14: + *valp = ui->prstatus->pr_reg.r_lr; + break; + case UNW_ARM_R15: + *valp = ui->prstatus->pr_reg.r_pc; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } + } #else #error Port me #endif diff --git a/contrib/libunwind/src/coredump/_UCD_destroy.c b/contrib/libunwind/src/coredump/_UCD_destroy.c index 5aff989ccc1..ddc36ec8986 100644 --- a/contrib/libunwind/src/coredump/_UCD_destroy.c +++ b/contrib/libunwind/src/coredump/_UCD_destroy.c @@ -44,7 +44,9 @@ _UCD_destroy (struct UCD_info *ui) close(phdr->backing_fd); } + free(ui->phdrs); free(ui->note_phdr); + free(ui->threads); free(ui); } diff --git a/contrib/libunwind/src/coredump/libunwind-coredump.pc b/contrib/libunwind/src/coredump/libunwind-coredump.pc deleted file mode 100644 index 6d6e81c7042..00000000000 --- a/contrib/libunwind/src/coredump/libunwind-coredump.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libunwind-coredump -Description: libunwind coredump library -Version: 1.2 -Requires: libunwind-generic libunwind -Libs: -L${libdir} -lunwind-coredump -Cflags: -I${includedir} diff --git a/contrib/libunwind/src/dwarf/Gfde.c b/contrib/libunwind/src/dwarf/Gfde.c index 55d8da8422d..49484eee131 100644 --- a/contrib/libunwind/src/dwarf/Gfde.c +++ b/contrib/libunwind/src/dwarf/Gfde.c @@ -32,7 +32,7 @@ is_cie_id (unw_word_t val, int is_debug_frame) 0xffffffffffffffff (for 64-bit ELF). However, .eh_frame uses 0. */ if (is_debug_frame) - return (val == - (uint32_t) 1 || val == - (uint64_t) 1); + return (val == (uint32_t)(-1) || val == (uint64_t)(-1)); else return (val == 0); } diff --git a/contrib/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/contrib/libunwind/src/dwarf/Gfind_proc_info-lsb.c index 3e66bc1a96c..d8cbc3e09bc 100644 --- a/contrib/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ b/contrib/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -199,7 +199,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, name = (char*) dlname; err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space); - + if (!err) { fdesc = malloc (sizeof (struct unw_debug_frame_list)); @@ -210,10 +210,10 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, fdesc->debug_frame_size = bufsize; fdesc->index = NULL; fdesc->next = as->debug_frames; - + as->debug_frames = fdesc; } - + return fdesc; } @@ -235,10 +235,10 @@ debug_frame_tab_append (struct debug_frame_tab *tab, tab->size *= 2; tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); } - + tab->tab[length].fde_offset = fde_offset; tab->tab[length].start_ip_offset = start_ip; - + tab->length = length + 1; } @@ -256,7 +256,7 @@ static int debug_frame_tab_compare (const void *a, const void *b) { const struct table_entry *fa = a, *fb = b; - + if (fa->start_ip_offset > fb->start_ip_offset) return 1; else if (fa->start_ip_offset < fb->start_ip_offset) @@ -522,7 +522,7 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) else if (phdr->p_type == PT_DYNAMIC) p_dynamic = phdr; } - + if (!p_text) return 0; @@ -537,14 +537,14 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) eh_frame = dwarf_find_eh_frame_section (info); if (eh_frame) { - unsigned char *p = (unsigned char *) &synth_eh_frame_hdr; Debug (1, "using synthetic .eh_frame_hdr section for %s\n", info->dlpi_name); - /* synth_eh_frame_hdr.version */ p[0] = DW_EH_VERSION; - /* synth_eh_frame_hdr.eh_frame_ptr_enc */ p[1] = DW_EH_PE_absptr | ((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); - /* synth_eh_frame_hdr.fde_count_enc */ p[2] = DW_EH_PE_omit; - /* synth_eh_frame_hdr.table_enc */ p[3] = DW_EH_PE_omit; - *(Elf_W (Addr) *)(&p[4]) = eh_frame; + synth_eh_frame_hdr.version = DW_EH_VERSION; + synth_eh_frame_hdr.eh_frame_ptr_enc = DW_EH_PE_absptr | + ((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); + synth_eh_frame_hdr.fde_count_enc = DW_EH_PE_omit; + synth_eh_frame_hdr.table_enc = DW_EH_PE_omit; + synth_eh_frame_hdr.eh_frame = eh_frame; hdr = &synth_eh_frame_hdr; } } @@ -581,7 +581,7 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) } a = unw_get_accessors (unw_local_addr_space); - addr = (unw_word_t) (uintptr_t) (hdr + 1); + addr = (unw_word_t) (uintptr_t) (&hdr->eh_frame); /* (Optionally) read eh_frame_ptr: */ if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, @@ -618,12 +618,13 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) /* XXX we know how to build a local binary search table for .debug_frame, so we could do that here too. */ - cb_data->single_fde = 1; found = linear_search (unw_local_addr_space, ip, eh_frame_start, eh_frame_end, fde_count, pi, need_unwind_info, NULL); if (found != 1) found = 0; + else + cb_data->single_fde = 1; } else { diff --git a/contrib/libunwind/src/dwarf/Gfind_unwind_table.c b/contrib/libunwind/src/dwarf/Gfind_unwind_table.c index 215948e09f3..c171eeca9a9 100644 --- a/contrib/libunwind/src/dwarf/Gfind_unwind_table.c +++ b/contrib/libunwind/src/dwarf/Gfind_unwind_table.c @@ -139,7 +139,7 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, } a = unw_get_accessors (unw_local_addr_space); - addr = to_unw_word (hdr + 1); + addr = to_unw_word (&hdr->eh_frame); /* Fill in a dummy proc_info structure. We just need to fill in enough to ensure that dwarf_read_encoded_pointer() can do it's diff --git a/contrib/libunwind/src/dwarf/Gparser.c b/contrib/libunwind/src/dwarf/Gparser.c index efbb5e07429..9d405e76696 100644 --- a/contrib/libunwind/src/dwarf/Gparser.c +++ b/contrib/libunwind/src/dwarf/Gparser.c @@ -278,7 +278,7 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, ret = -UNW_ENOMEM; break; } - memcpy (&(*rs_stack)->state, &sr->rs_current, sizeof (sr->rs_current)) + memcpy (&(*rs_stack)->state, &sr->rs_current, sizeof (sr->rs_current)); Debug (15, "CFA_remember_state\n"); break; @@ -289,8 +289,10 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, ret = -UNW_EINVAL; break; } - memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof (sr->rs_current)); - pop_rstate_stack(rs_stack); + if (*ip < end_ip) { + memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof (sr->rs_current)); + pop_rstate_stack(rs_stack); + } Debug (15, "CFA_restore_state\n"); break; @@ -606,7 +608,17 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) if (caching == UNW_CACHE_NONE) return NULL; +#if defined(HAVE___THREAD) && HAVE___THREAD + if (likely (caching == UNW_CACHE_PER_THREAD)) + { + static __thread struct dwarf_rs_cache tls_cache __attribute__((tls_model("initial-exec"))); + Debug (16, "using TLS cache\n"); + cache = &tls_cache; + } + else +#else if (likely (caching == UNW_CACHE_GLOBAL)) +#endif { Debug (16, "acquiring lock\n"); lock_acquire (&cache->lock, *saved_maskp); @@ -615,6 +627,8 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) || !cache->hash) { + /* cache_size is only set in the global_cache, copy it over before flushing */ + cache->log_size = as->global_cache.log_size; if (dwarf_flush_rs_cache (cache) < 0) return NULL; cache->generation = as->cache_generation; @@ -679,7 +693,7 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) unsigned short head; head = cache->rr_head; - cache->rr_head = (head + 1) & (cache->log_size - 1); + cache->rr_head = (head + 1) & (DWARF_UNW_CACHE_SIZE(cache->log_size) - 1); /* remove the old rs from the hash table (if it's there): */ if (cache->links[head].ip) @@ -885,7 +899,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) int ret = 0; intrmask_t saved_mask; - if ((cache = get_rs_cache(c->as, &saved_mask)) && + if ((cache = get_rs_cache(c->as, &saved_mask)) && (rs = rs_lookup(cache, c))) { /* update hint; no locking needed: single-word writes are atomic */ @@ -951,7 +965,7 @@ dwarf_make_proc_info (struct dwarf_cursor *c) needed for unw_resume */ dwarf_state_record_t sr; int ret; - + /* Lookup it up the slow way... */ ret = fetch_proc_info (c, c->ip, 0); if (ret >= 0) @@ -1018,11 +1032,11 @@ dwarf_reg_states_iterate(struct dwarf_cursor *c, case UNW_INFO_FORMAT_REMOTE_TABLE: ret = dwarf_reg_states_table_iterate(c, cb, token); break; - + case UNW_INFO_FORMAT_DYNAMIC: ret = dwarf_reg_states_dynamic_iterate (c, cb, token); break; - + default: Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); ret = -UNW_EINVAL; diff --git a/contrib/libunwind/src/elfxx.c b/contrib/libunwind/src/elfxx.c index 685cf2f534c..48a08cdc383 100644 --- a/contrib/libunwind/src/elfxx.c +++ b/contrib/libunwind/src/elfxx.c @@ -386,6 +386,8 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) { int ret; Elf_W (Shdr) *shdr; + Elf_W (Ehdr) *prev_image = ei->image; + off_t prev_size = ei->size; if (!ei->image) { @@ -420,7 +422,6 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) if (memchr (linkbuf, 0, shdr->sh_size) == NULL) return 0; - munmap (ei->image, ei->size); ei->image = NULL; Debug(1, "Found debuglink section, following %s\n", linkbuf); @@ -456,6 +457,19 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local) ret = elf_w (load_debuglink) (newname, ei, -1); } + if (ret == -1) + { + /* No debuglink file found even though .gnu_debuglink existed */ + ei->image = prev_image; + ei->size = prev_size; + + return 0; + } + else + { + munmap (prev_image, prev_size); + } + return ret; } } diff --git a/contrib/libunwind/src/hppa/Ginit.c b/contrib/libunwind/src/hppa/Ginit.c index 89ad51caca6..28779c39ba5 100644 --- a/contrib/libunwind/src/hppa/Ginit.c +++ b/contrib/libunwind/src/hppa/Ginit.c @@ -179,7 +179,7 @@ HIDDEN void hppa_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/hppa/Ginit_local.c b/contrib/libunwind/src/hppa/Ginit_local.c index 94583d9da75..5c59f48f880 100644 --- a/contrib/libunwind/src/hppa/Ginit_local.c +++ b/contrib/libunwind/src/hppa/Ginit_local.c @@ -58,9 +58,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/ia64/Gapply_reg_state.c b/contrib/libunwind/src/ia64/Gapply_reg_state.c index eec93046f56..a049b57ecae 100644 --- a/contrib/libunwind/src/ia64/Gapply_reg_state.c +++ b/contrib/libunwind/src/ia64/Gapply_reg_state.c @@ -33,5 +33,7 @@ unw_apply_reg_state (unw_cursor_t *cursor, { struct cursor *c = (struct cursor *) cursor; - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); + // Needs dwarf support on ia64 + // return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); + return -UNW_EINVAL; } diff --git a/contrib/libunwind/src/ia64/Ginit.c b/contrib/libunwind/src/ia64/Ginit.c index 7b64f0c1e1e..395450ec9ab 100644 --- a/contrib/libunwind/src/ia64/Ginit.c +++ b/contrib/libunwind/src/ia64/Ginit.c @@ -361,7 +361,7 @@ ia64_local_addr_space_init (void) #elif defined(__hpux) local_addr_space.abi = ABI_HPUX; #endif - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = tdep_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/ia64/Greg_states_iterate.c b/contrib/libunwind/src/ia64/Greg_states_iterate.c index a39837a1781..49908b2cab2 100644 --- a/contrib/libunwind/src/ia64/Greg_states_iterate.c +++ b/contrib/libunwind/src/ia64/Greg_states_iterate.c @@ -33,5 +33,7 @@ unw_reg_states_iterate (unw_cursor_t *cursor, { struct cursor *c = (struct cursor *) cursor; - return dwarf_reg_states_iterate (&c->dwarf, cb, token); + // Needs dwarf support on ia64 + // return dwarf_reg_states_iterate (&c->dwarf, cb, token); + return -UNW_EINVAL; } diff --git a/contrib/libunwind/src/ia64/Gscript.c b/contrib/libunwind/src/ia64/Gscript.c index e96e89e0e83..526aeaf299e 100644 --- a/contrib/libunwind/src/ia64/Gscript.c +++ b/contrib/libunwind/src/ia64/Gscript.c @@ -45,7 +45,7 @@ enum ia64_script_insn_opcode IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */ }; -#ifdef HAVE___THREAD +#if defined(HAVE___THREAD) && HAVE___THREAD static __thread struct ia64_script_cache ia64_per_thread_cache = { #ifdef HAVE_ATOMIC_OPS_H @@ -105,7 +105,7 @@ get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp) if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) return NULL; #else -# ifdef HAVE___THREAD +# if defined(HAVE___THREAD) && HAVE___THREAD if (as->caching_policy == UNW_CACHE_PER_THREAD) cache = &ia64_per_thread_cache; # endif diff --git a/contrib/libunwind/src/libunwind-generic.pc b/contrib/libunwind/src/libunwind-generic.pc deleted file mode 100644 index 714fcd75e90..00000000000 --- a/contrib/libunwind/src/libunwind-generic.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libunwind-generic -Description: libunwind generic library -Version: 1.2 -Requires: libunwind -Libs: -L${libdir} -lunwind-generic -Cflags: -I${includedir} diff --git a/contrib/libunwind/src/mi/Gdyn-extract.c b/contrib/libunwind/src/mi/Gdyn-extract.c index c8ae7a03dcb..5f7682e650d 100644 --- a/contrib/libunwind/src/mi/Gdyn-extract.c +++ b/contrib/libunwind/src/mi/Gdyn-extract.c @@ -49,6 +49,7 @@ unwi_extract_dynamic_proc_info (unw_addr_space_t as, unw_word_t ip, case UNW_INFO_FORMAT_TABLE: case UNW_INFO_FORMAT_REMOTE_TABLE: + case UNW_INFO_FORMAT_ARM_EXIDX: case UNW_INFO_FORMAT_IP_OFFSET: #ifdef tdep_search_unwind_table /* call platform-specific search routine: */ diff --git a/contrib/libunwind/src/mi/Gget_proc_name.c b/contrib/libunwind/src/mi/Gget_proc_name.c index 5376f82cc76..41ed9394da4 100644 --- a/contrib/libunwind/src/mi/Gget_proc_name.c +++ b/contrib/libunwind/src/mi/Gget_proc_name.c @@ -104,11 +104,15 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, int error; ip = tdep_get_ip (c); +#if !defined(__ia64__) if (c->dwarf.use_prev_instr) --ip; +#endif error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, tdep_get_as_arg (c)); +#if !defined(__ia64__) if (c->dwarf.use_prev_instr && offp != NULL && error == 0) *offp += 1; +#endif return error; } diff --git a/contrib/libunwind/src/mi/Gset_cache_size.c b/contrib/libunwind/src/mi/Gset_cache_size.c index 2f06deb3b14..a0d8b5bf13c 100644 --- a/contrib/libunwind/src/mi/Gset_cache_size.c +++ b/contrib/libunwind/src/mi/Gset_cache_size.c @@ -38,6 +38,12 @@ unw_set_cache_size (unw_addr_space_t as, size_t size, int flag) if (flag != 0) return -1; + /* Currently not supported for per-thread cache due to memory leak */ + /* A pthread-key destructor would work, but is not signal safe */ +#if defined(HAVE___THREAD) && HAVE___THREAD + return -1; +#endif + /* Round up to next power of two, slowly but portably */ while(power < size) { @@ -48,10 +54,12 @@ unw_set_cache_size (unw_addr_space_t as, size_t size, int flag) break; } +#if !defined(__ia64__) if (log_size == as->global_cache.log_size) return 0; /* no change */ as->global_cache.log_size = log_size; +#endif /* Ensure caches are empty (and initialized). */ unw_flush_cache (as, 0, 0); diff --git a/contrib/libunwind/src/mi/Gset_caching_policy.c b/contrib/libunwind/src/mi/Gset_caching_policy.c index 45ba1001323..9df9eb82e5c 100644 --- a/contrib/libunwind/src/mi/Gset_caching_policy.c +++ b/contrib/libunwind/src/mi/Gset_caching_policy.c @@ -31,7 +31,7 @@ unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy) if (!tdep_init_done) tdep_init (); -#ifndef HAVE___THREAD +#if !(defined(HAVE___THREAD) && HAVE___THREAD) if (policy == UNW_CACHE_PER_THREAD) policy = UNW_CACHE_GLOBAL; #endif diff --git a/contrib/libunwind/src/mips/Ginit.c b/contrib/libunwind/src/mips/Ginit.c index 83b100fb8ec..077a386c6e8 100644 --- a/contrib/libunwind/src/mips/Ginit.c +++ b/contrib/libunwind/src/mips/Ginit.c @@ -195,7 +195,7 @@ mips_local_addr_space_init (void) # error Unsupported ABI #endif local_addr_space.addr_size = sizeof (void *); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/mips/Ginit_local.c b/contrib/libunwind/src/mips/Ginit_local.c index d24e9ea5150..a29b6d09b7a 100644 --- a/contrib/libunwind/src/mips/Ginit_local.c +++ b/contrib/libunwind/src/mips/Ginit_local.c @@ -57,9 +57,20 @@ unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal(unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/mips/Gregs.c b/contrib/libunwind/src/mips/Gregs.c index 269777673f8..95194022d2b 100644 --- a/contrib/libunwind/src/mips/Gregs.c +++ b/contrib/libunwind/src/mips/Gregs.c @@ -70,6 +70,8 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, break; case UNW_MIPS_PC: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ loc = c->dwarf.loc[reg]; break; diff --git a/contrib/libunwind/src/os-freebsd.c b/contrib/libunwind/src/os-freebsd.c index a96877d9bb3..2e59731e5d2 100644 --- a/contrib/libunwind/src/os-freebsd.c +++ b/contrib/libunwind/src/os-freebsd.c @@ -56,7 +56,7 @@ get_pid_by_tid(int tid) size_t len, len1; char *buf; struct kinfo_proc *kv; - int i, pid; + unsigned i, pid; len = 0; mib[0] = CTL_KERN; diff --git a/contrib/libunwind/src/ppc/Ginit_local.c b/contrib/libunwind/src/ppc/Ginit_local.c index 6c83b3b78a0..a05d4c8aaaa 100644 --- a/contrib/libunwind/src/ppc/Ginit_local.c +++ b/contrib/libunwind/src/ppc/Ginit_local.c @@ -69,9 +69,20 @@ unw_init_local(unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal(unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/ppc32/Gapply_reg_state.c b/contrib/libunwind/src/ppc32/Gapply_reg_state.c new file mode 100644 index 00000000000..eec93046f56 --- /dev/null +++ b/contrib/libunwind/src/ppc32/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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" + +PROTECTED int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/contrib/libunwind/src/ppc32/Ginit.c b/contrib/libunwind/src/ppc32/Ginit.c index f2e6e823679..dc599b9d0e4 100644 --- a/contrib/libunwind/src/ppc32/Ginit.c +++ b/contrib/libunwind/src/ppc32/Ginit.c @@ -201,7 +201,7 @@ HIDDEN void ppc32_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/dwarf/Gstep.c b/contrib/libunwind/src/ppc32/Greg_states_iterate.c similarity index 72% rename from contrib/libunwind/src/dwarf/Gstep.c rename to contrib/libunwind/src/ppc32/Greg_states_iterate.c index 59138e6f783..a39837a1781 100644 --- a/contrib/libunwind/src/dwarf/Gstep.c +++ b/contrib/libunwind/src/ppc32/Greg_states_iterate.c @@ -1,6 +1,8 @@ /* libunwind - a platform-independent unwind library - Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock This file is part of libunwind. @@ -23,19 +25,13 @@ 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 "dwarf.h" -#include "libunwind_i.h" +#include "unwind_i.h" -HIDDEN int -dwarf_step (struct dwarf_cursor *c) +PROTECTED int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) { - int ret; + struct cursor *c = (struct cursor *) cursor; - if ((ret = dwarf_find_save_locs (c)) >= 0) { - c->pi_valid = 0; - ret = (c->ip == 0) ? 0 : 1; - } - - Debug (15, "returning %d\n", ret); - return ret; + return dwarf_reg_states_iterate (&c->dwarf, cb, token); } diff --git a/contrib/libunwind/src/ppc32/Lapply_reg_state.c b/contrib/libunwind/src/ppc32/Lapply_reg_state.c new file mode 100644 index 00000000000..7ebada480e5 --- /dev/null +++ b/contrib/libunwind/src/ppc32/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/contrib/libunwind/src/ppc32/Lreg_states_iterate.c b/contrib/libunwind/src/ppc32/Lreg_states_iterate.c new file mode 100644 index 00000000000..f1eb1e79dcd --- /dev/null +++ b/contrib/libunwind/src/ppc32/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/contrib/libunwind/src/ppc64/Gapply_reg_state.c b/contrib/libunwind/src/ppc64/Gapply_reg_state.c new file mode 100644 index 00000000000..eec93046f56 --- /dev/null +++ b/contrib/libunwind/src/ppc64/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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" + +PROTECTED int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/contrib/libunwind/src/ppc64/Ginit.c b/contrib/libunwind/src/ppc64/Ginit.c index 3211cf4df17..287ecf4923d 100644 --- a/contrib/libunwind/src/ppc64/Ginit.c +++ b/contrib/libunwind/src/ppc64/Ginit.c @@ -214,7 +214,7 @@ ppc64_local_addr_space_init (void) #else local_addr_space.abi = UNW_PPC64_ABI_ELFv1; #endif - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/ppc64/Greg_states_iterate.c b/contrib/libunwind/src/ppc64/Greg_states_iterate.c new file mode 100644 index 00000000000..a39837a1781 --- /dev/null +++ b/contrib/libunwind/src/ppc64/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +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" + +PROTECTED int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/contrib/libunwind/src/ppc64/Lapply_reg_state.c b/contrib/libunwind/src/ppc64/Lapply_reg_state.c new file mode 100644 index 00000000000..7ebada480e5 --- /dev/null +++ b/contrib/libunwind/src/ppc64/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/contrib/libunwind/src/ppc64/Lreg_states_iterate.c b/contrib/libunwind/src/ppc64/Lreg_states_iterate.c new file mode 100644 index 00000000000..f1eb1e79dcd --- /dev/null +++ b/contrib/libunwind/src/ppc64/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/contrib/libunwind/src/ptrace/_UPT_access_fpreg.c b/contrib/libunwind/src/ptrace/_UPT_access_fpreg.c index e90ec47d081..2b92462fa92 100644 --- a/contrib/libunwind/src/ptrace/_UPT_access_fpreg.c +++ b/contrib/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -75,6 +75,18 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, pid_t pid = ui->pid; fpregset_t fpreg; +#if defined(__amd64__) + if (1) /* XXXKIB */ + return -UNW_EBADREG; +#elif defined(__i386__) + if ((unsigned) reg < UNW_X86_ST0 || (unsigned) reg > UNW_X86_ST7) + return -UNW_EBADREG; +#elif defined(__arm__) + if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) + return -UNW_EBADREG; +#else +#error Fix me +#endif if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) return -UNW_EBADREG; @@ -85,6 +97,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t)); #elif defined(__i386__) memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__arm__) + memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); #else #error Fix me #endif @@ -95,6 +109,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t)); #elif defined(__i386__) memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); +#elif defined(__arm__) + memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); #else #error Fix me #endif diff --git a/contrib/libunwind/src/ptrace/_UPT_access_reg.c b/contrib/libunwind/src/ptrace/_UPT_access_reg.c index ae71608b3df..ce25c783b04 100644 --- a/contrib/libunwind/src/ptrace/_UPT_access_reg.c +++ b/contrib/libunwind/src/ptrace/_UPT_access_reg.c @@ -34,7 +34,50 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # include "tdep-ia64/rse.h" #endif -#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE +#if HAVE_DECL_PTRACE_SETREGSET +#include +int +_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, + int write, void *arg) +{ + struct UPT_info *ui = arg; + pid_t pid = ui->pid; + gregset_t regs; + char *r; + struct iovec loc; + +#if UNW_DEBUG + Debug(16, "using getregset: reg: %s [%u], val: %lx, write: %u\n", + unw_regname(reg), (unsigned) reg, (long) val, write); + + if (write) + Debug (16, "%s [%u] <- %lx\n", unw_regname (reg), (unsigned) reg, (long) *val); +#endif + if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset)) + { + errno = EINVAL; + goto badreg; + } + + loc.iov_base = ®s; + loc.iov_len = sizeof(regs); + + r = (char *)®s + _UPT_reg_offset[reg]; + if (ptrace (PTRACE_GETREGSET, pid, NT_PRSTATUS, &loc) == -1) + goto badreg; + if (write) { + memcpy(r, val, sizeof(unw_word_t)); + if (ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &loc) == -1) + goto badreg; + } else + memcpy(val, r, sizeof(unw_word_t)); + return 0; + +badreg: + Debug (1, "bad register %s [%u] (error: %s)\n", unw_regname(reg), reg, strerror (errno)); + return -UNW_EBADREG; +} +#elif HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE int _UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) diff --git a/contrib/libunwind/src/ptrace/_UPT_reg_offset.c b/contrib/libunwind/src/ptrace/_UPT_reg_offset.c index 033594db0aa..c82d1c98872 100644 --- a/contrib/libunwind/src/ptrace/_UPT_reg_offset.c +++ b/contrib/libunwind/src/ptrace/_UPT_reg_offset.c @@ -484,6 +484,7 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = #endif #elif defined(UNW_TARGET_ARM) +#if defined(__linux__) || defined(__FreeBSD__) [UNW_ARM_R0] = 0x00, [UNW_ARM_R1] = 0x04, [UNW_ARM_R2] = 0x08, @@ -500,6 +501,9 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = [UNW_ARM_R13] = 0x34, [UNW_ARM_R14] = 0x38, [UNW_ARM_R15] = 0x3c, +#else +#error Fix me +#endif #elif defined(UNW_TARGET_MIPS) [UNW_MIPS_R0] = 0, [UNW_MIPS_R1] = 1, diff --git a/contrib/libunwind/src/ptrace/libunwind-ptrace.pc b/contrib/libunwind/src/ptrace/libunwind-ptrace.pc deleted file mode 100644 index df77448cf87..00000000000 --- a/contrib/libunwind/src/ptrace/libunwind-ptrace.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libunwind-ptrace -Description: libunwind ptrace library -Version: 1.2 -Requires: libunwind-generic libunwind -Libs: -L${libdir} -lunwind-ptrace -Cflags: -I${includedir} diff --git a/contrib/libunwind/src/setjmp/libunwind-setjmp.pc b/contrib/libunwind/src/setjmp/libunwind-setjmp.pc deleted file mode 100644 index 680251db27a..00000000000 --- a/contrib/libunwind/src/setjmp/libunwind-setjmp.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libunwind-setjmp -Description: libunwind setjmp library -Version: 1.2 -Requires: libunwind -Libs: -L${libdir} -lunwind-setjmp -Cflags: -I${includedir} diff --git a/contrib/libunwind/src/sh/Ginit.c b/contrib/libunwind/src/sh/Ginit.c index b380db1da62..0bfac4907ee 100644 --- a/contrib/libunwind/src/sh/Ginit.c +++ b/contrib/libunwind/src/sh/Ginit.c @@ -171,7 +171,7 @@ HIDDEN void sh_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/sh/Ginit_local.c b/contrib/libunwind/src/sh/Ginit_local.c index 598f708a36f..36d1329b6ff 100644 --- a/contrib/libunwind/src/sh/Ginit_local.c +++ b/contrib/libunwind/src/sh/Ginit_local.c @@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, unw_context_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/sh/Gregs.c b/contrib/libunwind/src/sh/Gregs.c index fb4ca740037..7d8e8e93da0 100644 --- a/contrib/libunwind/src/sh/Gregs.c +++ b/contrib/libunwind/src/sh/Gregs.c @@ -33,6 +33,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, switch (reg) { + case UNW_SH_PC: + if (write) + c->dwarf.ip = *valp; /* update the IP cache */ case UNW_SH_R0: case UNW_SH_R1: case UNW_SH_R2: @@ -48,7 +51,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_SH_R12: case UNW_SH_R13: case UNW_SH_R14: - case UNW_SH_PC: case UNW_SH_PR: loc = c->dwarf.loc[reg]; break; diff --git a/contrib/libunwind/src/tilegx/Ginit.c b/contrib/libunwind/src/tilegx/Ginit.c index df3ffcaa643..a0bb69d7719 100644 --- a/contrib/libunwind/src/tilegx/Ginit.c +++ b/contrib/libunwind/src/tilegx/Ginit.c @@ -152,7 +152,7 @@ tilegx_local_addr_space_init (void) local_addr_space.abi = UNW_TILEGX_ABI_N64; local_addr_space.addr_size = sizeof (void *); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/tilegx/Ginit_local.c b/contrib/libunwind/src/tilegx/Ginit_local.c index 800dc00fb8c..6aa679f05df 100644 --- a/contrib/libunwind/src/tilegx/Ginit_local.c +++ b/contrib/libunwind/src/tilegx/Ginit_local.c @@ -61,9 +61,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/tilegx/Gregs.c b/contrib/libunwind/src/tilegx/Gregs.c index 53e7bf4ce80..565c6f4432a 100644 --- a/contrib/libunwind/src/tilegx/Gregs.c +++ b/contrib/libunwind/src/tilegx/Gregs.c @@ -52,7 +52,17 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, } if (write) - return dwarf_put (&c->dwarf, loc, *valp); + { + if (ci->dwarf.use_prev_instr == 0) { + if (reg == UNW_TILEGX_PC) + c->dwarf.ip = *valp; /* update the IP cache */ + } + else { + if (reg == UNW_TILEGX_R55) + c->dwarf.ip = *valp; /* update the IP cache */ + } + return dwarf_put (&c->dwarf, loc, *valp); + } else return dwarf_get (&c->dwarf, loc, valp); } diff --git a/contrib/libunwind/src/unwind/libunwind.pc b/contrib/libunwind/src/unwind/libunwind.pc deleted file mode 100644 index 987d55c22b3..00000000000 --- a/contrib/libunwind/src/unwind/libunwind.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libunwind -Description: libunwind base library -Version: 1.2 -Libs: -L${libdir} -lunwind -Libs.private: -llzma -Cflags: -I${includedir} diff --git a/contrib/libunwind/src/x86/Ginit.c b/contrib/libunwind/src/x86/Ginit.c index b05a08edba3..876990fe1cd 100644 --- a/contrib/libunwind/src/x86/Ginit.c +++ b/contrib/libunwind/src/x86/Ginit.c @@ -228,7 +228,7 @@ HIDDEN void x86_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/x86/Ginit_local.c b/contrib/libunwind/src/x86/Ginit_local.c index 025c84cb9d2..88c52de3848 100644 --- a/contrib/libunwind/src/x86/Ginit_local.c +++ b/contrib/libunwind/src/x86/Ginit_local.c @@ -60,9 +60,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/x86/Gos-linux.c b/contrib/libunwind/src/x86/Gos-linux.c index 17aebc2974a..37a22b97b2f 100644 --- a/contrib/libunwind/src/x86/Gos-linux.c +++ b/contrib/libunwind/src/x86/Gos-linux.c @@ -52,7 +52,7 @@ unw_is_signal_frame (unw_cursor_t *cursor) __restore_rt: 0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax 0xcd 0x80 int 0x80 - 0x00 + 0x00 if SA_SIGINFO is specified. */ @@ -296,7 +296,7 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc); - sigreturn (sc); + x86_sigreturn (sc); } else { @@ -305,4 +305,25 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) } return -UNW_EINVAL; } + +/* sigreturn() is a no-op on x86 glibc. */ +HIDDEN void +x86_sigreturn (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + mcontext_t *sc_mcontext = &((struct ucontext*)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); + __asm__ __volatile__ ("mov %0, %%esp;" + "mov %1, %%eax;" + "syscall" + :: "r"(sc), "i"(SYS_rt_sigreturn) + : "memory"); + abort(); +} #endif diff --git a/contrib/libunwind/src/x86/unwind_i.h b/contrib/libunwind/src/x86/unwind_i.h index cd52824226a..d2aed609e57 100644 --- a/contrib/libunwind/src/x86/unwind_i.h +++ b/contrib/libunwind/src/x86/unwind_i.h @@ -52,6 +52,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define x86_scratch_loc UNW_OBJ(scratch_loc) #define x86_get_scratch_loc UNW_OBJ(get_scratch_loc) #define x86_r_uc_addr UNW_OBJ(r_uc_addr) +#define x86_sigreturn UNW_OBJ(sigreturn) extern void x86_local_addr_space_init (void); extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, @@ -60,4 +61,6 @@ extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg); extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg); extern void *x86_r_uc_addr (ucontext_t *uc, int reg); +extern void x86_sigreturn (unw_cursor_t *cursor); + #endif /* unwind_i_h */ diff --git a/contrib/libunwind/src/x86_64/Ginit.c b/contrib/libunwind/src/x86_64/Ginit.c index 782757622e5..c66d59ba685 100644 --- a/contrib/libunwind/src/x86_64/Ginit.c +++ b/contrib/libunwind/src/x86_64/Ginit.c @@ -72,10 +72,57 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, #define PAGE_SIZE 4096 #define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) +static int mem_validate_pipe[2] = {-1, -1}; + +static inline void +open_pipe (void) +{ + /* ignore errors for closing invalid fd's */ + close (mem_validate_pipe[0]); + close (mem_validate_pipe[1]); + + pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); +} + +ALWAYS_INLINE +static int +write_validate (void *addr) +{ + int ret = -1; + ssize_t bytes = 0; + + do + { + char buf; + bytes = read (mem_validate_pipe[0], &buf, 1); + } + while ( errno == EINTR ); + + int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); + if (!valid_read) + { + // re-open closed pipe + open_pipe (); + } + + do + { + ret = write (mem_validate_pipe[1], addr, 1); + } + while ( errno == EINTR ); + + return ret; +} + static int (*mem_validate_func) (void *addr, size_t len); static int msync_validate (void *addr, size_t len) { - return msync (addr, len, MS_ASYNC); + if (msync (addr, len, MS_ASYNC) != 0) + { + return -1; + } + + return write_validate (addr); } #ifdef HAVE_MINCORE @@ -96,7 +143,7 @@ static int mincore_validate (void *addr, size_t len) if (!(mvec[i] & 1)) return -1; } - return 0; + return write_validate (addr); } #endif @@ -107,6 +154,8 @@ static int mincore_validate (void *addr, size_t len) HIDDEN void tdep_init_mem_validate (void) { + open_pipe (); + #ifdef HAVE_MINCORE unsigned char present = 1; unw_word_t addr = PAGE_START((unw_word_t)&present); @@ -273,7 +322,7 @@ HIDDEN void x86_64_local_addr_space_init (void) { memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY; local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; diff --git a/contrib/libunwind/src/x86_64/Ginit_local.c b/contrib/libunwind/src/x86_64/Ginit_local.c index 2d2b1754b7a..7696f11caf9 100644 --- a/contrib/libunwind/src/x86_64/Ginit_local.c +++ b/contrib/libunwind/src/x86_64/Ginit_local.c @@ -62,9 +62,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) } PROTECTED int -unw_init_local_signal (unw_cursor_t *cursor, ucontext_t *uc) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { - return unw_init_local_common(cursor, uc, 0); + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } } #endif /* !UNW_REMOTE_ONLY */ diff --git a/contrib/libunwind/src/x86_64/Gos-linux.c b/contrib/libunwind/src/x86_64/Gos-linux.c index a4f80cad360..0a3c21221fb 100644 --- a/contrib/libunwind/src/x86_64/Gos-linux.c +++ b/contrib/libunwind/src/x86_64/Gos-linux.c @@ -138,7 +138,7 @@ 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 = &((struct ucontext*)sc)->uc_mcontext; + 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)); diff --git a/contrib/libunwind/src/x86_64/init.h b/contrib/libunwind/src/x86_64/init.h index 3ceab791474..a7a996f1272 100644 --- a/contrib/libunwind/src/x86_64/init.h +++ b/contrib/libunwind/src/x86_64/init.h @@ -83,6 +83,7 @@ common_init (struct cursor *c, unsigned use_prev_instr) c->dwarf.pi_is_dynamic = 0; c->dwarf.hint = 0; c->dwarf.prev_rs = 0; + c->dwarf.eh_valid_mask = 0; return 0; } diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index 375f8dfa9cb..c25f8036f8b 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -192,7 +192,7 @@ size_t backtraceLibUnwind(void ** out_frames, size_t max_frames, ucontext_t & co unw_cursor_t cursor; - if (unw_init_local_signal(&cursor, &context) < 0) + if (unw_init_local2(&cursor, &context, UNW_INIT_SIGNAL_FRAME) < 0) return 0; size_t i = 0;