libunwind_i.h revision 16b95a68caaa7e021209e2cd6a877ae1e558f740
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 <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> 120static inline int 121cmpxchg_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 144static inline int 145cmpxchg_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. */ 173typedef sigset_t intrmask_t; 174 175extern 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 */ 179static 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#define define_lock(name) \ 190 pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER 191#define lock_init(l) mutex_init (l) 192#define lock_acquire(l,m) \ 193do { \ 194 SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m)); \ 195 mutex_lock (l); \ 196} while (0) 197#define lock_release(l,m) \ 198do { \ 199 mutex_unlock (l); \ 200 SIGPROCMASK (SIG_SETMASK, &(m), NULL); \ 201} while (0) 202 203#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */ 204 205#ifndef MAP_ANONYMOUS 206# define MAP_ANONYMOUS MAP_ANON 207#endif 208#define GET_MEMORY(mem, size) \ 209do { \ 210 /* Hopefully, mmap() goes straight through to a system call stub... */ \ 211 mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \ 212 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ 213 if (mem == MAP_FAILED) \ 214 mem = NULL; \ 215} while (0) 216 217#define unwi_find_dynamic_proc_info UNWI_OBJ(find_dynamic_proc_info) 218#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info) 219#define unwi_put_dynamic_unwind_info UNWI_OBJ(put_dynamic_unwind_info) 220#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info) 221#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info) 222#define unwi_dyn_validate_cache UNWI_OBJ(dyn_validate_cache) 223 224extern int unwi_find_dynamic_proc_info (unw_addr_space_t as, 225 unw_word_t ip, 226 unw_proc_info_t *pi, 227 int need_unwind_info, void *arg); 228extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as, 229 unw_word_t ip, 230 unw_proc_info_t *pi, 231 unw_dyn_info_t *di, 232 int need_unwind_info, 233 void *arg); 234extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as, 235 unw_proc_info_t *pi, void *arg); 236 237/* These handle the remote (cross-address-space) case of accessing 238 dynamic unwind info. */ 239 240extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as, 241 unw_word_t ip, 242 unw_proc_info_t *pi, 243 int need_unwind_info, 244 void *arg); 245extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as, 246 unw_proc_info_t *pi, 247 void *arg); 248extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg); 249 250extern unw_dyn_info_list_t _U_dyn_info_list; 251extern pthread_mutex_t _U_dyn_info_list_lock; 252 253#if UNW_DEBUG 254#define unwi_debug_level UNWI_ARCH_OBJ(debug_level) 255extern long unwi_debug_level; 256 257# include <stdio.h> 258# define Debug(level,format...) \ 259do { \ 260 if (unwi_debug_level >= level) \ 261 { \ 262 int _n = level; \ 263 if (_n > 16) \ 264 _n = 16; \ 265 fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ 266 fprintf (stderr, format); \ 267 } \ 268} while (0) 269# define Dprintf(format...) fprintf (stderr, format) 270# ifdef __GNUC__ 271# undef inline 272# define inline UNUSED 273# endif 274#else 275# define Debug(level,format...) 276# define Dprintf(format...) 277#endif 278 279static ALWAYS_INLINE int 280print_error (const char *string) 281{ 282 return write (2, string, strlen (string)); 283} 284 285#define mi_init UNWI_ARCH_OBJ(mi_init) 286 287extern void mi_init (void); /* machine-independent initializations */ 288extern unw_word_t _U_dyn_info_list_addr (void); 289 290/* This is needed/used by ELF targets only. */ 291 292struct elf_image 293 { 294 void *image; /* pointer to mmap'd image */ 295 size_t size; /* (file-) size of the image */ 296 }; 297 298struct elf_dyn_info 299 { 300 /* ANDROID support update.*/ 301 /* Removed: struct elf_image ei; */ 302 /* End of ANDROID update. */ 303 unw_dyn_info_t di_cache; 304 unw_dyn_info_t di_debug; /* additional table info for .debug_frame */ 305#if UNW_TARGET_IA64 306 unw_dyn_info_t ktab; 307#endif 308#if UNW_TARGET_ARM 309 unw_dyn_info_t di_arm; /* additional table info for .ARM.exidx */ 310#endif 311 }; 312 313static inline void invalidate_edi (struct elf_dyn_info *edi) 314{ 315 /* ANDROID support update.*/ 316 /* Removed: if (edi->ei.image) */ 317 /* munmap (edi->ei.image, edi->ei.size); */ 318 /* End of ANDROID update. */ 319 memset (edi, 0, sizeof (*edi)); 320 edi->di_cache.format = -1; 321 edi->di_debug.format = -1; 322#if UNW_TARGET_ARM 323 edi->di_arm.format = -1; 324#endif 325} 326 327 328/* Provide a place holder for architecture to override for fast access 329 to memory when known not to need to validate and know the access 330 will be local to the process. A suitable override will improve 331 unw_tdep_trace() performance in particular. */ 332#define ACCESS_MEM_FAST(ret,validate,cur,addr,to) \ 333 do { (ret) = dwarf_get ((cur), DWARF_MEM_LOC ((cur), (addr)), &(to)); } \ 334 while (0) 335 336/* Define GNU and processor specific values for the Phdr p_type field in case 337 they aren't defined by <elf.h>. */ 338#ifndef PT_GNU_EH_FRAME 339# define PT_GNU_EH_FRAME 0x6474e550 340#endif /* !PT_GNU_EH_FRAME */ 341#ifndef PT_ARM_EXIDX 342# define PT_ARM_EXIDX 0x70000001 /* ARM unwind segment */ 343#endif /* !PT_ARM_EXIDX */ 344 345#include "tdep/libunwind_i.h" 346 347#ifndef tdep_get_func_addr 348# define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) 349#endif 350 351#define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) 352 353#endif /* libunwind_i_h */ 354