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>
5 This file is part of libunwind.
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:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
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. */
29 #include <libunwind.h>
31 struct dwarf_cursor
; /* forward-declaration */
34 #include "dwarf-config.h"
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
47 #ifndef UNW_REMOTE_ONLY
48 #if defined(HAVE_LINK_H)
50 #elif defined(HAVE_SYS_LINK_H)
53 #error Could not find <link.h>
59 /* DWARF expression opcodes. */
92 DW_OP_plus_uconst
= 0x23,
106 DW_OP_lit1
, DW_OP_lit2
, DW_OP_lit3
, DW_OP_lit4
, DW_OP_lit5
,
107 DW_OP_lit6
, DW_OP_lit7
, DW_OP_lit8
, DW_OP_lit9
, DW_OP_lit10
,
108 DW_OP_lit11
, DW_OP_lit12
, DW_OP_lit13
, DW_OP_lit14
, DW_OP_lit15
,
109 DW_OP_lit16
, DW_OP_lit17
, DW_OP_lit18
, DW_OP_lit19
, DW_OP_lit20
,
110 DW_OP_lit21
, DW_OP_lit22
, DW_OP_lit23
, DW_OP_lit24
, DW_OP_lit25
,
111 DW_OP_lit26
, DW_OP_lit27
, DW_OP_lit28
, DW_OP_lit29
, DW_OP_lit30
,
114 DW_OP_reg1
, DW_OP_reg2
, DW_OP_reg3
, DW_OP_reg4
, DW_OP_reg5
,
115 DW_OP_reg6
, DW_OP_reg7
, DW_OP_reg8
, DW_OP_reg9
, DW_OP_reg10
,
116 DW_OP_reg11
, DW_OP_reg12
, DW_OP_reg13
, DW_OP_reg14
, DW_OP_reg15
,
117 DW_OP_reg16
, DW_OP_reg17
, DW_OP_reg18
, DW_OP_reg19
, DW_OP_reg20
,
118 DW_OP_reg21
, DW_OP_reg22
, DW_OP_reg23
, DW_OP_reg24
, DW_OP_reg25
,
119 DW_OP_reg26
, DW_OP_reg27
, DW_OP_reg28
, DW_OP_reg29
, DW_OP_reg30
,
122 DW_OP_breg1
, DW_OP_breg2
, DW_OP_breg3
, DW_OP_breg4
, DW_OP_breg5
,
123 DW_OP_breg6
, DW_OP_breg7
, DW_OP_breg8
, DW_OP_breg9
, DW_OP_breg10
,
124 DW_OP_breg11
, DW_OP_breg12
, DW_OP_breg13
, DW_OP_breg14
, DW_OP_breg15
,
125 DW_OP_breg16
, DW_OP_breg17
, DW_OP_breg18
, DW_OP_breg19
, DW_OP_breg20
,
126 DW_OP_breg21
, DW_OP_breg22
, DW_OP_breg23
, DW_OP_breg24
, DW_OP_breg25
,
127 DW_OP_breg26
, DW_OP_breg27
, DW_OP_breg28
, DW_OP_breg29
, DW_OP_breg30
,
133 DW_OP_deref_size
= 0x94,
134 DW_OP_xderef_size
= 0x95,
136 DW_OP_push_object_address
= 0x97,
139 DW_OP_call_ref
= 0x9a,
140 DW_OP_lo_user
= 0xe0,
145 #define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */
147 #define DWARF_CFA_OPCODE_MASK 0xc0
148 #define DWARF_CFA_OPERAND_MASK 0x3f
152 DW_CFA_advance_loc
= 0x40,
153 DW_CFA_offset
= 0x80,
154 DW_CFA_restore
= 0xc0,
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_expression
= 0x16,
176 DW_CFA_lo_user
= 0x1c,
177 DW_CFA_MIPS_advance_loc8
= 0x1d,
178 DW_CFA_GNU_window_save
= 0x2d,
179 DW_CFA_GNU_args_size
= 0x2e,
180 DW_CFA_GNU_negative_offset_extended
= 0x2f,
181 DW_CFA_hi_user
= 0x3c
185 /* DWARF Pointer-Encoding (PEs).
187 Pointer-Encodings were invented for the GCC exception-handling
188 support for C++, but they represent a rather generic way of
189 describing the format in which an address/pointer is stored and
190 hence we include the definitions here, in the main dwarf.h file.
191 The Pointer-Encoding format is partially documented in Linux Base
192 Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse
196 #define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
197 #define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
198 /* Flag bit. If set, the resulting pointer is the address of the word
199 that contains the final address. */
200 #define DW_EH_PE_indirect 0x80
202 /* Pointer-encoding formats: */
203 #define DW_EH_PE_omit 0xff
204 #define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
205 #define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */
206 #define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */
207 #define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
208 #define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
209 #define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */
210 #define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */
211 #define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
212 #define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
214 /* Pointer-encoding application: */
215 #define DW_EH_PE_absptr 0x00 /* absolute value */
216 #define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
217 #define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */
218 #define DW_EH_PE_datarel 0x30 /* data-relative */
219 /* The following are not documented by LSB v1.3, yet they are used by
220 GCC, presumably they aren't documented by LSB since they aren't
222 #define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
223 #define DW_EH_PE_aligned 0x50 /* aligned pointer */
225 extern struct mempool dwarf_reg_state_pool
;
226 extern struct mempool dwarf_cie_info_pool
;
230 DWARF_WHERE_UNDEF
, /* register isn't saved at all */
231 DWARF_WHERE_SAME
, /* register has same value as in prev. frame */
232 DWARF_WHERE_CFAREL
, /* register saved at CFA-relative address */
233 DWARF_WHERE_REG
, /* register saved in another register */
234 DWARF_WHERE_EXPR
, /* register saved */
235 DWARF_WHERE_VAL_EXPR
, /* register has computed value */
241 dwarf_where_t where
; /* how is the register saved? */
242 unw_word_t val
; /* where it's saved */
246 /* For uniformity, we'd like to treat the CFA save-location like any
247 other register save-location, but this doesn't quite work, because
248 the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle
249 this, we use two dwarf_save_loc structures to describe the CFA.
250 The first one (CFA_REG_COLUMN), tells us where the CFA is saved.
251 In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF
252 location expression whose address is given by member "val". In the
253 case of DWARF_WHERE_REG, member "val" gives the number of the
254 base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives
256 #define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
257 #define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
259 typedef struct dwarf_reg_state
261 struct dwarf_reg_state
*next
; /* for rs_stack */
262 dwarf_save_loc_t reg
[DWARF_NUM_PRESERVED_REGS
+ 2];
263 unw_word_t ip
; /* ip this rs is for */
264 unw_word_t ret_addr_column
; /* indicates which column in the rule table represents return address */
265 unsigned short lru_chain
; /* used for least-recently-used chain */
266 unsigned short coll_chain
; /* used for hash collisions */
267 unsigned short hint
; /* hint for next rs to try (or -1) */
268 unsigned short valid
: 1; /* optional machine-dependent signal info */
269 unsigned short signal_frame
: 1; /* optional machine-dependent signal info */
273 typedef struct dwarf_cie_info
275 unw_word_t cie_instr_start
; /* start addr. of CIE "initial_instructions" */
276 unw_word_t cie_instr_end
; /* end addr. of CIE "initial_instructions" */
277 unw_word_t fde_instr_start
; /* start addr. of FDE "instructions" */
278 unw_word_t fde_instr_end
; /* end addr. of FDE "instructions" */
279 unw_word_t code_align
; /* code-alignment factor */
280 unw_word_t data_align
; /* data-alignment factor */
281 unw_word_t ret_addr_column
; /* column of return-address register */
282 unw_word_t handler
; /* address of personality-routine */
285 uint8_t fde_encoding
;
286 uint8_t lsda_encoding
;
287 unsigned int sized_augmentation
: 1;
288 unsigned int have_abi_marker
: 1;
289 unsigned int signal_frame
: 1;
293 typedef struct dwarf_state_record
295 unsigned char fde_encoding
;
296 unw_word_t args_size
;
298 dwarf_reg_state_t rs_initial
; /* reg-state after CIE instructions */
299 dwarf_reg_state_t rs_current
; /* current reg-state */
301 dwarf_state_record_t
;
303 typedef struct dwarf_cursor
305 void *as_arg
; /* argument to address-space callbacks */
306 unw_addr_space_t as
; /* reference to per-address-space info */
308 unw_word_t cfa
; /* canonical frame address; aka frame-/stack-pointer */
309 unw_word_t ip
; /* instruction pointer */
310 unw_word_t args_size
; /* size of arguments */
311 unw_word_t ret_addr_column
; /* column for return-address */
312 unw_word_t eh_args
[UNW_TDEP_NUM_EH_REGS
];
313 unsigned int eh_valid_mask
;
315 dwarf_loc_t loc
[DWARF_NUM_PRESERVED_REGS
];
317 unsigned int stash_frames
:1; /* stash frames for fast lookup */
318 unsigned int use_prev_instr
:1; /* use previous (= call) or current (= signal) instruction? */
319 unsigned int pi_valid
:1; /* is proc_info valid? */
320 unsigned int pi_is_dynamic
:1; /* proc_info found via dynamic proc info? */
321 unw_proc_info_t pi
; /* info about current procedure */
323 short hint
; /* faster lookup of the rs cache */
328 #define DWARF_LOG_UNW_CACHE_SIZE 7
329 #define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE)
331 #define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1)
332 #define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE)
334 typedef unsigned char unw_hash_index_t
;
336 struct dwarf_rs_cache
338 pthread_mutex_t lock
;
339 unsigned short lru_head
; /* index of lead-recently used rs */
340 unsigned short lru_tail
; /* index of most-recently used rs */
342 /* hash table that maps instruction pointer to rs index: */
343 unsigned short hash
[DWARF_UNW_HASH_SIZE
];
345 uint32_t generation
; /* generation number */
348 dwarf_reg_state_t buckets
[DWARF_UNW_CACHE_SIZE
];
351 /* A list of descriptors for loaded .debug_frame sections. */
353 struct unw_debug_frame_list
355 /* The start (inclusive) and end (exclusive) of the described region. */
358 /* The debug frame itself. */
360 size_t debug_frame_size
;
361 /* Index (for binary search). */
362 struct table_entry
*index
;
364 /* Pointer to next descriptor. */
365 struct unw_debug_frame_list
*next
;
368 struct dwarf_callback_data
371 unw_word_t ip
; /* instruction-pointer we're looking for */
372 int need_unwind_info
;
377 unw_word_t ip_offset
;
381 /* Convenience macros: */
382 #define dwarf_init UNW_ARCH_OBJ (dwarf_init)
383 #define dwarf_callback UNW_OBJ (dwarf_callback)
384 #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
385 #define dwarf_find_debug_frame UNW_OBJ (dwarf_find_debug_frame)
386 #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table)
387 #define dwarf_find_unwind_table UNW_OBJ (dwarf_find_unwind_table)
388 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
389 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
390 #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
391 #define dwarf_extract_proc_info_from_fde \
392 UNW_OBJ (dwarf_extract_proc_info_from_fde)
393 #define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
394 #define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
395 #define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
396 #define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer)
397 #define dwarf_step UNW_OBJ (dwarf_step)
399 extern int dwarf_init (void);
400 #ifndef UNW_REMOTE_ONLY
401 extern int dwarf_callback (struct dl_phdr_info
*info
, size_t size
, void *ptr
);
402 extern int dwarf_find_proc_info (unw_addr_space_t as
, unw_word_t ip
,
404 int need_unwind_info
, void *arg
);
405 #endif /* !UNW_REMOTE_ONLY */
406 extern int dwarf_find_debug_frame (int found
, unw_dyn_info_t
*di_debug
,
407 unw_word_t ip
, unw_word_t segbase
,
408 const char* obj_name
, unw_word_t start
,
410 extern int dwarf_search_unwind_table (unw_addr_space_t as
,
414 int need_unwind_info
, void *arg
);
415 extern int dwarf_find_unwind_table (struct elf_dyn_info
*edi
, unw_addr_space_t as
,
416 char *path
, unw_word_t segbase
, unw_word_t mapoff
,
418 extern void dwarf_put_unwind_info (unw_addr_space_t as
,
419 unw_proc_info_t
*pi
, void *arg
);
420 extern int dwarf_eval_expr (struct dwarf_cursor
*c
, unw_word_t
*addr
,
421 unw_word_t len
, unw_word_t
*valp
,
423 extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as
,
425 unw_word_t
*fde_addr
,
428 int need_unwind_info
,
431 extern int dwarf_find_save_locs (struct dwarf_cursor
*c
);
432 extern int dwarf_create_state_record (struct dwarf_cursor
*c
,
433 dwarf_state_record_t
*sr
);
434 extern int dwarf_make_proc_info (struct dwarf_cursor
*c
);
435 extern int dwarf_read_encoded_pointer (unw_addr_space_t as
,
438 unsigned char encoding
,
441 unw_word_t
*valp
, void *arg
);
442 extern int dwarf_step (struct dwarf_cursor
*c
);