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