Home | History | Annotate | Download | only in include
      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 (at) 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 /* ANDROID support update. */
     34 struct elf_image;
     35 
     36 #ifdef HAVE_CONFIG_H
     37 # include "config.h"
     38 #endif
     39 
     40 #include "dwarf-config.h"
     41 /* End of ANDROID update. */
     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 
     57 typedef 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   }
    139 dwarf_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 
    146 typedef 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   }
    178 dwarf_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 
    220 extern struct mempool dwarf_reg_state_pool;
    221 extern struct mempool dwarf_cie_info_pool;
    222 
    223 typedef 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   }
    231 dwarf_where_t;
    232 
    233 typedef struct
    234   {
    235     dwarf_where_t where;	/* how is the register saved? */
    236     unw_word_t val;		/* where it's saved */
    237   }
    238 dwarf_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 
    253 typedef 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   }
    265 dwarf_reg_state_t;
    266 
    267 typedef 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   }
    285 dwarf_cie_info_t;
    286 
    287 typedef 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   }
    295 dwarf_state_record_t;
    296 
    297 typedef 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   }
    323 dwarf_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 
    331 typedef unsigned char unw_hash_index_t;
    332 
    333 struct 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 
    350 struct 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     /* Relocation amount since debug_frame was compressed. */
    359     unw_word_t segbase_bias;
    360     /* Index (for binary search).  */
    361     struct table_entry *index;
    362     size_t index_size;
    363     /* Pointer to next descriptor.  */
    364     struct unw_debug_frame_list *next;
    365   };
    366 
    367 struct dwarf_callback_data
    368   {
    369     /* in: */
    370     unw_word_t ip;		/* instruction-pointer we're looking for */
    371     unw_proc_info_t *pi;	/* proc-info pointer */
    372     int need_unwind_info;
    373     /* out: */
    374     int single_fde;		/* did we find a single FDE? (vs. a table) */
    375     unw_dyn_info_t di;		/* table info (if single_fde is false) */
    376     unw_dyn_info_t di_debug;	/* additional table info for .debug_frame */
    377   };
    378 
    379 /* Convenience macros: */
    380 #define dwarf_init			UNW_ARCH_OBJ (dwarf_init)
    381 #define dwarf_callback			UNW_OBJ (dwarf_callback)
    382 #define dwarf_find_proc_info		UNW_OBJ (dwarf_find_proc_info)
    383 #define dwarf_find_debug_frame		UNW_OBJ (dwarf_find_debug_frame)
    384 #define dwarf_search_unwind_table	UNW_OBJ (dwarf_search_unwind_table)
    385 #define dwarf_find_unwind_table		UNW_OBJ (dwarf_find_unwind_table)
    386 #define dwarf_put_unwind_info		UNW_OBJ (dwarf_put_unwind_info)
    387 #define dwarf_put_unwind_info		UNW_OBJ (dwarf_put_unwind_info)
    388 #define dwarf_eval_expr			UNW_OBJ (dwarf_eval_expr)
    389 #define dwarf_extract_proc_info_from_fde \
    390 		UNW_OBJ (dwarf_extract_proc_info_from_fde)
    391 #define dwarf_find_save_locs		UNW_OBJ (dwarf_find_save_locs)
    392 #define dwarf_create_state_record	UNW_OBJ (dwarf_create_state_record)
    393 #define dwarf_make_proc_info		UNW_OBJ (dwarf_make_proc_info)
    394 #define dwarf_read_encoded_pointer	UNW_OBJ (dwarf_read_encoded_pointer)
    395 #define dwarf_step			UNW_OBJ (dwarf_step)
    396 
    397 extern int dwarf_init (void);
    398 #ifndef UNW_REMOTE_ONLY
    399 extern int dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr);
    400 extern int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
    401 				 unw_proc_info_t *pi,
    402 				 int need_unwind_info, void *arg);
    403 #endif /* !UNW_REMOTE_ONLY */
    404 extern int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug,
    405 				   unw_word_t ip, unw_word_t segbase,
    406 				   const char* obj_name, unw_word_t start,
    407 				   unw_word_t end);
    408 extern int dwarf_search_unwind_table (unw_addr_space_t as,
    409 				      unw_word_t ip,
    410 				      unw_dyn_info_t *di,
    411 				      unw_proc_info_t *pi,
    412 				      int need_unwind_info, void *arg);
    413 /* ANDROID support update. */
    414 extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
    415 				    unw_addr_space_t as, char *path,
    416 				    unw_word_t segbase, unw_word_t mapoff,
    417 				    unw_word_t ip);
    418 /* End of ANDROID update. */
    419 extern void dwarf_put_unwind_info (unw_addr_space_t as,
    420 				   unw_proc_info_t *pi, void *arg);
    421 extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
    422 			    unw_word_t len, unw_word_t *valp,
    423 			    int *is_register);
    424 extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
    425 					     unw_accessors_t *a,
    426 					     unw_word_t *fde_addr,
    427 					     unw_proc_info_t *pi,
    428 					     int need_unwind_info,
    429 					     unw_word_t base,
    430 					     void *arg);
    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,
    436 				       unw_accessors_t *a,
    437 				       unw_word_t *addr,
    438 				       unsigned char encoding,
    439 				       const unw_proc_info_t *pi,
    440 				       unw_word_t *valp, void *arg);
    441 extern int dwarf_step (struct dwarf_cursor *c);
    442 
    443 #endif /* dwarf_h */
    444