Protect against some memory leaks
[platform/upstream/libunwind.git] / include / dwarf.h
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
31 struct dwarf_cursor;    /* forward-declaration */
32 struct elf_dyn_info;
33
34 #include "dwarf-config.h"
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
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 #ifndef UNW_REMOTE_ONLY
48   #if defined(HAVE_LINK_H)
49     #include <link.h>
50   #elif defined(HAVE_SYS_LINK_H)
51     #include <sys/link.h>
52   #else
53     #error Could not find <link.h>
54   #endif
55 #endif
56
57 #include <pthread.h>
58
59 /* DWARF expression opcodes.  */
60
61 typedef enum
62   {
63     DW_OP_addr                  = 0x03,
64     DW_OP_deref                 = 0x06,
65     DW_OP_const1u               = 0x08,
66     DW_OP_const1s               = 0x09,
67     DW_OP_const2u               = 0x0a,
68     DW_OP_const2s               = 0x0b,
69     DW_OP_const4u               = 0x0c,
70     DW_OP_const4s               = 0x0d,
71     DW_OP_const8u               = 0x0e,
72     DW_OP_const8s               = 0x0f,
73     DW_OP_constu                = 0x10,
74     DW_OP_consts                = 0x11,
75     DW_OP_dup                   = 0x12,
76     DW_OP_drop                  = 0x13,
77     DW_OP_over                  = 0x14,
78     DW_OP_pick                  = 0x15,
79     DW_OP_swap                  = 0x16,
80     DW_OP_rot                   = 0x17,
81     DW_OP_xderef                = 0x18,
82     DW_OP_abs                   = 0x19,
83     DW_OP_and                   = 0x1a,
84     DW_OP_div                   = 0x1b,
85     DW_OP_minus                 = 0x1c,
86     DW_OP_mod                   = 0x1d,
87     DW_OP_mul                   = 0x1e,
88     DW_OP_neg                   = 0x1f,
89     DW_OP_not                   = 0x20,
90     DW_OP_or                    = 0x21,
91     DW_OP_plus                  = 0x22,
92     DW_OP_plus_uconst           = 0x23,
93     DW_OP_shl                   = 0x24,
94     DW_OP_shr                   = 0x25,
95     DW_OP_shra                  = 0x26,
96     DW_OP_xor                   = 0x27,
97     DW_OP_skip                  = 0x2f,
98     DW_OP_bra                   = 0x28,
99     DW_OP_eq                    = 0x29,
100     DW_OP_ge                    = 0x2a,
101     DW_OP_gt                    = 0x2b,
102     DW_OP_le                    = 0x2c,
103     DW_OP_lt                    = 0x2d,
104     DW_OP_ne                    = 0x2e,
105     DW_OP_lit0                  = 0x30,
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,
112     DW_OP_lit31,
113     DW_OP_reg0                  = 0x50,
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,
120     DW_OP_reg31,
121     DW_OP_breg0                 = 0x70,
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,
128     DW_OP_breg31,
129     DW_OP_regx                  = 0x90,
130     DW_OP_fbreg                 = 0x91,
131     DW_OP_bregx                 = 0x92,
132     DW_OP_piece                 = 0x93,
133     DW_OP_deref_size            = 0x94,
134     DW_OP_xderef_size           = 0x95,
135     DW_OP_nop                   = 0x96,
136     DW_OP_push_object_address   = 0x97,
137     DW_OP_call2                 = 0x98,
138     DW_OP_call4                 = 0x99,
139     DW_OP_call_ref              = 0x9a,
140     DW_OP_lo_user               = 0xe0,
141     DW_OP_hi_user               = 0xff
142   }
143 dwarf_expr_op_t;
144
145 #define DWARF_CIE_VERSION       3       /* GCC emits version 1??? */
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_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
182   }
183 dwarf_cfa_t;
184
185 /* DWARF Pointer-Encoding (PEs).
186
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
193    engineered from GCC.
194
195 */
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
201
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 */
213
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
221    used on Linux:  */
222 #define DW_EH_PE_funcrel        0x40    /* start-of-procedure-relative */
223 #define DW_EH_PE_aligned        0x50    /* aligned pointer */
224
225 extern struct mempool dwarf_reg_state_pool;
226 extern struct mempool dwarf_cie_info_pool;
227
228 typedef enum
229   {
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 */
236   }
237 dwarf_where_t;
238
239 typedef struct
240   {
241     dwarf_where_t where;        /* how is the register saved? */
242     unw_word_t val;             /* where it's saved */
243   }
244 dwarf_save_loc_t;
245
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
255    the offset value.  */
256 #define DWARF_CFA_REG_COLUMN    DWARF_NUM_PRESERVED_REGS
257 #define DWARF_CFA_OFF_COLUMN    (DWARF_NUM_PRESERVED_REGS + 1)
258
259 typedef struct dwarf_reg_state
260   {
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 */
270   }
271 dwarf_reg_state_t;
272
273 typedef struct dwarf_cie_info
274   {
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 */
283     uint16_t abi;
284     uint16_t tag;
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;
290   }
291 dwarf_cie_info_t;
292
293 typedef struct dwarf_state_record
294   {
295     unsigned char fde_encoding;
296     unw_word_t args_size;
297
298     dwarf_reg_state_t rs_initial;       /* reg-state after CIE instructions */
299     dwarf_reg_state_t rs_current;       /* current reg-state */
300   }
301 dwarf_state_record_t;
302
303 typedef struct dwarf_cursor
304   {
305     void *as_arg;               /* argument to address-space callbacks */
306     unw_addr_space_t as;        /* reference to per-address-space info */
307
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;
314
315     dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS];
316
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 */
322
323     short hint; /* faster lookup of the rs cache */
324     short prev_rs;
325   }
326 dwarf_cursor_t;
327
328 #define DWARF_LOG_UNW_CACHE_SIZE        7
329 #define DWARF_UNW_CACHE_SIZE    (1 << DWARF_LOG_UNW_CACHE_SIZE)
330
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)
333
334 typedef unsigned char unw_hash_index_t;
335
336 struct dwarf_rs_cache
337   {
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 */
341
342     /* hash table that maps instruction pointer to rs index: */
343     unsigned short hash[DWARF_UNW_HASH_SIZE];
344
345     uint32_t generation;        /* generation number */
346
347     /* rs cache: */
348     dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE];
349   };
350
351 /* A list of descriptors for loaded .debug_frame sections.  */
352
353 struct unw_debug_frame_list
354   {
355     /* The start (inclusive) and end (exclusive) of the described region.  */
356     unw_word_t start;
357     unw_word_t end;
358     /* The debug frame itself.  */
359     char *debug_frame;
360     size_t debug_frame_size;
361     /* Index (for binary search).  */
362     struct table_entry *index;
363     size_t index_size;
364     /* Pointer to next descriptor.  */
365     struct unw_debug_frame_list *next;
366   };
367
368 struct dwarf_callback_data
369   {
370     /* in: */
371     unw_word_t ip;              /* instruction-pointer we're looking for */
372     unw_proc_info_t *pi;        /* proc-info pointer */
373     int need_unwind_info;
374     /* out: */
375     int single_fde;             /* did we find a single FDE? (vs. a table) */
376     unw_dyn_info_t di;          /* table info (if single_fde is false) */
377     unw_dyn_info_t di_debug;    /* additional table info for .debug_frame */
378   };
379
380 /* Convenience macros: */
381 #define dwarf_init                      UNW_ARCH_OBJ (dwarf_init)
382 #define dwarf_callback                  UNW_OBJ (dwarf_callback)
383 #define dwarf_find_proc_info            UNW_OBJ (dwarf_find_proc_info)
384 #define dwarf_find_debug_frame          UNW_OBJ (dwarf_find_debug_frame)
385 #define dwarf_search_unwind_table       UNW_OBJ (dwarf_search_unwind_table)
386 #define dwarf_find_unwind_table         UNW_OBJ (dwarf_find_unwind_table)
387 #define dwarf_put_unwind_info           UNW_OBJ (dwarf_put_unwind_info)
388 #define dwarf_put_unwind_info           UNW_OBJ (dwarf_put_unwind_info)
389 #define dwarf_eval_expr                 UNW_OBJ (dwarf_eval_expr)
390 #define dwarf_extract_proc_info_from_fde \
391                 UNW_OBJ (dwarf_extract_proc_info_from_fde)
392 #define dwarf_find_save_locs            UNW_OBJ (dwarf_find_save_locs)
393 #define dwarf_create_state_record       UNW_OBJ (dwarf_create_state_record)
394 #define dwarf_make_proc_info            UNW_OBJ (dwarf_make_proc_info)
395 #define dwarf_read_encoded_pointer      UNW_OBJ (dwarf_read_encoded_pointer)
396 #define dwarf_step                      UNW_OBJ (dwarf_step)
397
398 extern int dwarf_init (void);
399 #ifndef UNW_REMOTE_ONLY
400 extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr);
401 extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
402                                  unw_proc_info_t *pi,
403                                  int need_unwind_info, void *arg);
404 #endif /* !UNW_REMOTE_ONLY */
405 extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
406                                    unw_word_t ip, unw_word_t segbase,
407                                    const char* obj_name, unw_word_t start,
408                                    unw_word_t end);
409 extern int dwarf_search_unwind_table (unw_addr_space_t as,
410                                       unw_word_t ip,
411                                       unw_dyn_info_t *di,
412                                       unw_proc_info_t *pi,
413                                       int need_unwind_info, void *arg);
414 extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
415                                     char *path, unw_word_t segbase, unw_word_t mapoff,
416                                     unw_word_t ip);
417 extern void dwarf_put_unwind_info (unw_addr_space_t as,
418                                    unw_proc_info_t *pi, void *arg);
419 extern 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);
422 extern 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                                              unw_word_t base,
427                                              int need_unwind_info,
428                                              int is_debug_frame,
429                                              void *arg);
430 extern int dwarf_find_save_locs (struct dwarf_cursor *c);
431 extern int dwarf_create_state_record (struct dwarf_cursor *c,
432                                       dwarf_state_record_t *sr);
433 extern int dwarf_make_proc_info (struct dwarf_cursor *c);
434 extern int dwarf_read_encoded_pointer (unw_addr_space_t as,
435                                        unw_accessors_t *a,
436                                        unw_word_t *addr,
437                                        unsigned char encoding,
438                                        const unw_proc_info_t *pi,
439                                        unw_word_t *valp, void *arg);
440 extern int dwarf_step (struct dwarf_cursor *c);
441
442 #endif /* dwarf_h */