1 /* libunwind - a platform-independent unwind library 2 Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. 3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4 5 This file is part of libunwind. 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 "Software"), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be 16 included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 26 #ifndef dwarf_h 27 #define dwarf_h 28 29 #include <libunwind.h> 30 #include <stdatomic.h> 31 32 struct dwarf_cursor; /* forward-declaration */ 33 struct elf_dyn_info; 34 struct elf_image; 35 struct map_info; 36 37 #include "dwarf-config.h" 38 39 #ifdef HAVE_CONFIG_H 40 # include "config.h" 41 #endif 42 43 #ifndef UNW_REMOTE_ONLY 44 #if defined(HAVE_LINK_H) 45 #include <link.h> 46 #elif defined(HAVE_SYS_LINK_H) 47 #include <sys/link.h> 48 #else 49 #error Could not find <link.h> 50 #endif 51 #if defined(__ANDROID__) && defined(__arm__) && __ANDROID_API__ < 21 52 int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), void *); 53 #endif 54 #endif 55 56 #include <pthread.h> 57 58 /* DWARF expression opcodes. */ 59 60 typedef enum 61 { 62 DW_OP_addr = 0x03, 63 DW_OP_deref = 0x06, 64 DW_OP_const1u = 0x08, 65 DW_OP_const1s = 0x09, 66 DW_OP_const2u = 0x0a, 67 DW_OP_const2s = 0x0b, 68 DW_OP_const4u = 0x0c, 69 DW_OP_const4s = 0x0d, 70 DW_OP_const8u = 0x0e, 71 DW_OP_const8s = 0x0f, 72 DW_OP_constu = 0x10, 73 DW_OP_consts = 0x11, 74 DW_OP_dup = 0x12, 75 DW_OP_drop = 0x13, 76 DW_OP_over = 0x14, 77 DW_OP_pick = 0x15, 78 DW_OP_swap = 0x16, 79 DW_OP_rot = 0x17, 80 DW_OP_xderef = 0x18, 81 DW_OP_abs = 0x19, 82 DW_OP_and = 0x1a, 83 DW_OP_div = 0x1b, 84 DW_OP_minus = 0x1c, 85 DW_OP_mod = 0x1d, 86 DW_OP_mul = 0x1e, 87 DW_OP_neg = 0x1f, 88 DW_OP_not = 0x20, 89 DW_OP_or = 0x21, 90 DW_OP_plus = 0x22, 91 DW_OP_plus_uconst = 0x23, 92 DW_OP_shl = 0x24, 93 DW_OP_shr = 0x25, 94 DW_OP_shra = 0x26, 95 DW_OP_xor = 0x27, 96 DW_OP_skip = 0x2f, 97 DW_OP_bra = 0x28, 98 DW_OP_eq = 0x29, 99 DW_OP_ge = 0x2a, 100 DW_OP_gt = 0x2b, 101 DW_OP_le = 0x2c, 102 DW_OP_lt = 0x2d, 103 DW_OP_ne = 0x2e, 104 DW_OP_lit0 = 0x30, 105 DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5, 106 DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10, 107 DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, 108 DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20, 109 DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25, 110 DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30, 111 DW_OP_lit31, 112 DW_OP_reg0 = 0x50, 113 DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5, 114 DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10, 115 DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15, 116 DW_OP_reg16, DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20, 117 DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25, 118 DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30, 119 DW_OP_reg31, 120 DW_OP_breg0 = 0x70, 121 DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5, 122 DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10, 123 DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15, 124 DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20, 125 DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25, 126 DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30, 127 DW_OP_breg31, 128 DW_OP_regx = 0x90, 129 DW_OP_fbreg = 0x91, 130 DW_OP_bregx = 0x92, 131 DW_OP_piece = 0x93, 132 DW_OP_deref_size = 0x94, 133 DW_OP_xderef_size = 0x95, 134 DW_OP_nop = 0x96, 135 DW_OP_push_object_address = 0x97, 136 DW_OP_call2 = 0x98, 137 DW_OP_call4 = 0x99, 138 DW_OP_call_ref = 0x9a, 139 DW_OP_lo_user = 0xe0, 140 DW_OP_hi_user = 0xff 141 } 142 dwarf_expr_op_t; 143 144 #define DWARF_CIE_VERSION 3 145 #define DWARF_CIE_VERSION_MAX 4 146 147 #define DWARF_CFA_OPCODE_MASK 0xc0 148 #define DWARF_CFA_OPERAND_MASK 0x3f 149 150 typedef enum 151 { 152 DW_CFA_advance_loc = 0x40, 153 DW_CFA_offset = 0x80, 154 DW_CFA_restore = 0xc0, 155 DW_CFA_nop = 0x00, 156 DW_CFA_set_loc = 0x01, 157 DW_CFA_advance_loc1 = 0x02, 158 DW_CFA_advance_loc2 = 0x03, 159 DW_CFA_advance_loc4 = 0x04, 160 DW_CFA_offset_extended = 0x05, 161 DW_CFA_restore_extended = 0x06, 162 DW_CFA_undefined = 0x07, 163 DW_CFA_same_value = 0x08, 164 DW_CFA_register = 0x09, 165 DW_CFA_remember_state = 0x0a, 166 DW_CFA_restore_state = 0x0b, 167 DW_CFA_def_cfa = 0x0c, 168 DW_CFA_def_cfa_register = 0x0d, 169 DW_CFA_def_cfa_offset = 0x0e, 170 DW_CFA_def_cfa_expression = 0x0f, 171 DW_CFA_expression = 0x10, 172 DW_CFA_offset_extended_sf = 0x11, 173 DW_CFA_def_cfa_sf = 0x12, 174 DW_CFA_def_cfa_offset_sf = 0x13, 175 DW_CFA_val_offset = 0x14, 176 DW_CFA_val_offset_sf = 0x15, 177 DW_CFA_val_expression = 0x16, 178 DW_CFA_lo_user = 0x1c, 179 DW_CFA_MIPS_advance_loc8 = 0x1d, 180 DW_CFA_GNU_window_save = 0x2d, 181 DW_CFA_GNU_args_size = 0x2e, 182 DW_CFA_GNU_negative_offset_extended = 0x2f, 183 DW_CFA_hi_user = 0x3c 184 } 185 dwarf_cfa_t; 186 187 /* DWARF Pointer-Encoding (PEs). 188 189 Pointer-Encodings were invented for the GCC exception-handling 190 support for C++, but they represent a rather generic way of 191 describing the format in which an address/pointer is stored and 192 hence we include the definitions here, in the main dwarf.h file. 193 The Pointer-Encoding format is partially documented in Linux Base 194 Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse 195 engineered from GCC. 196 197 */ 198 #define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */ 199 #define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */ 200 /* Flag bit. If set, the resulting pointer is the address of the word 201 that contains the final address. */ 202 #define DW_EH_PE_indirect 0x80 203 204 /* Pointer-encoding formats: */ 205 #define DW_EH_PE_omit 0xff 206 #define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */ 207 #define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */ 208 #define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */ 209 #define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */ 210 #define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */ 211 #define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */ 212 #define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */ 213 #define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */ 214 #define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */ 215 216 /* Pointer-encoding application: */ 217 #define DW_EH_PE_absptr 0x00 /* absolute value */ 218 #define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */ 219 #define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */ 220 #define DW_EH_PE_datarel 0x30 /* data-relative */ 221 /* The following are not documented by LSB v1.3, yet they are used by 222 GCC, presumably they aren't documented by LSB since they aren't 223 used on Linux: */ 224 #define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */ 225 #define DW_EH_PE_aligned 0x50 /* aligned pointer */ 226 227 extern struct mempool dwarf_reg_state_pool; 228 extern struct mempool dwarf_cie_info_pool; 229 230 typedef enum 231 { 232 DWARF_WHERE_UNDEF, /* register isn't saved at all */ 233 DWARF_WHERE_SAME, /* register has same value as in prev. frame */ 234 DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */ 235 DWARF_WHERE_REG, /* register saved in another register */ 236 DWARF_WHERE_EXPR, /* register saved */ 237 DWARF_WHERE_VAL_EXPR, /* register has computed value */ 238 DWARF_WHERE_VAL, /* register that is the value */ 239 } 240 dwarf_where_t; 241 242 /* For uniformity, we'd like to treat the CFA save-location like any 243 other register save-location, but this doesn't quite work, because 244 the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle 245 this, we use two dwarf_save_loc structures to describe the CFA. 246 The first one (CFA_REG_COLUMN), tells us where the CFA is saved. 247 In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF 248 location expression whose address is given by member "val". In the 249 case of DWARF_WHERE_REG, member "val" gives the number of the 250 base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives 251 the offset value. */ 252 #define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS 253 #define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1) 254 255 typedef struct dwarf_reg_only_state 256 { 257 char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */ 258 unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */ 259 } 260 dwarf_reg_only_state_t; 261 262 typedef struct dwarf_reg_state 263 { 264 unw_word_t ret_addr_column; /* which column in rule table represents return address */ 265 dwarf_reg_only_state_t reg; 266 } 267 dwarf_reg_state_t; 268 269 typedef struct dwarf_stackable_reg_state 270 { 271 struct dwarf_stackable_reg_state *next; /* for rs_stack */ 272 dwarf_reg_state_t state; 273 } 274 dwarf_stackable_reg_state_t; 275 276 typedef struct dwarf_reg_cache_entry 277 { 278 unw_word_t ip; /* ip this rs is for */ 279 unsigned short coll_chain; /* used for hash collisions */ 280 unsigned short hint; /* hint for next rs to try (or -1) */ 281 unsigned short valid : 1; /* optional machine-dependent signal info */ 282 unsigned short signal_frame : 1; /* optional machine-dependent signal info */ 283 } 284 dwarf_reg_cache_entry_t; 285 286 typedef struct dwarf_cie_info 287 { 288 unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */ 289 unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */ 290 unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */ 291 unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */ 292 unw_word_t code_align; /* code-alignment factor */ 293 unw_word_t data_align; /* data-alignment factor */ 294 unw_word_t ret_addr_column; /* column of return-address register */ 295 unw_word_t handler; /* address of personality-routine */ 296 uint16_t abi; 297 uint16_t tag; 298 uint8_t fde_encoding; 299 uint8_t lsda_encoding; 300 unsigned int sized_augmentation : 1; 301 unsigned int have_abi_marker : 1; 302 unsigned int signal_frame : 1; 303 } 304 dwarf_cie_info_t; 305 306 typedef struct dwarf_state_record 307 { 308 unsigned char fde_encoding; 309 unw_word_t args_size; 310 311 dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */ 312 dwarf_reg_state_t rs_current; /* current reg-state */ 313 } 314 dwarf_state_record_t; 315 316 typedef struct dwarf_cursor 317 { 318 void *as_arg; /* argument to address-space callbacks */ 319 unw_addr_space_t as; /* reference to per-address-space info */ 320 321 unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ 322 unw_word_t ip; /* instruction pointer */ 323 unw_word_t args_size; /* size of arguments */ 324 unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; 325 unsigned int eh_valid_mask; 326 327 dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS]; 328 329 unsigned int stash_frames :1; /* stash frames for fast lookup */ 330 unsigned int use_prev_instr :1; /* use previous (= call) or current (= signal) instruction? */ 331 unsigned int pi_valid :1; /* is proc_info valid? */ 332 unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ 333 unw_proc_info_t pi; /* info about current procedure */ 334 335 short hint; /* faster lookup of the rs cache */ 336 short prev_rs; 337 unw_word_t rel_pc; /* pc related to the beginning of the elf, used for addr2line */ 338 unw_word_t cached_ip; /* cached instruction pointer */ 339 struct map_info *cached_map; /* memory mapping info associated with cached ip */ 340 // allow us set unwind context 341 int index; 342 int reg_sz; 343 unw_word_t ctx[DWARF_NUM_PRESERVED_REGS]; 344 unw_word_t fp; /* frame-pointer */ 345 } 346 dwarf_cursor_t; 347 348 #define DWARF_DEFAULT_LOG_UNW_CACHE_SIZE 7 349 #define DWARF_DEFAULT_UNW_CACHE_SIZE (1 << DWARF_DEFAULT_LOG_UNW_CACHE_SIZE) 350 351 #define DWARF_DEFAULT_LOG_UNW_HASH_SIZE (DWARF_DEFAULT_LOG_UNW_CACHE_SIZE + 1) 352 #define DWARF_DEFAULT_UNW_HASH_SIZE (1 << DWARF_DEFAULT_LOG_UNW_HASH_SIZE) 353 354 typedef unsigned char unw_hash_index_t; 355 356 struct dwarf_rs_cache 357 { 358 pthread_mutex_t lock; 359 unsigned short rr_head; /* index of least-recently allocated rs */ 360 361 unsigned short log_size; 362 unsigned short prev_log_size; 363 364 /* hash table that maps instruction pointer to rs index: */ 365 unsigned short *hash; 366 367 _Atomic uint32_t generation; /* generation number */ 368 369 /* rs cache: */ 370 dwarf_reg_state_t *buckets; 371 dwarf_reg_cache_entry_t *links; 372 373 /* default memory, loaded in BSS segment */ 374 unsigned short default_hash[DWARF_DEFAULT_UNW_HASH_SIZE]; 375 dwarf_reg_state_t default_buckets[DWARF_DEFAULT_UNW_CACHE_SIZE]; 376 dwarf_reg_cache_entry_t default_links[DWARF_DEFAULT_UNW_CACHE_SIZE]; 377 }; 378 379 /* A list of descriptors for loaded .debug_frame sections. */ 380 381 struct unw_debug_frame_list 382 { 383 /* The start (inclusive) and end (exclusive) of the described region. */ 384 unw_word_t start; 385 unw_word_t end; 386 /* ELF load offset */ 387 unw_word_t load_offset; 388 /* The debug frame itself. */ 389 char *debug_frame; 390 size_t debug_frame_size; 391 /* Index (for binary search). */ 392 struct table_entry *index; 393 size_t index_size; 394 /* Pointer to next descriptor. */ 395 struct unw_debug_frame_list *next; 396 }; 397 398 /* Convenience macros: */ 399 #define dwarf_init UNW_ARCH_OBJ (dwarf_init) 400 #define dwarf_callback UNW_OBJ (dwarf_callback) 401 #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info) 402 #define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame) 403 #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table) 404 #define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table) 405 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) 406 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info) 407 #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr) 408 #define dwarf_stack_aligned UNW_OBJ (dwarf_stack_aligned) 409 #define dwarf_extract_proc_info_from_fde \ 410 UNW_OBJ (dwarf_extract_proc_info_from_fde) 411 #define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs) 412 #define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info) 413 #define dwarf_apply_reg_state UNW_OBJ (dwarf_apply_reg_state) 414 #define dwarf_reg_states_iterate UNW_OBJ (dwarf_reg_states_iterate) 415 #define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer) 416 #define dwarf_step UNW_OBJ (dwarf_step) 417 #define dwarf_flush_rs_cache UNW_OBJ (dwarf_flush_rs_cache) 418 419 extern int dwarf_init (void); 420 #ifndef UNW_REMOTE_ONLY 421 extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr); 422 extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, 423 unw_proc_info_t *pi, 424 int need_unwind_info, void *arg); 425 #endif /* !UNW_REMOTE_ONLY */ 426 extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, 427 unw_word_t ip, unw_word_t segbase, 428 const char* obj_name, unw_word_t start, 429 unw_word_t end); 430 extern int dwarf_search_unwind_table (unw_addr_space_t as, 431 unw_word_t ip, 432 unw_dyn_info_t *di, 433 unw_proc_info_t *pi, 434 int need_unwind_info, void *arg); 435 /* Add For Cache MAP And ELF */ 436 extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei, 437 unw_addr_space_t as, char *path, 438 unw_word_t segbase, unw_word_t mapoff, 439 unw_word_t ip); 440 /* Add For Cache MAP And ELF */ 441 extern void dwarf_put_unwind_info (unw_addr_space_t as, 442 unw_proc_info_t *pi, void *arg); 443 extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, 444 unw_word_t len, unw_word_t *valp, 445 int *is_register); 446 extern int 447 dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, 448 unw_word_t rbp_addr, unw_word_t *offset); 449 450 extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as, 451 unw_accessors_t *a, 452 unw_word_t *fde_addr, 453 unw_proc_info_t *pi, 454 unw_word_t base, 455 int need_unwind_info, 456 int is_debug_frame, 457 void *arg); 458 extern int dwarf_find_save_locs (struct dwarf_cursor *c); 459 extern int dwarf_make_proc_info (struct dwarf_cursor *c); 460 extern int dwarf_apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs); 461 extern int dwarf_reg_states_iterate (struct dwarf_cursor *c, unw_reg_states_callback cb, void *token); 462 extern int dwarf_read_encoded_pointer (unw_addr_space_t as, 463 unw_accessors_t *a, 464 unw_word_t *addr, 465 unsigned char encoding, 466 const unw_proc_info_t *pi, 467 unw_word_t *valp, void *arg); 468 extern int dwarf_step (struct dwarf_cursor *c); 469 extern int dwarf_flush_rs_cache (struct dwarf_rs_cache *cache); 470 471 #endif /* dwarf_h */ 472