libunwind_i.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /* libunwind - a platform-independent unwind library
  2. Copyright (C) 2001-2005 Hewlett-Packard Co
  3. Copyright (C) 2007 David Mosberger-Tang
  4. Contributed by David Mosberger-Tang <dmosberger@gmail.com>
  5. This file is part of libunwind.
  6. Permission is hereby granted, free of charge, to any person obtaining
  7. a copy of this software and associated documentation files (the
  8. "Software"), to deal in the Software without restriction, including
  9. without limitation the rights to use, copy, modify, merge, publish,
  10. distribute, sublicense, and/or sell copies of the Software, and to
  11. permit persons to whom the Software is furnished to do so, subject to
  12. the following conditions:
  13. The above copyright notice and this permission notice shall be
  14. included in all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22. /* This files contains libunwind-internal definitions which are
  23. subject to frequent change and are not to be exposed to
  24. libunwind-users. */
  25. #ifndef libunwind_i_h
  26. #define libunwind_i_h
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #ifdef HAVE___THREAD
  31. /* For now, turn off per-thread caching. It uses up too much TLS
  32. memory per thread even when the thread never uses libunwind at
  33. all. */
  34. # undef HAVE___THREAD
  35. #endif
  36. /* Platform-independent libunwind-internal declarations. */
  37. #include <sys/types.h> /* HP-UX needs this before include of pthread.h */
  38. #include <assert.h>
  39. #include <libunwind.h>
  40. #if HAVE_SGX
  41. #include "pthread_compat.h"
  42. #else
  43. #include <pthread.h>
  44. #include <signal.h>
  45. #endif
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <unistd.h>
  49. #include <sys/mman.h>
  50. #include <elf.h>
  51. #if defined(HAVE_ENDIAN_H)
  52. # include <endian.h>
  53. #elif defined(HAVE_SYS_ENDIAN_H)
  54. # include <sys/endian.h>
  55. #else
  56. # define __LITTLE_ENDIAN 1234
  57. # define __BIG_ENDIAN 4321
  58. # if defined(__hpux)
  59. # define __BYTE_ORDER __BIG_ENDIAN
  60. # else
  61. # error Host has unknown byte-order.
  62. # endif
  63. #endif
  64. #ifdef __GNUC__
  65. # define UNUSED __attribute__((unused))
  66. # define NORETURN __attribute__((noreturn))
  67. # define ALIAS(name) __attribute__((alias (#name)))
  68. # if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
  69. # define ALWAYS_INLINE inline __attribute__((always_inline))
  70. # define HIDDEN __attribute__((visibility ("hidden")))
  71. # define PROTECTED __attribute__((visibility ("protected")))
  72. # else
  73. # define ALWAYS_INLINE
  74. # define HIDDEN
  75. # define PROTECTED
  76. # endif
  77. # if (__GNUC__ >= 3)
  78. # define likely(x) __builtin_expect ((x), 1)
  79. # define unlikely(x) __builtin_expect ((x), 0)
  80. # else
  81. # define likely(x) (x)
  82. # define unlikely(x) (x)
  83. # endif
  84. #else
  85. # define ALWAYS_INLINE
  86. # define UNUSED
  87. # define NORETURN
  88. # define ALIAS(name)
  89. # define HIDDEN
  90. # define PROTECTED
  91. # define likely(x) (x)
  92. # define unlikely(x) (x)
  93. #endif
  94. #ifdef DEBUG
  95. # define UNW_DEBUG 1
  96. #else
  97. # define UNW_DEBUG 0
  98. #endif
  99. #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
  100. /* Make it easy to write thread-safe code which may or may not be
  101. linked against libpthread. The macros below can be used
  102. unconditionally and if -lpthread is around, they'll call the
  103. corresponding routines otherwise, they do nothing. */
  104. #if HAVE_SGX
  105. #define mutex_init(l) do { *l = PTHREAD_MUTEX_INITIALIZER; } while(0)
  106. #define mutex_lock(l) do { if (pthread_mutex_lock ((l)) != 0) abort(); } while(0)
  107. #define mutex_unlock(l) do { if (pthread_mutex_unlock ((l)) != 0) abort(); } while(0)
  108. #else
  109. #pragma weak pthread_mutex_init
  110. #pragma weak pthread_mutex_lock
  111. #pragma weak pthread_mutex_unlock
  112. #define mutex_init(l) \
  113. (pthread_mutex_init != 0 ? pthread_mutex_init ((l), 0) : 0)
  114. #define mutex_lock(l) \
  115. (pthread_mutex_lock != 0 ? pthread_mutex_lock (l) : 0)
  116. #define mutex_unlock(l) \
  117. (pthread_mutex_unlock != 0 ? pthread_mutex_unlock (l) : 0)
  118. #endif
  119. #ifdef HAVE_ATOMIC_OPS_H
  120. # include <atomic_ops.h>
  121. static inline int
  122. cmpxchg_ptr (void *addr, void *old, void *new)
  123. {
  124. union
  125. {
  126. void *vp;
  127. AO_t *aop;
  128. }
  129. u;
  130. u.vp = addr;
  131. return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
  132. }
  133. # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
  134. /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
  135. # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
  136. # define HAVE_CMPXCHG
  137. # endif
  138. # define HAVE_FETCH_AND_ADD1
  139. #else
  140. # ifdef HAVE_IA64INTRIN_H
  141. # include <ia64intrin.h>
  142. static inline int
  143. cmpxchg_ptr (void *addr, void *old, void *new)
  144. {
  145. union
  146. {
  147. void *vp;
  148. long *vlp;
  149. }
  150. u;
  151. u.vp = addr;
  152. return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
  153. }
  154. # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
  155. # define HAVE_CMPXCHG
  156. # define HAVE_FETCH_AND_ADD1
  157. # endif
  158. #endif
  159. #define atomic_read(ptr) (*(ptr))
  160. #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
  161. #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
  162. #define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
  163. /* Type of a mask that can be used to inhibit preemption. At the
  164. userlevel, preemption is caused by signals and hence sigset_t is
  165. appropriate. In constrast, the Linux kernel uses "unsigned long"
  166. to hold the processor "flags" instead. */
  167. typedef sigset_t intrmask_t;
  168. extern intrmask_t unwi_full_mask;
  169. /* Silence compiler warnings about variables which are used only if libunwind
  170. is configured in a certain way */
  171. static inline void mark_as_used(void *v) {
  172. }
  173. #if defined(CONFIG_BLOCK_SIGNALS)
  174. # define SIGPROCMASK(how, new_mask, old_mask) \
  175. sigprocmask((how), (new_mask), (old_mask))
  176. #else
  177. # define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask)
  178. #endif
  179. #define define_lock(name) \
  180. pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
  181. #define lock_init(l) mutex_init (l)
  182. #define lock_acquire(l,m) \
  183. do { \
  184. SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \
  185. mutex_lock (l); \
  186. } while (0)
  187. #define lock_release(l,m) \
  188. do { \
  189. mutex_unlock (l); \
  190. SIGPROCMASK (SIG_SETMASK, &(m), NULL); \
  191. } while (0)
  192. #define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */
  193. #if HAVE_SGX /* Running inside Enclave */
  194. #define GET_MEMORY(mem, size) do { mem = malloc(size); } while (0)
  195. #else /* Normal application */
  196. #ifndef MAP_ANONYMOUS
  197. # define MAP_ANONYMOUS MAP_ANON
  198. #endif
  199. #define GET_MEMORY(mem, size) \
  200. do { \
  201. /* Hopefully, mmap() goes straight through to a system call stub... */ \
  202. mem = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, \
  203. -1, 0); \
  204. if (mem == MAP_FAILED) \
  205. mem = NULL; \
  206. } while (0)
  207. #endif
  208. #define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info)
  209. #define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
  210. #define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info)
  211. #define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info)
  212. #define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info)
  213. #define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache)
  214. extern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
  215. unw_word_t ip,
  216. unw_proc_info_t *pi,
  217. int need_unwind_info, void *arg);
  218. extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
  219. unw_word_t ip,
  220. unw_proc_info_t *pi,
  221. unw_dyn_info_t *di,
  222. int need_unwind_info,
  223. void *arg);
  224. extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
  225. unw_proc_info_t *pi, void *arg);
  226. /* These handle the remote (cross-address-space) case of accessing
  227. dynamic unwind info. */
  228. extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
  229. unw_word_t ip,
  230. unw_proc_info_t *pi,
  231. int need_unwind_info,
  232. void *arg);
  233. extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
  234. unw_proc_info_t *pi,
  235. void *arg);
  236. extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
  237. extern unw_dyn_info_list_t _U_dyn_info_list;
  238. extern pthread_mutex_t _U_dyn_info_list_lock;
  239. #if UNW_DEBUG && !HAVE_SGX
  240. #define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
  241. extern long unwi_debug_level;
  242. # include <stdio.h>
  243. # define Debug(level,format...) \
  244. do { \
  245. if (unwi_debug_level >= level) \
  246. { \
  247. int _n = level; \
  248. if (_n > 16) \
  249. _n = 16; \
  250. fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \
  251. fprintf (stderr, format); \
  252. } \
  253. } while (0)
  254. # define Dprintf(format...) fprintf (stderr, format)
  255. # ifdef __GNUC__
  256. # undef inline
  257. # define inline UNUSED
  258. # endif
  259. #else
  260. # define Debug(level,format...)
  261. # define Dprintf(format...)
  262. #endif
  263. static ALWAYS_INLINE void
  264. print_error (const char *string)
  265. {
  266. #if !HAVE_SGX
  267. write (2, string, strlen (string));
  268. #endif
  269. }
  270. #define mi_init UNWI_ARCH_OBJ(mi_init)
  271. extern void mi_init (void); /* machine-independent initializations */
  272. extern unw_word_t _U_dyn_info_list_addr (void);
  273. /* This is needed/used by ELF targets only. */
  274. struct elf_image
  275. {
  276. void *image; /* pointer to mmap'd image */
  277. size_t size; /* (file-) size of the image */
  278. };
  279. struct elf_dyn_info
  280. {
  281. struct elf_image ei;
  282. unw_dyn_info_t di_cache;
  283. unw_dyn_info_t di_debug; /* additional table info for .debug_frame */
  284. #if UNW_TARGET_IA64
  285. unw_dyn_info_t ktab;
  286. #endif
  287. #if UNW_TARGET_ARM
  288. unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */
  289. #endif
  290. };
  291. static void inline invalidate_edi (struct elf_dyn_info *edi)
  292. {
  293. if (edi->ei.image)
  294. #if !HAVE_SGX
  295. munmap (edi->ei.image, edi->ei.size);
  296. #else /* to align with GET_MEMORY() */
  297. free(edi->ei.image);
  298. #endif
  299. memset (edi, 0, sizeof (*edi));
  300. edi->di_cache.format = -1;
  301. edi->di_debug.format = -1;
  302. #if UNW_TARGET_ARM
  303. edi->di_arm.format = -1;
  304. #endif
  305. }
  306. /* Provide a place holder for architecture to override for fast access
  307. to memory when known not to need to validate and know the access
  308. will be local to the process. A suitable override will improve
  309. unw_tdep_trace() performance in particular. */
  310. #define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \
  311. do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \
  312. while (0)
  313. /* Define GNU and processor specific values for the Phdr p_type field in case
  314. they aren't defined by <elf.h>. */
  315. #ifndef PT_GNU_EH_FRAME
  316. # define PT_GNU_EH_FRAME 0x6474e550
  317. #endif /* !PT_GNU_EH_FRAME */
  318. #ifndef PT_ARM_EXIDX
  319. # define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */
  320. #endif /* !PT_ARM_EXIDX */
  321. #include "tdep/libunwind_i.h"
  322. #ifndef tdep_get_func_addr
  323. # define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0)
  324. #endif
  325. #endif /* libunwind_i_h */