123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- #ifndef libunwind_i_h
- #define libunwind_i_h
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
- #ifdef HAVE___THREAD
-
- # undef HAVE___THREAD
- #endif
- #include <sys/types.h> /* HP-UX needs this before include of pthread.h */
- #include <assert.h>
- #include <libunwind.h>
- #if HAVE_SGX
- #include "pthread_compat.h"
- #else
- #include <pthread.h>
- #include <signal.h>
- #endif
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <elf.h>
- #if defined(HAVE_ENDIAN_H)
- # include <endian.h>
- #elif defined(HAVE_SYS_ENDIAN_H)
- # include <sys/endian.h>
- #else
- # define __LITTLE_ENDIAN 1234
- # define __BIG_ENDIAN 4321
- # if defined(__hpux)
- # define __BYTE_ORDER __BIG_ENDIAN
- # else
- # error Host has unknown byte-order.
- # endif
- #endif
- #ifdef __GNUC__
- # define UNUSED __attribute__((unused))
- # define NORETURN __attribute__((noreturn))
- # define ALIAS(name) __attribute__((alias (#name)))
- # if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
- # define ALWAYS_INLINE inline __attribute__((always_inline))
- # define HIDDEN __attribute__((visibility ("hidden")))
- # define PROTECTED __attribute__((visibility ("protected")))
- # else
- # define ALWAYS_INLINE
- # define HIDDEN
- # define PROTECTED
- # endif
- # if (__GNUC__ >= 3)
- # define likely(x) __builtin_expect ((x), 1)
- # define unlikely(x) __builtin_expect ((x), 0)
- # else
- # define likely(x) (x)
- # define unlikely(x) (x)
- # endif
- #else
- # define ALWAYS_INLINE
- # define UNUSED
- # define NORETURN
- # define ALIAS(name)
- # define HIDDEN
- # define PROTECTED
- # define likely(x) (x)
- # define unlikely(x) (x)
- #endif
- #ifdef DEBUG
- # define UNW_DEBUG 1
- #else
- # define UNW_DEBUG 0
- #endif
- #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
- #if HAVE_SGX
- #define mutex_init(l) do { *l = PTHREAD_MUTEX_INITIALIZER; } while(0)
- #define mutex_lock(l) do { if (pthread_mutex_lock ((l)) != 0) abort(); } while(0)
- #define mutex_unlock(l) do { if (pthread_mutex_unlock ((l)) != 0) abort(); } while(0)
- #else
- #pragma weak pthread_mutex_init
- #pragma weak pthread_mutex_lock
- #pragma weak pthread_mutex_unlock
- #define mutex_init(l) \
- (pthread_mutex_init != 0 ? pthread_mutex_init ((l), 0) : 0)
- #define mutex_lock(l) \
- (pthread_mutex_lock != 0 ? pthread_mutex_lock (l) : 0)
- #define mutex_unlock(l) \
- (pthread_mutex_unlock != 0 ? pthread_mutex_unlock (l) : 0)
- #endif
- #ifdef HAVE_ATOMIC_OPS_H
- # include <atomic_ops.h>
- static inline int
- cmpxchg_ptr (void *addr, void *old, void *new)
- {
- union
- {
- void *vp;
- AO_t *aop;
- }
- u;
- u.vp = addr;
- return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
- }
- # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
-
- # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
- # define HAVE_CMPXCHG
- # endif
- # define HAVE_FETCH_AND_ADD1
- #else
- # ifdef HAVE_IA64INTRIN_H
- # include <ia64intrin.h>
- static inline int
- cmpxchg_ptr (void *addr, void *old, void *new)
- {
- union
- {
- void *vp;
- long *vlp;
- }
- u;
- u.vp = addr;
- return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
- }
- # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
- # define HAVE_CMPXCHG
- # define HAVE_FETCH_AND_ADD1
- # endif
- #endif
- #define atomic_read(ptr) (*(ptr))
- #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
- #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
- #define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
- typedef sigset_t intrmask_t;
- extern intrmask_t unwi_full_mask;
- static inline void mark_as_used(void *v) {
- }
- #if defined(CONFIG_BLOCK_SIGNALS)
- # define SIGPROCMASK(how, new_mask, old_mask) \
- sigprocmask((how), (new_mask), (old_mask))
- #else
- # define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask)
- #endif
- #define define_lock(name) \
- pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
- #define lock_init(l) mutex_init (l)
- #define lock_acquire(l,m) \
- do { \
- SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \
- mutex_lock (l); \
- } while (0)
- #define lock_release(l,m) \
- do { \
- mutex_unlock (l); \
- SIGPROCMASK (SIG_SETMASK, &(m), NULL); \
- } while (0)
- #define SOS_MEMORY_SIZE 16384
- #if HAVE_SGX
- #define GET_MEMORY(mem, size) do { mem = malloc(size); } while (0)
- #else
- #ifndef MAP_ANONYMOUS
- # define MAP_ANONYMOUS MAP_ANON
- #endif
- #define GET_MEMORY(mem, size) \
- do { \
- \
- mem = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, \
- -1, 0); \
- if (mem == MAP_FAILED) \
- mem = NULL; \
- } while (0)
- #endif
- #define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info)
- #define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
- #define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info)
- #define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info)
- #define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info)
- #define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache)
- extern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
- unw_word_t ip,
- unw_proc_info_t *pi,
- int need_unwind_info, void *arg);
- extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
- unw_word_t ip,
- unw_proc_info_t *pi,
- unw_dyn_info_t *di,
- int need_unwind_info,
- void *arg);
- extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pi, void *arg);
- extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
- unw_word_t ip,
- unw_proc_info_t *pi,
- int need_unwind_info,
- void *arg);
- extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pi,
- void *arg);
- extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
- extern unw_dyn_info_list_t _U_dyn_info_list;
- extern pthread_mutex_t _U_dyn_info_list_lock;
- #if UNW_DEBUG && !HAVE_SGX
- #define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
- extern long unwi_debug_level;
- # include <stdio.h>
- # define Debug(level,format...) \
- do { \
- if (unwi_debug_level >= level) \
- { \
- int _n = level; \
- if (_n > 16) \
- _n = 16; \
- fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \
- fprintf (stderr, format); \
- } \
- } while (0)
- # define Dprintf(format...) fprintf (stderr, format)
- # ifdef __GNUC__
- # undef inline
- # define inline UNUSED
- # endif
- #else
- # define Debug(level,format...)
- # define Dprintf(format...)
- #endif
- static ALWAYS_INLINE void
- print_error (const char *string)
- {
- #if !HAVE_SGX
- write (2, string, strlen (string));
- #endif
- }
- #define mi_init UNWI_ARCH_OBJ(mi_init)
- extern void mi_init (void);
- extern unw_word_t _U_dyn_info_list_addr (void);
- struct elf_image
- {
- void *image;
- size_t size;
- };
- struct elf_dyn_info
- {
- struct elf_image ei;
- unw_dyn_info_t di_cache;
- unw_dyn_info_t di_debug;
- #if UNW_TARGET_IA64
- unw_dyn_info_t ktab;
- #endif
- #if UNW_TARGET_ARM
- unw_dyn_info_t di_arm;
- #endif
- };
- static void inline invalidate_edi (struct elf_dyn_info *edi)
- {
- if (edi->ei.image)
- #if !HAVE_SGX
- munmap (edi->ei.image, edi->ei.size);
- #else
- free(edi->ei.image);
- #endif
- memset (edi, 0, sizeof (*edi));
- edi->di_cache.format = -1;
- edi->di_debug.format = -1;
- #if UNW_TARGET_ARM
- edi->di_arm.format = -1;
- #endif
- }
- #define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \
- do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \
- while (0)
- #ifndef PT_GNU_EH_FRAME
- # define PT_GNU_EH_FRAME 0x6474e550
- #endif
- #ifndef PT_ARM_EXIDX
- # define PT_ARM_EXIDX 0x70000001
- #endif
- #include "tdep/libunwind_i.h"
- #ifndef tdep_get_func_addr
- # define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0)
- #endif
- #endif
|