mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
contrib: Fixed unwind build under GCC 7. [#METR-21516]
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81712 .
This commit is contained in:
parent
8f3a244d26
commit
07c964ef3b
@ -45,7 +45,6 @@ src/dwarf/Lfde.c
|
|||||||
src/dwarf/Lfind_proc_info-lsb.c
|
src/dwarf/Lfind_proc_info-lsb.c
|
||||||
src/dwarf/Lparser.c
|
src/dwarf/Lparser.c
|
||||||
src/dwarf/Lpe.c
|
src/dwarf/Lpe.c
|
||||||
src/dwarf/Lstep.c
|
|
||||||
src/dwarf/global.c
|
src/dwarf/global.c
|
||||||
src/elf64.c
|
src/elf64.c
|
||||||
|
|
||||||
@ -53,9 +52,17 @@ src/os-linux.c
|
|||||||
src/x86_64/Los-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_definitions (unwind PRIVATE HAVE_CONFIG_H=1 _XOPEN_SOURCE _GNU_SOURCE)
|
||||||
target_compile_options (unwind PRIVATE -Wno-visibility -Wno-header-guard)
|
target_compile_options (unwind PRIVATE -Wno-visibility -Wno-header-guard)
|
||||||
|
|
||||||
target_include_directories (unwind PUBLIC include)
|
target_include_directories (unwind PUBLIC include)
|
||||||
target_include_directories (unwind PRIVATE include/tdep)
|
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)
|
target_include_directories (unwind PRIVATE src)
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
Source: https://github.com/libunwind/libunwind
|
Source: https://github.com/libunwind/libunwind
|
||||||
Revision: 2934cf40529e0261801a4142fabae449a65effd0
|
Revision: 60ddc67196eafb5cafd0d89e461c9d700a697d6d
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
/* #undef HAVE_ASM_PTRACE_OFFSETS_H */
|
/* #undef HAVE_ASM_PTRACE_OFFSETS_H */
|
||||||
|
|
||||||
/* Define to 1 if you have the <atomic_ops.h> header file. */
|
/* Define to 1 if you have the <atomic_ops.h> header file. */
|
||||||
/* #undef HAVE_ATOMIC_OPS_H */
|
#cmakedefine HAVE_ATOMIC_OPS_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||||
#define HAVE_BYTESWAP_H 1
|
#define HAVE_BYTESWAP_H 1
|
||||||
@ -34,6 +34,10 @@
|
|||||||
you don't. */
|
you don't. */
|
||||||
#define HAVE_DECL_PTRACE_POKEUSER 1
|
#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
|
/* Define to 1 if you have the declaration of `PTRACE_SINGLESTEP', and to 0 if
|
||||||
you don't. */
|
you don't. */
|
||||||
#define HAVE_DECL_PTRACE_SINGLESTEP 1
|
#define HAVE_DECL_PTRACE_SINGLESTEP 1
|
||||||
@ -183,9 +187,10 @@
|
|||||||
#define HAVE__BUILTIN___CLEAR_CACHE 1
|
#define HAVE__BUILTIN___CLEAR_CACHE 1
|
||||||
|
|
||||||
/* Define to 1 if __thread keyword is supported by the C compiler. */
|
/* 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/"
|
#define LT_OBJDIR ".libs/"
|
||||||
|
|
||||||
/* Name of package */
|
/* Name of package */
|
@ -86,6 +86,12 @@ typedef enum
|
|||||||
}
|
}
|
||||||
unw_caching_policy_t;
|
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;
|
typedef int unw_regnum_t;
|
||||||
|
|
||||||
/* The unwind cursor starts at the youngest (most deeply nested) frame
|
/* 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_destroy_addr_space UNW_OBJ(destroy_addr_space)
|
||||||
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
|
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
|
||||||
#define unw_init_local UNW_OBJ(init_local)
|
#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_init_remote UNW_OBJ(init_remote)
|
||||||
#define unw_step UNW_OBJ(step)
|
#define unw_step UNW_OBJ(step)
|
||||||
#define unw_resume UNW_OBJ(resume)
|
#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 const char *unw_regname (unw_regnum_t);
|
||||||
|
|
||||||
extern int unw_init_local (unw_cursor_t *, unw_context_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_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
|
||||||
extern int unw_step (unw_cursor_t *);
|
extern int unw_step (unw_cursor_t *);
|
||||||
extern int unw_resume (unw_cursor_t *);
|
extern int unw_resume (unw_cursor_t *);
|
@ -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 <asm/ptrace_offsets.h> header file. */
|
|
||||||
#undef HAVE_ASM_PTRACE_OFFSETS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <atomic_ops.h> header file. */
|
|
||||||
#undef HAVE_ATOMIC_OPS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <byteswap.h> 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 <dlfcn.h> 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 <elf.h> header file. */
|
|
||||||
#undef HAVE_ELF_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <endian.h> header file. */
|
|
||||||
#undef HAVE_ENDIAN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <execinfo.h> 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 <ia64intrin.h> header file. */
|
|
||||||
#undef HAVE_IA64INTRIN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> 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 <link.h> header file. */
|
|
||||||
#undef HAVE_LINK_H
|
|
||||||
|
|
||||||
/* Define if you have liblzma */
|
|
||||||
#undef HAVE_LZMA
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> 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 <signal.h> header file. */
|
|
||||||
#undef HAVE_SIGNAL_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#undef HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#undef HAVE_STDLIB_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#undef HAVE_STRINGS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> 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 <sys/elf.h> header file. */
|
|
||||||
#undef HAVE_SYS_ELF_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
|
||||||
#undef HAVE_SYS_ENDIAN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/link.h> header file. */
|
|
||||||
#undef HAVE_SYS_LINK_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/procfs.h> header file. */
|
|
||||||
#undef HAVE_SYS_PROCFS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/ptrace.h> header file. */
|
|
||||||
#undef HAVE_SYS_PTRACE_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#undef HAVE_SYS_STAT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#undef HAVE_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/uc_access.h> 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 <unistd.h> 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 <sys/types.h> does not define. */
|
|
||||||
#undef size_t
|
|
@ -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 */
|
#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 version;
|
||||||
unsigned char eh_frame_ptr_enc;
|
unsigned char eh_frame_ptr_enc;
|
||||||
unsigned char fde_count_enc;
|
unsigned char fde_count_enc;
|
||||||
unsigned char table_enc;
|
unsigned char table_enc;
|
||||||
|
Elf_W (Addr) eh_frame;
|
||||||
/* The rest of the header is variable-length and consists of the
|
/* The rest of the header is variable-length and consists of the
|
||||||
following members:
|
following members:
|
||||||
|
|
||||||
encoded_t eh_frame_ptr;
|
|
||||||
encoded_t fde_count;
|
encoded_t fde_count;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -37,13 +37,6 @@ struct elf_dyn_info;
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#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
|
#ifndef UNW_REMOTE_ONLY
|
||||||
#if defined(HAVE_LINK_H)
|
#if defined(HAVE_LINK_H)
|
||||||
#include <link.h>
|
#include <link.h>
|
||||||
|
@ -265,7 +265,7 @@ unw_tdep_context_t;
|
|||||||
#ifndef __thumb__
|
#ifndef __thumb__
|
||||||
#define unw_tdep_getcontext(uc) (({ \
|
#define unw_tdep_getcontext(uc) (({ \
|
||||||
unw_tdep_context_t *unw_ctx = (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__ ( \
|
__asm__ __volatile__ ( \
|
||||||
"stmia %[base], {r0-r15}" \
|
"stmia %[base], {r0-r15}" \
|
||||||
: : [base] "r" (unw_base) : "memory"); \
|
: : [base] "r" (unw_base) : "memory"); \
|
||||||
@ -273,11 +273,12 @@ unw_tdep_context_t;
|
|||||||
#else /* __thumb__ */
|
#else /* __thumb__ */
|
||||||
#define unw_tdep_getcontext(uc) (({ \
|
#define unw_tdep_getcontext(uc) (({ \
|
||||||
unw_tdep_context_t *unw_ctx = (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__ ( \
|
__asm__ __volatile__ ( \
|
||||||
".align 2\nbx pc\nnop\n.code 32\n" \
|
".align 2\nbx pc\nnop\n.code 32\n" \
|
||||||
"stmia %[base], {r0-r15}\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"); \
|
: [base] "+r" (unw_base) : : "memory", "cc"); \
|
||||||
}), 0)
|
}), 0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,6 +86,12 @@ typedef enum
|
|||||||
}
|
}
|
||||||
unw_caching_policy_t;
|
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;
|
typedef int unw_regnum_t;
|
||||||
|
|
||||||
/* The unwind cursor starts at the youngest (most deeply nested) frame
|
/* 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_destroy_addr_space UNW_OBJ(destroy_addr_space)
|
||||||
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
|
#define unw_get_accessors UNW_ARCH_OBJ(get_accessors)
|
||||||
#define unw_init_local UNW_OBJ(init_local)
|
#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_init_remote UNW_OBJ(init_remote)
|
||||||
#define unw_step UNW_OBJ(step)
|
#define unw_step UNW_OBJ(step)
|
||||||
#define unw_resume UNW_OBJ(resume)
|
#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 const char *unw_regname (unw_regnum_t);
|
||||||
|
|
||||||
extern int unw_init_local (unw_cursor_t *, unw_context_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_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
|
||||||
extern int unw_step (unw_cursor_t *);
|
extern int unw_step (unw_cursor_t *);
|
||||||
extern int unw_resume (unw_cursor_t *);
|
extern int unw_resume (unw_cursor_t *);
|
||||||
|
@ -37,11 +37,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
|
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
|
||||||
#ifdef HAVE___THREAD
|
#if defined(HAVE___THREAD) && HAVE___THREAD
|
||||||
/* For now, turn off per-thread caching. It uses up too much TLS
|
#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_PER_THREAD
|
||||||
memory per thread even when the thread never uses libunwind at
|
#else
|
||||||
all. */
|
#define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_GLOBAL
|
||||||
# undef HAVE___THREAD
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Platform-independent libunwind-internal declarations. */
|
/* Platform-independent libunwind-internal declarations. */
|
||||||
@ -69,6 +68,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
# include <endian.h>
|
# include <endian.h>
|
||||||
#elif defined(HAVE_SYS_ENDIAN_H)
|
#elif defined(HAVE_SYS_ENDIAN_H)
|
||||||
# include <sys/endian.h>
|
# include <sys/endian.h>
|
||||||
|
# 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
|
#else
|
||||||
# define __LITTLE_ENDIAN 1234
|
# define __LITTLE_ENDIAN 1234
|
||||||
# define __BIG_ENDIAN 4321
|
# define __BIG_ENDIAN 4321
|
||||||
|
@ -1 +0,0 @@
|
|||||||
timestamp for include/config.h
|
|
@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
|
|
||||||
typedef enum
|
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_STANDARD = -2, /* regular r7, sp +/- offset */
|
||||||
UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */
|
UNW_ARM_FRAME_SIGRETURN = -1, /* special sigreturn frame */
|
||||||
UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */
|
UNW_ARM_FRAME_OTHER = 0, /* not cacheable (special or unrecognised) */
|
||||||
@ -48,7 +49,7 @@ unw_tdep_frame_type_t;
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t virtual_address;
|
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 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_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 */
|
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_SIGFRAME, /* non-RT signal frame, kernel >=2.6.18 */
|
||||||
ARM_SCF_LINUX_RT_SIGFRAME, /* 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_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;
|
sigcontext_format;
|
||||||
unw_word_t sigcontext_addr;
|
unw_word_t sigcontext_addr;
|
||||||
|
@ -36,10 +36,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
#include "mempool.h"
|
#include "mempool.h"
|
||||||
#include "dwarf.h"
|
#include "dwarf.h"
|
||||||
|
|
||||||
#ifdef HAVE___THREAD
|
|
||||||
# undef HAVE___THREAD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* no Tilegx-specific fast trace */
|
/* no Tilegx-specific fast trace */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#if defined __aarch64__
|
#if defined __aarch64__
|
||||||
# include "tdep-aarch64/jmpbuf.h"
|
# include "tdep-aarch64/jmpbuf.h"
|
||||||
#if defined __arm__
|
#elif defined __arm__
|
||||||
# include "tdep-arm/jmpbuf.h"
|
# include "tdep-arm/jmpbuf.h"
|
||||||
#elif defined __hppa__
|
#elif defined __hppa__
|
||||||
# include "tdep-hppa/jmpbuf.h"
|
# include "tdep-hppa/jmpbuf.h"
|
||||||
|
749
contrib/libunwind/src/Makefile.am
Normal file
749
contrib/libunwind/src/Makefile.am
Normal file
@ -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.
|
@ -43,8 +43,10 @@ PROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
|
|||||||
static inline void *
|
static inline void *
|
||||||
uc_addr (ucontext_t *uc, int reg)
|
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];
|
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
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ HIDDEN void
|
|||||||
aarch64_local_addr_space_init (void)
|
aarch64_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -55,6 +55,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
|
|||||||
loc = c->dwarf.loc[reg];
|
loc = c->dwarf.loc[reg];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UNW_AARCH64_X30:
|
||||||
|
if (write)
|
||||||
|
c->dwarf.ip = *valp; /* update the IP cache */
|
||||||
case UNW_AARCH64_X4:
|
case UNW_AARCH64_X4:
|
||||||
case UNW_AARCH64_X5:
|
case UNW_AARCH64_X5:
|
||||||
case UNW_AARCH64_X6:
|
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_X27:
|
||||||
case UNW_AARCH64_X28:
|
case UNW_AARCH64_X28:
|
||||||
case UNW_AARCH64_X29:
|
case UNW_AARCH64_X29:
|
||||||
case UNW_AARCH64_X30:
|
|
||||||
case UNW_AARCH64_PC:
|
case UNW_AARCH64_PC:
|
||||||
case UNW_AARCH64_PSTATE:
|
case UNW_AARCH64_PSTATE:
|
||||||
loc = c->dwarf.loc[reg];
|
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,
|
tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp,
|
||||||
int write)
|
int write)
|
||||||
{
|
{
|
||||||
Debug (1, "bad register number %u\n", reg);
|
dwarf_loc_t loc = c->dwarf.loc[reg];
|
||||||
return -UNW_EBADREG;
|
if (write)
|
||||||
|
return dwarf_putfp (&c->dwarf, loc, *valp);
|
||||||
|
else
|
||||||
|
return dwarf_getfp (&c->dwarf, loc, valp);
|
||||||
}
|
}
|
||||||
|
@ -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
|
/* Since there are no signals involved here we restore EH and non scratch
|
||||||
registers only. */
|
registers only. */
|
||||||
unsigned long regs[15];
|
unsigned long regs[24];
|
||||||
regs[0] = uc->uc_mcontext.regs[0];
|
regs[0] = uc->uc_mcontext.regs[0];
|
||||||
regs[1] = uc->uc_mcontext.regs[1];
|
regs[1] = uc->uc_mcontext.regs[1];
|
||||||
regs[2] = uc->uc_mcontext.regs[2];
|
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[11] = uc->uc_mcontext.regs[26];
|
||||||
regs[12] = uc->uc_mcontext.regs[27];
|
regs[12] = uc->uc_mcontext.regs[27];
|
||||||
regs[13] = uc->uc_mcontext.regs[28];
|
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;
|
unsigned long sp = uc->uc_mcontext.sp;
|
||||||
|
|
||||||
struct regs_overlay {
|
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 x23, x24, [x4,64]\n"
|
||||||
"ldp x25, x26, [x4,80]\n"
|
"ldp x25, x26, [x4,80]\n"
|
||||||
"ldp x27, x28, [x4,96]\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"
|
"mov sp, x5\n"
|
||||||
"ret \n"
|
"ret \n"
|
||||||
:
|
:
|
||||||
@ -147,7 +160,7 @@ establish_machine_state (struct cursor *c)
|
|||||||
|
|
||||||
Debug (8, "copying out cursor state\n");
|
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);
|
Debug (16, "copying %s %d\n", unw_regname (reg), reg);
|
||||||
if (unw_is_fpreg (reg))
|
if (unw_is_fpreg (reg))
|
||||||
|
@ -27,6 +27,30 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
#include "offsets.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
|
PROTECTED int
|
||||||
unw_handle_signal_frame (unw_cursor_t *cursor)
|
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);
|
dwarf_get (&c->dwarf, c->dwarf.loc[UNW_AARCH64_PC], &c->dwarf.ip);
|
||||||
|
|
||||||
c->dwarf.pi_valid = 0;
|
c->dwarf.pi_valid = 0;
|
||||||
|
c->dwarf.use_prev_instr = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -125,7 +150,40 @@ unw_step (unw_cursor_t *cursor)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (unlikely (ret < 0))
|
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;
|
return (c->dwarf.ip == 0) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
@ -59,4 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved))
|
||||||
|
|
||||||
#endif /* unwind_i_h */
|
#endif /* unwind_i_h */
|
||||||
|
@ -126,6 +126,11 @@ static int
|
|||||||
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
|
access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
|
/* validate address */
|
||||||
|
const struct cursor *c = (const struct cursor *) arg;
|
||||||
|
if (c && validate_mem(addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (write)
|
if (write)
|
||||||
{
|
{
|
||||||
Debug (16, "mem[%x] <- %x\n", addr, *val);
|
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
|
else
|
||||||
{
|
{
|
||||||
/* validate address */
|
|
||||||
const struct cursor *c = (const struct cursor *) arg;
|
|
||||||
if (c && validate_mem(addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
*val = *(unw_word_t *) addr;
|
*val = *(unw_word_t *) addr;
|
||||||
Debug (16, "mem[%x] -> %x\n", addr, *val);
|
Debug (16, "mem[%x] -> %x\n", addr, *val);
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ HIDDEN void
|
|||||||
arm_local_addr_space_init (void)
|
arm_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = arm_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = arm_put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -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 <stdio.h>
|
|
||||||
#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
|
|
||||||
}
|
|
129
contrib/libunwind/src/arm/Gos-freebsd.c
Normal file
129
contrib/libunwind/src/arm/Gos-freebsd.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2008 CodeSourcery
|
||||||
|
Copyright 2011 Linaro Limited
|
||||||
|
Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#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;
|
||||||
|
}
|
182
contrib/libunwind/src/arm/Gos-linux.c
Normal file
182
contrib/libunwind/src/arm/Gos-linux.c
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/* libunwind - a platform-independent unwind library
|
||||||
|
Copyright (C) 2008 CodeSourcery
|
||||||
|
Copyright 2011 Linaro Limited
|
||||||
|
Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#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;
|
||||||
|
}
|
@ -1,8 +1,7 @@
|
|||||||
/* libunwind - a platform-independent unwind library
|
/* libunwind - a platform-independent unwind library
|
||||||
Copyright (C) 2006-2007 IBM
|
Copyright (C) 2008 CodeSourcery
|
||||||
Contributed by
|
Copyright 2011 Linaro Limited
|
||||||
Corey Ashford <cjashfor@us.ibm.com>
|
Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
|
||||||
Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
|
|
||||||
|
|
||||||
This file is part of libunwind.
|
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
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "unwind_i.h"
|
||||||
|
#include "offsets.h"
|
||||||
|
|
||||||
#include <libunwind_i.h>
|
PROTECTED int
|
||||||
|
unw_handle_signal_frame (unw_cursor_t *cursor)
|
||||||
PROTECTED unw_addr_space_t
|
|
||||||
unw_create_addr_space (unw_accessors_t *a, int byte_order)
|
|
||||||
{
|
{
|
||||||
#ifdef UNW_LOCAL_ONLY
|
return -UNW_EUNSPEC;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
PROTECTED int
|
||||||
|
unw_is_signal_frame (unw_cursor_t *cursor)
|
||||||
|
{
|
||||||
|
#if defined(__QNX__)
|
||||||
|
/* Not supported yet */
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
unw_addr_space_t as = malloc (sizeof (*as));
|
printf ("%s: implement me\n", __FUNCTION__);
|
||||||
|
return -UNW_ENOINFO;
|
||||||
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;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -32,6 +32,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
|
|||||||
|
|
||||||
switch (reg)
|
switch (reg)
|
||||||
{
|
{
|
||||||
|
case UNW_ARM_R15:
|
||||||
|
if (write)
|
||||||
|
c->dwarf.ip = *valp; /* update the IP cache */
|
||||||
case UNW_ARM_R0:
|
case UNW_ARM_R0:
|
||||||
case UNW_ARM_R1:
|
case UNW_ARM_R1:
|
||||||
case UNW_ARM_R2:
|
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_R11:
|
||||||
case UNW_ARM_R12:
|
case UNW_ARM_R12:
|
||||||
case UNW_ARM_R14:
|
case UNW_ARM_R14:
|
||||||
case UNW_ARM_R15:
|
|
||||||
loc = c->dwarf.loc[reg - UNW_ARM_R0];
|
loc = c->dwarf.loc[reg - UNW_ARM_R0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -45,8 +45,14 @@ arm_exidx_step (struct cursor *c)
|
|||||||
/* mark PC unsaved */
|
/* mark PC unsaved */
|
||||||
c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC;
|
c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC;
|
||||||
|
|
||||||
if ((ret = tdep_find_proc_info (&c->dwarf, c->dwarf.ip, 1)) < 0)
|
/* check dynamic info first --- it overrides everything else */
|
||||||
return ret;
|
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)
|
if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX)
|
||||||
return -UNW_ENOINFO;
|
return -UNW_ENOINFO;
|
||||||
@ -73,99 +79,6 @@ arm_exidx_step (struct cursor *c)
|
|||||||
return (c->dwarf.ip == 0) ? 0 : 1;
|
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
|
PROTECTED int
|
||||||
unw_step (unw_cursor_t *cursor)
|
unw_step (unw_cursor_t *cursor)
|
||||||
{
|
{
|
||||||
@ -210,14 +123,18 @@ unw_step (unw_cursor_t *cursor)
|
|||||||
|
|
||||||
/* Fall back on APCS frame parsing.
|
/* Fall back on APCS frame parsing.
|
||||||
Note: This won't work in case the ARM EABI is used. */
|
Note: This won't work in case the ARM EABI is used. */
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (0)
|
||||||
|
#else
|
||||||
if (unlikely (ret < 0))
|
if (unlikely (ret < 0))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME))
|
if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME))
|
||||||
{
|
{
|
||||||
|
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
|
||||||
ret = UNW_ESUCCESS;
|
ret = UNW_ESUCCESS;
|
||||||
/* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */
|
/* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */
|
||||||
unw_word_t instr, i;
|
unw_word_t instr, i;
|
||||||
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
|
|
||||||
dwarf_loc_t ip_loc, fp_loc;
|
dwarf_loc_t ip_loc, fp_loc;
|
||||||
unw_word_t frame;
|
unw_word_t frame;
|
||||||
/* Mark all registers unsaved, since we don't know where
|
/* 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_R12] = ip_loc;
|
||||||
c->dwarf.loc[UNW_ARM_R11] = fp_loc;
|
c->dwarf.loc[UNW_ARM_R11] = fp_loc;
|
||||||
c->dwarf.pi_valid = 0;
|
c->dwarf.pi_valid = 0;
|
||||||
Debug(15, "ip=%lx\n", c->dwarf.ip);
|
Debug(15, "ip=%x\n", c->dwarf.ip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -268,5 +185,5 @@ unw_step (unw_cursor_t *cursor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret == -UNW_ENOINFO ? 0 : 1;
|
return ret == -UNW_ENOINFO ? 0 : ret;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
|
|||||||
|
|
||||||
case UNW_ARM_FRAME_SIGRETURN:
|
case UNW_ARM_FRAME_SIGRETURN:
|
||||||
cfa = cfa + f->cfa_reg_offset; /* cfa now points to ucontext_t. */
|
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);
|
ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_PC_OFF, pc);
|
||||||
if (likely(ret >= 0))
|
if (likely(ret >= 0))
|
||||||
ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_R7_OFF, r7);
|
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. */
|
doesn't save the link register in the prologue, e.g. kill. */
|
||||||
if (likely(ret >= 0))
|
if (likely(ret >= 0))
|
||||||
ACCESS_MEM_FAST(ret, c->validate, d, cfa + LINUX_SC_LR_OFF, lr);
|
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
|
/* Resume stack at signal restoration point. The stack is not
|
||||||
necessarily continuous here, especially with sigaltstack(). */
|
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;
|
d->use_prev_instr = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case UNW_ARM_FRAME_SYSCALL:
|
||||||
|
printf("XXX1\n");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* We cannot trace through this frame, give up and tell the
|
/* We cannot trace through this frame, give up and tell the
|
||||||
caller we had to stop. Data collected so far may still be
|
caller we had to stop. Data collected so far may still be
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#define UNW_LOCAL_ONLY
|
#define UNW_LOCAL_ONLY
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
#include "Gis_signal_frame.c"
|
#include "Gos-freebsd.c"
|
||||||
#endif
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
#define UNW_LOCAL_ONLY
|
#define UNW_LOCAL_ONLY
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
#include "Gstep.c"
|
#include "Gos-linux.c"
|
||||||
#endif
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
#define UNW_LOCAL_ONLY
|
#define UNW_LOCAL_ONLY
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
#include "Gcreate_addr_space.c"
|
#include "Gos-freebsd.c"
|
||||||
#endif
|
#endif
|
@ -35,8 +35,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
_Uarm_getcontext:
|
_Uarm_getcontext:
|
||||||
stmfd sp!, {r0, r1}
|
stmfd sp!, {r0, r1}
|
||||||
@ store r0
|
@ store r0
|
||||||
|
#if defined(__linux__)
|
||||||
str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF]
|
str r0, [r0, #LINUX_UC_MCONTEXT_OFF + LINUX_SC_R0_OFF]
|
||||||
add 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
|
@ store r1 to r12
|
||||||
stmib r0, {r1-r12}
|
stmib r0, {r1-r12}
|
||||||
@ reconstruct r13 at call site, then store
|
@ reconstruct r13 at call site, then store
|
||||||
@ -50,7 +57,7 @@ _Uarm_getcontext:
|
|||||||
str r1, [r0, #15 * 4]
|
str r1, [r0, #15 * 4]
|
||||||
ldmfd sp!, {r0, r1}
|
ldmfd sp!, {r0, r1}
|
||||||
bx lr
|
bx lr
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
/* We do not need executable stack. */
|
/* We do not need executable stack. */
|
||||||
.section .note.GNU-stack,"",%progbits
|
.section .note.GNU-stack,"",%progbits
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,3 +34,9 @@
|
|||||||
#define LINUX_SC_PC_OFF 0x48
|
#define LINUX_SC_PC_OFF 0x48
|
||||||
#define LINUX_SC_CPSR_OFF 0x4C
|
#define LINUX_SC_CPSR_OFF 0x4C
|
||||||
#define LINUX_SC_FAULTADDR_OFF 0x50
|
#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
|
||||||
|
@ -76,7 +76,7 @@ _UCD_access_reg (unw_addr_space_t as,
|
|||||||
default:
|
default:
|
||||||
Debug(0, "bad regnum:%d\n", regnum);
|
Debug(0, "bad regnum:%d\n", regnum);
|
||||||
return -UNW_EINVAL;
|
return -UNW_EINVAL;
|
||||||
};
|
}
|
||||||
#elif defined(UNW_TARGET_X86_64)
|
#elif defined(UNW_TARGET_X86_64)
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
case UNW_X86_64_RAX:
|
case UNW_X86_64_RAX:
|
||||||
@ -109,7 +109,26 @@ _UCD_access_reg (unw_addr_space_t as,
|
|||||||
default:
|
default:
|
||||||
Debug(0, "bad regnum:%d\n", regnum);
|
Debug(0, "bad regnum:%d\n", regnum);
|
||||||
return -UNW_EINVAL;
|
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
|
#else
|
||||||
#error Port me
|
#error Port me
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,7 +44,9 @@ _UCD_destroy (struct UCD_info *ui)
|
|||||||
close(phdr->backing_fd);
|
close(phdr->backing_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(ui->phdrs);
|
||||||
free(ui->note_phdr);
|
free(ui->note_phdr);
|
||||||
|
free(ui->threads);
|
||||||
|
|
||||||
free(ui);
|
free(ui);
|
||||||
}
|
}
|
||||||
|
@ -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}
|
|
@ -32,7 +32,7 @@ is_cie_id (unw_word_t val, int is_debug_frame)
|
|||||||
0xffffffffffffffff (for 64-bit ELF). However, .eh_frame
|
0xffffffffffffffff (for 64-bit ELF). However, .eh_frame
|
||||||
uses 0. */
|
uses 0. */
|
||||||
if (is_debug_frame)
|
if (is_debug_frame)
|
||||||
return (val == - (uint32_t) 1 || val == - (uint64_t) 1);
|
return (val == (uint32_t)(-1) || val == (uint64_t)(-1));
|
||||||
else
|
else
|
||||||
return (val == 0);
|
return (val == 0);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
|
|||||||
name = (char*) dlname;
|
name = (char*) dlname;
|
||||||
|
|
||||||
err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space);
|
err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
fdesc = malloc (sizeof (struct unw_debug_frame_list));
|
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->debug_frame_size = bufsize;
|
||||||
fdesc->index = NULL;
|
fdesc->index = NULL;
|
||||||
fdesc->next = as->debug_frames;
|
fdesc->next = as->debug_frames;
|
||||||
|
|
||||||
as->debug_frames = fdesc;
|
as->debug_frames = fdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fdesc;
|
return fdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,10 +235,10 @@ debug_frame_tab_append (struct debug_frame_tab *tab,
|
|||||||
tab->size *= 2;
|
tab->size *= 2;
|
||||||
tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size);
|
tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
tab->tab[length].fde_offset = fde_offset;
|
tab->tab[length].fde_offset = fde_offset;
|
||||||
tab->tab[length].start_ip_offset = start_ip;
|
tab->tab[length].start_ip_offset = start_ip;
|
||||||
|
|
||||||
tab->length = length + 1;
|
tab->length = length + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ static int
|
|||||||
debug_frame_tab_compare (const void *a, const void *b)
|
debug_frame_tab_compare (const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const struct table_entry *fa = a, *fb = b;
|
const struct table_entry *fa = a, *fb = b;
|
||||||
|
|
||||||
if (fa->start_ip_offset > fb->start_ip_offset)
|
if (fa->start_ip_offset > fb->start_ip_offset)
|
||||||
return 1;
|
return 1;
|
||||||
else if (fa->start_ip_offset < fb->start_ip_offset)
|
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)
|
else if (phdr->p_type == PT_DYNAMIC)
|
||||||
p_dynamic = phdr;
|
p_dynamic = phdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_text)
|
if (!p_text)
|
||||||
return 0;
|
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);
|
eh_frame = dwarf_find_eh_frame_section (info);
|
||||||
if (eh_frame)
|
if (eh_frame)
|
||||||
{
|
{
|
||||||
unsigned char *p = (unsigned char *) &synth_eh_frame_hdr;
|
|
||||||
Debug (1, "using synthetic .eh_frame_hdr section for %s\n",
|
Debug (1, "using synthetic .eh_frame_hdr section for %s\n",
|
||||||
info->dlpi_name);
|
info->dlpi_name);
|
||||||
/* synth_eh_frame_hdr.version */ p[0] = DW_EH_VERSION;
|
synth_eh_frame_hdr.version = 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.eh_frame_ptr_enc = DW_EH_PE_absptr |
|
||||||
/* synth_eh_frame_hdr.fde_count_enc */ p[2] = DW_EH_PE_omit;
|
((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8);
|
||||||
/* synth_eh_frame_hdr.table_enc */ p[3] = DW_EH_PE_omit;
|
synth_eh_frame_hdr.fde_count_enc = DW_EH_PE_omit;
|
||||||
*(Elf_W (Addr) *)(&p[4]) = eh_frame;
|
synth_eh_frame_hdr.table_enc = DW_EH_PE_omit;
|
||||||
|
synth_eh_frame_hdr.eh_frame = eh_frame;
|
||||||
hdr = &synth_eh_frame_hdr;
|
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);
|
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: */
|
/* (Optionally) read eh_frame_ptr: */
|
||||||
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
|
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
|
/* XXX we know how to build a local binary search table for
|
||||||
.debug_frame, so we could do that here too. */
|
.debug_frame, so we could do that here too. */
|
||||||
cb_data->single_fde = 1;
|
|
||||||
found = linear_search (unw_local_addr_space, ip,
|
found = linear_search (unw_local_addr_space, ip,
|
||||||
eh_frame_start, eh_frame_end, fde_count,
|
eh_frame_start, eh_frame_end, fde_count,
|
||||||
pi, need_unwind_info, NULL);
|
pi, need_unwind_info, NULL);
|
||||||
if (found != 1)
|
if (found != 1)
|
||||||
found = 0;
|
found = 0;
|
||||||
|
else
|
||||||
|
cb_data->single_fde = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -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);
|
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
|
/* 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
|
enough to ensure that dwarf_read_encoded_pointer() can do it's
|
||||||
|
@ -278,7 +278,7 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
|
|||||||
ret = -UNW_ENOMEM;
|
ret = -UNW_ENOMEM;
|
||||||
break;
|
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");
|
Debug (15, "CFA_remember_state\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -289,8 +289,10 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
|
|||||||
ret = -UNW_EINVAL;
|
ret = -UNW_EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof (sr->rs_current));
|
if (*ip < end_ip) {
|
||||||
pop_rstate_stack(rs_stack);
|
memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof (sr->rs_current));
|
||||||
|
pop_rstate_stack(rs_stack);
|
||||||
|
}
|
||||||
Debug (15, "CFA_restore_state\n");
|
Debug (15, "CFA_restore_state\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -606,7 +608,17 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
|
|||||||
if (caching == UNW_CACHE_NONE)
|
if (caching == UNW_CACHE_NONE)
|
||||||
return NULL;
|
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))
|
if (likely (caching == UNW_CACHE_GLOBAL))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Debug (16, "acquiring lock\n");
|
Debug (16, "acquiring lock\n");
|
||||||
lock_acquire (&cache->lock, *saved_maskp);
|
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))
|
if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
|
||||||
|| !cache->hash)
|
|| !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)
|
if (dwarf_flush_rs_cache (cache) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
cache->generation = as->cache_generation;
|
cache->generation = as->cache_generation;
|
||||||
@ -679,7 +693,7 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c)
|
|||||||
unsigned short head;
|
unsigned short head;
|
||||||
|
|
||||||
head = cache->rr_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): */
|
/* remove the old rs from the hash table (if it's there): */
|
||||||
if (cache->links[head].ip)
|
if (cache->links[head].ip)
|
||||||
@ -885,7 +899,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
intrmask_t saved_mask;
|
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)))
|
(rs = rs_lookup(cache, c)))
|
||||||
{
|
{
|
||||||
/* update hint; no locking needed: single-word writes are atomic */
|
/* 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 */
|
needed for unw_resume */
|
||||||
dwarf_state_record_t sr;
|
dwarf_state_record_t sr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Lookup it up the slow way... */
|
/* Lookup it up the slow way... */
|
||||||
ret = fetch_proc_info (c, c->ip, 0);
|
ret = fetch_proc_info (c, c->ip, 0);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
@ -1018,11 +1032,11 @@ dwarf_reg_states_iterate(struct dwarf_cursor *c,
|
|||||||
case UNW_INFO_FORMAT_REMOTE_TABLE:
|
case UNW_INFO_FORMAT_REMOTE_TABLE:
|
||||||
ret = dwarf_reg_states_table_iterate(c, cb, token);
|
ret = dwarf_reg_states_table_iterate(c, cb, token);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNW_INFO_FORMAT_DYNAMIC:
|
case UNW_INFO_FORMAT_DYNAMIC:
|
||||||
ret = dwarf_reg_states_dynamic_iterate (c, cb, token);
|
ret = dwarf_reg_states_dynamic_iterate (c, cb, token);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Debug (1, "Unexpected unwind-info format %d\n", c->pi.format);
|
Debug (1, "Unexpected unwind-info format %d\n", c->pi.format);
|
||||||
ret = -UNW_EINVAL;
|
ret = -UNW_EINVAL;
|
||||||
|
@ -386,6 +386,8 @@ elf_w (load_debuglink) (const char* file, struct elf_image *ei, int is_local)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Elf_W (Shdr) *shdr;
|
Elf_W (Shdr) *shdr;
|
||||||
|
Elf_W (Ehdr) *prev_image = ei->image;
|
||||||
|
off_t prev_size = ei->size;
|
||||||
|
|
||||||
if (!ei->image)
|
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)
|
if (memchr (linkbuf, 0, shdr->sh_size) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
munmap (ei->image, ei->size);
|
|
||||||
ei->image = NULL;
|
ei->image = NULL;
|
||||||
|
|
||||||
Debug(1, "Found debuglink section, following %s\n", linkbuf);
|
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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ HIDDEN void
|
|||||||
hppa_local_addr_space_init (void)
|
hppa_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -58,9 +58,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -33,5 +33,7 @@ unw_apply_reg_state (unw_cursor_t *cursor,
|
|||||||
{
|
{
|
||||||
struct cursor *c = (struct cursor *) 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;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ ia64_local_addr_space_init (void)
|
|||||||
#elif defined(__hpux)
|
#elif defined(__hpux)
|
||||||
local_addr_space.abi = ABI_HPUX;
|
local_addr_space.abi = ABI_HPUX;
|
||||||
#endif
|
#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.find_proc_info = tdep_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -33,5 +33,7 @@ unw_reg_states_iterate (unw_cursor_t *cursor,
|
|||||||
{
|
{
|
||||||
struct cursor *c = (struct cursor *) 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;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ enum ia64_script_insn_opcode
|
|||||||
IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */
|
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 =
|
static __thread struct ia64_script_cache ia64_per_thread_cache =
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ATOMIC_OPS_H
|
#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))
|
if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
|
||||||
return NULL;
|
return NULL;
|
||||||
#else
|
#else
|
||||||
# ifdef HAVE___THREAD
|
# if defined(HAVE___THREAD) && HAVE___THREAD
|
||||||
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
if (as->caching_policy == UNW_CACHE_PER_THREAD)
|
||||||
cache = &ia64_per_thread_cache;
|
cache = &ia64_per_thread_cache;
|
||||||
# endif
|
# endif
|
||||||
|
@ -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}
|
|
@ -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_TABLE:
|
||||||
case UNW_INFO_FORMAT_REMOTE_TABLE:
|
case UNW_INFO_FORMAT_REMOTE_TABLE:
|
||||||
|
case UNW_INFO_FORMAT_ARM_EXIDX:
|
||||||
case UNW_INFO_FORMAT_IP_OFFSET:
|
case UNW_INFO_FORMAT_IP_OFFSET:
|
||||||
#ifdef tdep_search_unwind_table
|
#ifdef tdep_search_unwind_table
|
||||||
/* call platform-specific search routine: */
|
/* call platform-specific search routine: */
|
||||||
|
@ -104,11 +104,15 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len,
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
ip = tdep_get_ip (c);
|
ip = tdep_get_ip (c);
|
||||||
|
#if !defined(__ia64__)
|
||||||
if (c->dwarf.use_prev_instr)
|
if (c->dwarf.use_prev_instr)
|
||||||
--ip;
|
--ip;
|
||||||
|
#endif
|
||||||
error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp,
|
error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp,
|
||||||
tdep_get_as_arg (c));
|
tdep_get_as_arg (c));
|
||||||
|
#if !defined(__ia64__)
|
||||||
if (c->dwarf.use_prev_instr && offp != NULL && error == 0)
|
if (c->dwarf.use_prev_instr && offp != NULL && error == 0)
|
||||||
*offp += 1;
|
*offp += 1;
|
||||||
|
#endif
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,12 @@ unw_set_cache_size (unw_addr_space_t as, size_t size, int flag)
|
|||||||
if (flag != 0)
|
if (flag != 0)
|
||||||
return -1;
|
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 */
|
/* Round up to next power of two, slowly but portably */
|
||||||
while(power < size)
|
while(power < size)
|
||||||
{
|
{
|
||||||
@ -48,10 +54,12 @@ unw_set_cache_size (unw_addr_space_t as, size_t size, int flag)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(__ia64__)
|
||||||
if (log_size == as->global_cache.log_size)
|
if (log_size == as->global_cache.log_size)
|
||||||
return 0; /* no change */
|
return 0; /* no change */
|
||||||
|
|
||||||
as->global_cache.log_size = log_size;
|
as->global_cache.log_size = log_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Ensure caches are empty (and initialized). */
|
/* Ensure caches are empty (and initialized). */
|
||||||
unw_flush_cache (as, 0, 0);
|
unw_flush_cache (as, 0, 0);
|
||||||
|
@ -31,7 +31,7 @@ unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy)
|
|||||||
if (!tdep_init_done)
|
if (!tdep_init_done)
|
||||||
tdep_init ();
|
tdep_init ();
|
||||||
|
|
||||||
#ifndef HAVE___THREAD
|
#if !(defined(HAVE___THREAD) && HAVE___THREAD)
|
||||||
if (policy == UNW_CACHE_PER_THREAD)
|
if (policy == UNW_CACHE_PER_THREAD)
|
||||||
policy = UNW_CACHE_GLOBAL;
|
policy = UNW_CACHE_GLOBAL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,7 +195,7 @@ mips_local_addr_space_init (void)
|
|||||||
# error Unsupported ABI
|
# error Unsupported ABI
|
||||||
#endif
|
#endif
|
||||||
local_addr_space.addr_size = sizeof (void *);
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -57,9 +57,20 @@ unw_init_local(unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -70,6 +70,8 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case UNW_MIPS_PC:
|
case UNW_MIPS_PC:
|
||||||
|
if (write)
|
||||||
|
c->dwarf.ip = *valp; /* update the IP cache */
|
||||||
loc = c->dwarf.loc[reg];
|
loc = c->dwarf.loc[reg];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ get_pid_by_tid(int tid)
|
|||||||
size_t len, len1;
|
size_t len, len1;
|
||||||
char *buf;
|
char *buf;
|
||||||
struct kinfo_proc *kv;
|
struct kinfo_proc *kv;
|
||||||
int i, pid;
|
unsigned i, pid;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
mib[0] = CTL_KERN;
|
mib[0] = CTL_KERN;
|
||||||
|
@ -69,9 +69,20 @@ unw_init_local(unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
37
contrib/libunwind/src/ppc32/Gapply_reg_state.c
Normal file
37
contrib/libunwind/src/ppc32/Gapply_reg_state.c
Normal file
@ -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 <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "unwind_i.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -201,7 +201,7 @@ HIDDEN void
|
|||||||
ppc32_local_addr_space_init (void)
|
ppc32_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* libunwind - a platform-independent unwind library
|
/* libunwind - a platform-independent unwind library
|
||||||
Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
|
Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P.
|
||||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
|
||||||
|
|
||||||
This file is part of libunwind.
|
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
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
#include "dwarf.h"
|
#include "unwind_i.h"
|
||||||
#include "libunwind_i.h"
|
|
||||||
|
|
||||||
HIDDEN int
|
PROTECTED int
|
||||||
dwarf_step (struct dwarf_cursor *c)
|
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) {
|
return dwarf_reg_states_iterate (&c->dwarf, cb, token);
|
||||||
c->pi_valid = 0;
|
|
||||||
ret = (c->ip == 0) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug (15, "returning %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
5
contrib/libunwind/src/ppc32/Lapply_reg_state.c
Normal file
5
contrib/libunwind/src/ppc32/Lapply_reg_state.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
|
#include "Gapply_reg_state.c"
|
||||||
|
#endif
|
5
contrib/libunwind/src/ppc32/Lreg_states_iterate.c
Normal file
5
contrib/libunwind/src/ppc32/Lreg_states_iterate.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
|
#include "Greg_states_iterate.c"
|
||||||
|
#endif
|
37
contrib/libunwind/src/ppc64/Gapply_reg_state.c
Normal file
37
contrib/libunwind/src/ppc64/Gapply_reg_state.c
Normal file
@ -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 <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "unwind_i.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -214,7 +214,7 @@ ppc64_local_addr_space_init (void)
|
|||||||
#else
|
#else
|
||||||
local_addr_space.abi = UNW_PPC64_ABI_ELFv1;
|
local_addr_space.abi = UNW_PPC64_ABI_ELFv1;
|
||||||
#endif
|
#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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
37
contrib/libunwind/src/ppc64/Greg_states_iterate.c
Normal file
37
contrib/libunwind/src/ppc64/Greg_states_iterate.c
Normal file
@ -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 <davidm@hpl.hp.com>
|
||||||
|
|
||||||
|
Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
|
||||||
|
|
||||||
|
This file is part of libunwind.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#include "unwind_i.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
5
contrib/libunwind/src/ppc64/Lapply_reg_state.c
Normal file
5
contrib/libunwind/src/ppc64/Lapply_reg_state.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
|
#include "Gapply_reg_state.c"
|
||||||
|
#endif
|
5
contrib/libunwind/src/ppc64/Lreg_states_iterate.c
Normal file
5
contrib/libunwind/src/ppc64/Lreg_states_iterate.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
|
||||||
|
#include "Greg_states_iterate.c"
|
||||||
|
#endif
|
@ -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;
|
pid_t pid = ui->pid;
|
||||||
fpregset_t fpreg;
|
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))
|
if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset))
|
||||||
return -UNW_EBADREG;
|
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));
|
memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t));
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t));
|
memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t));
|
||||||
|
#elif defined(__arm__)
|
||||||
|
memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t));
|
||||||
#else
|
#else
|
||||||
#error Fix me
|
#error Fix me
|
||||||
#endif
|
#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));
|
memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t));
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t));
|
memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t));
|
||||||
|
#elif defined(__arm__)
|
||||||
|
memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t));
|
||||||
#else
|
#else
|
||||||
#error Fix me
|
#error Fix me
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,7 +34,50 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||||||
# include "tdep-ia64/rse.h"
|
# include "tdep-ia64/rse.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
|
#if HAVE_DECL_PTRACE_SETREGSET
|
||||||
|
#include <sys/uio.h>
|
||||||
|
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
|
int
|
||||||
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
|
||||||
int write, void *arg)
|
int write, void *arg)
|
||||||
|
@ -484,6 +484,7 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] =
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(UNW_TARGET_ARM)
|
#elif defined(UNW_TARGET_ARM)
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
[UNW_ARM_R0] = 0x00,
|
[UNW_ARM_R0] = 0x00,
|
||||||
[UNW_ARM_R1] = 0x04,
|
[UNW_ARM_R1] = 0x04,
|
||||||
[UNW_ARM_R2] = 0x08,
|
[UNW_ARM_R2] = 0x08,
|
||||||
@ -500,6 +501,9 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] =
|
|||||||
[UNW_ARM_R13] = 0x34,
|
[UNW_ARM_R13] = 0x34,
|
||||||
[UNW_ARM_R14] = 0x38,
|
[UNW_ARM_R14] = 0x38,
|
||||||
[UNW_ARM_R15] = 0x3c,
|
[UNW_ARM_R15] = 0x3c,
|
||||||
|
#else
|
||||||
|
#error Fix me
|
||||||
|
#endif
|
||||||
#elif defined(UNW_TARGET_MIPS)
|
#elif defined(UNW_TARGET_MIPS)
|
||||||
[UNW_MIPS_R0] = 0,
|
[UNW_MIPS_R0] = 0,
|
||||||
[UNW_MIPS_R1] = 1,
|
[UNW_MIPS_R1] = 1,
|
||||||
|
@ -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}
|
|
@ -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}
|
|
@ -171,7 +171,7 @@ HIDDEN void
|
|||||||
sh_local_addr_space_init (void)
|
sh_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -59,9 +59,20 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -33,6 +33,9 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
|
|||||||
|
|
||||||
switch (reg)
|
switch (reg)
|
||||||
{
|
{
|
||||||
|
case UNW_SH_PC:
|
||||||
|
if (write)
|
||||||
|
c->dwarf.ip = *valp; /* update the IP cache */
|
||||||
case UNW_SH_R0:
|
case UNW_SH_R0:
|
||||||
case UNW_SH_R1:
|
case UNW_SH_R1:
|
||||||
case UNW_SH_R2:
|
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_R12:
|
||||||
case UNW_SH_R13:
|
case UNW_SH_R13:
|
||||||
case UNW_SH_R14:
|
case UNW_SH_R14:
|
||||||
case UNW_SH_PC:
|
|
||||||
case UNW_SH_PR:
|
case UNW_SH_PR:
|
||||||
loc = c->dwarf.loc[reg];
|
loc = c->dwarf.loc[reg];
|
||||||
break;
|
break;
|
||||||
|
@ -152,7 +152,7 @@ tilegx_local_addr_space_init (void)
|
|||||||
|
|
||||||
local_addr_space.abi = UNW_TILEGX_ABI_N64;
|
local_addr_space.abi = UNW_TILEGX_ABI_N64;
|
||||||
local_addr_space.addr_size = sizeof (void *);
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -61,9 +61,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -52,7 +52,17 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (write)
|
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
|
else
|
||||||
return dwarf_get (&c->dwarf, loc, valp);
|
return dwarf_get (&c->dwarf, loc, valp);
|
||||||
}
|
}
|
||||||
|
@ -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}
|
|
@ -228,7 +228,7 @@ HIDDEN void
|
|||||||
x86_local_addr_space_init (void)
|
x86_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -60,9 +60,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -52,7 +52,7 @@ unw_is_signal_frame (unw_cursor_t *cursor)
|
|||||||
__restore_rt:
|
__restore_rt:
|
||||||
0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax
|
0xb8 0xad 0x00 0x00 0x00 movl 0xad,%eax
|
||||||
0xcd 0x80 int 0x80
|
0xcd 0x80 int 0x80
|
||||||
0x00
|
0x00
|
||||||
|
|
||||||
if SA_SIGINFO is specified.
|
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;
|
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||||
|
|
||||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
||||||
sigreturn (sc);
|
x86_sigreturn (sc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -305,4 +305,25 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
|||||||
}
|
}
|
||||||
return -UNW_EINVAL;
|
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
|
#endif
|
||||||
|
@ -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_scratch_loc UNW_OBJ(scratch_loc)
|
||||||
#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc)
|
#define x86_get_scratch_loc UNW_OBJ(get_scratch_loc)
|
||||||
#define x86_r_uc_addr UNW_OBJ(r_uc_addr)
|
#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 void x86_local_addr_space_init (void);
|
||||||
extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
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 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_r_uc_addr (ucontext_t *uc, int reg);
|
||||||
|
|
||||||
|
extern void x86_sigreturn (unw_cursor_t *cursor);
|
||||||
|
|
||||||
#endif /* unwind_i_h */
|
#endif /* unwind_i_h */
|
||||||
|
@ -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_SIZE 4096
|
||||||
#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1))
|
#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 (*mem_validate_func) (void *addr, size_t len);
|
||||||
static int msync_validate (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
|
#ifdef HAVE_MINCORE
|
||||||
@ -96,7 +143,7 @@ static int mincore_validate (void *addr, size_t len)
|
|||||||
if (!(mvec[i] & 1)) return -1;
|
if (!(mvec[i] & 1)) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return write_validate (addr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -107,6 +154,8 @@ static int mincore_validate (void *addr, size_t len)
|
|||||||
HIDDEN void
|
HIDDEN void
|
||||||
tdep_init_mem_validate (void)
|
tdep_init_mem_validate (void)
|
||||||
{
|
{
|
||||||
|
open_pipe ();
|
||||||
|
|
||||||
#ifdef HAVE_MINCORE
|
#ifdef HAVE_MINCORE
|
||||||
unsigned char present = 1;
|
unsigned char present = 1;
|
||||||
unw_word_t addr = PAGE_START((unw_word_t)&present);
|
unw_word_t addr = PAGE_START((unw_word_t)&present);
|
||||||
@ -273,7 +322,7 @@ HIDDEN void
|
|||||||
x86_64_local_addr_space_init (void)
|
x86_64_local_addr_space_init (void)
|
||||||
{
|
{
|
||||||
memset (&local_addr_space, 0, sizeof (local_addr_space));
|
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.find_proc_info = dwarf_find_proc_info;
|
||||||
local_addr_space.acc.put_unwind_info = put_unwind_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;
|
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
|
||||||
|
@ -62,9 +62,20 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECTED int
|
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 */
|
#endif /* !UNW_REMOTE_ONLY */
|
||||||
|
@ -138,7 +138,7 @@ x86_64_sigreturn (unw_cursor_t *cursor)
|
|||||||
{
|
{
|
||||||
struct cursor *c = (struct cursor *) cursor;
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
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 */
|
/* Copy in saved uc - all preserved regs are at the start of sigcontext */
|
||||||
memcpy(sc_mcontext, &c->uc->uc_mcontext,
|
memcpy(sc_mcontext, &c->uc->uc_mcontext,
|
||||||
DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t));
|
DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t));
|
||||||
|
@ -83,6 +83,7 @@ common_init (struct cursor *c, unsigned use_prev_instr)
|
|||||||
c->dwarf.pi_is_dynamic = 0;
|
c->dwarf.pi_is_dynamic = 0;
|
||||||
c->dwarf.hint = 0;
|
c->dwarf.hint = 0;
|
||||||
c->dwarf.prev_rs = 0;
|
c->dwarf.prev_rs = 0;
|
||||||
|
c->dwarf.eh_valid_mask = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ size_t backtraceLibUnwind(void ** out_frames, size_t max_frames, ucontext_t & co
|
|||||||
|
|
||||||
unw_cursor_t cursor;
|
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;
|
return 0;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user