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