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