Home | History | Annotate | Download | only in libdw
      1 /* Internal definitions for libdw CFI interpreter.
      2    Copyright (C) 2009-2010, 2013 Red Hat, Inc.
      3    This file is part of elfutils.
      4 
      5    This file is free software; you can redistribute it and/or modify
      6    it under the terms of either
      7 
      8      * the GNU Lesser General Public License as published by the Free
      9        Software Foundation; either version 3 of the License, or (at
     10        your option) any later version
     11 
     12    or
     13 
     14      * the GNU General Public License as published by the Free
     15        Software Foundation; either version 2 of the License, or (at
     16        your option) any later version
     17 
     18    or both in parallel, as here.
     19 
     20    elfutils is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received copies of the GNU General Public License and
     26    the GNU Lesser General Public License along with this program.  If
     27    not, see <http://www.gnu.org/licenses/>.  */
     28 
     29 #ifndef _UNWINDP_H
     30 #define _UNWINDP_H 1
     31 
     32 #include "libdwP.h"
     33 #include "libelfP.h"
     34 struct ebl;
     35 
     36 /* Cached CIE representation.  */
     37 struct dwarf_cie
     38 {
     39   Dwarf_Off offset;	 /* Our position, as seen in FDEs' CIE_pointer.  */
     40 
     41   Dwarf_Word code_alignment_factor;
     42   Dwarf_Sword data_alignment_factor;
     43   Dwarf_Word return_address_register;
     44 
     45   size_t fde_augmentation_data_size;
     46 
     47   // play out to initial state
     48   const uint8_t *initial_instructions;
     49   const uint8_t *initial_instructions_end;
     50 
     51   const Dwarf_Frame *initial_state;
     52 
     53   uint8_t fde_encoding;		/* DW_EH_PE_* for addresses in FDEs.  */
     54   uint8_t lsda_encoding;    /* DW_EH_PE_* for LSDA in FDE augmentation.  */
     55 
     56   bool sized_augmentation_data;	/* Saw 'z': FDEs have self-sized data.  */
     57   bool signal_frame;		/* Saw 'S': FDE is for a signal frame.  */
     58 };
     59 
     60 /* Cached FDE representation.  */
     61 struct dwarf_fde
     62 {
     63   struct dwarf_cie *cie;
     64 
     65   /* This FDE describes PC values in [start, end).  */
     66   Dwarf_Addr start;
     67   Dwarf_Addr end;
     68 
     69   const uint8_t *instructions;
     70   const uint8_t *instructions_end;
     71 };
     72 
     73 /* This holds everything we cache about the CFI from each ELF file's
     74    .debug_frame or .eh_frame section.  */
     75 struct Dwarf_CFI_s
     76 {
     77   /* Dwarf handle we came from.  If null, this is .eh_frame data.  */
     78   Dwarf *dbg;
     79 #define CFI_IS_EH(cfi)	((cfi)->dbg == NULL)
     80 
     81   /* Data of the .debug_frame or .eh_frame section.  */
     82   Elf_Data_Scn *data;
     83   const unsigned char *e_ident;	/* For EI_DATA and EI_CLASS.  */
     84 
     85   Dwarf_Addr frame_vaddr;  /* DW_EH_PE_pcrel, address of frame section.  */
     86   Dwarf_Addr textrel;		/* DW_EH_PE_textrel base address.  */
     87   Dwarf_Addr datarel;		/* DW_EH_PE_datarel base address.  */
     88 
     89   /* Location of next unread entry in the section.  */
     90   Dwarf_Off next_offset;
     91 
     92   /* Search tree for the CIEs, indexed by CIE_pointer (section offset).  */
     93   void *cie_tree;
     94 
     95   /* Search tree for the FDEs, indexed by PC address.  */
     96   void *fde_tree;
     97 
     98   /* Search tree for parsed DWARF expressions, indexed by raw pointer.  */
     99   void *expr_tree;
    100 
    101   /* Backend hook.  */
    102   struct ebl *ebl;
    103 
    104   /* Binary search table in .eh_frame_hdr section.  */
    105   const uint8_t *search_table;
    106   Dwarf_Addr search_table_vaddr;
    107   size_t search_table_entries;
    108   uint8_t search_table_encoding;
    109 
    110   /* True if the file has a byte order different from the host.  */
    111   bool other_byte_order;
    112 
    113   /* Default rule for registers not previously mentioned
    114      is same_value, not undefined.  */
    115   bool default_same_value;
    116 };
    117 
    118 
    119 enum dwarf_frame_rule
    120   {
    121     reg_unspecified,		/* Uninitialized state.  */
    122     reg_undefined,		/* DW_CFA_undefined */
    123     reg_same_value,		/* DW_CFA_same_value */
    124     reg_offset,			/* DW_CFA_offset_extended et al */
    125     reg_val_offset,		/* DW_CFA_val_offset et al */
    126     reg_register,		/* DW_CFA_register */
    127     reg_expression,		/* DW_CFA_expression */
    128     reg_val_expression,		/* DW_CFA_val_expression */
    129   };
    130 
    131 /* This describes what we know about an individual register.  */
    132 struct dwarf_frame_register
    133 {
    134   enum dwarf_frame_rule rule:3;
    135 
    136   /* The meaning of the value bits depends on the rule:
    137 
    138 	Rule			Value
    139 	----			-----
    140 	undefined		unused
    141 	same_value		unused
    142 	offset(N)		N	(register saved at CFA + value)
    143 	val_offset(N)		N	(register = CFA + value)
    144 	register(R)		R	(register = register #value)
    145 	expression(E)		section offset of DW_FORM_block containing E
    146 					(register saved at address E computes)
    147 	val_expression(E)	section offset of DW_FORM_block containing E
    148 					(register = value E computes)
    149   */
    150   Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3);
    151 };
    152 
    153 /* This holds instructions for unwinding frame at a particular PC location
    154    described by an FDE.  */
    155 struct Dwarf_Frame_s
    156 {
    157   /* This frame description covers PC values in [start, end).  */
    158   Dwarf_Addr start;
    159   Dwarf_Addr end;
    160 
    161   Dwarf_CFI *cache;
    162 
    163   /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state,
    164      or NULL in an initial_state pseudo-frame.  */
    165   Dwarf_Frame *prev;
    166 
    167   /* The FDE that generated this frame state.  This points to its CIE,
    168      which has the return_address_register and signal_frame flag.  */
    169   struct dwarf_fde *fde;
    170 
    171   /* The CFA is unknown, is R+N, or is computed by a DWARF expression.
    172      A bogon in the CFI can indicate an invalid/incalculable rule.
    173      We store that as cfa_invalid rather than barfing when processing it,
    174      so callers can ignore the bogon unless they really need that CFA.  */
    175   enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule;
    176   union
    177   {
    178     Dwarf_Op offset;
    179     Dwarf_Block expr;
    180   } cfa_data;
    181   /* We store an offset rule as a DW_OP_bregx operation.  */
    182 #define cfa_val_reg	cfa_data.offset.number
    183 #define cfa_val_offset	cfa_data.offset.number2
    184 
    185   size_t nregs;
    186   struct dwarf_frame_register regs[];
    187 };
    188 
    189 
    190 /* Clean up the data structure and all it points to.  */
    191 extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
    192   __nonnull_attribute__ (1) internal_function;
    193 
    194 /* Enter a CIE encountered while reading through for FDEs.  */
    195 extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset,
    196 				const Dwarf_CIE *info)
    197   __nonnull_attribute__ (1, 3) internal_function;
    198 
    199 /* Look up a CIE_pointer for random access.  */
    200 extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
    201   __nonnull_attribute__ (1) internal_function;
    202 
    203 
    204 /* Look for an FDE covering the given PC address.  */
    205 extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache,
    206 					   Dwarf_Addr address)
    207   __nonnull_attribute__ (1) internal_function;
    208 
    209 /* Look for an FDE by its offset in the section.  */
    210 extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache,
    211 						Dwarf_Off offset)
    212   __nonnull_attribute__ (1) internal_function;
    213 
    214 /* Process the FDE that contains the given PC address,
    215    to yield the frame state when stopped there.
    216    The return value is a DWARF_E_* error code.  */
    217 extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
    218 				     Dwarf_Addr address, Dwarf_Frame **frame)
    219   __nonnull_attribute__ (1, 2, 4) internal_function;
    220 
    221 
    222 /* Dummy struct for memory-access.h macros.  */
    223 #define BYTE_ORDER_DUMMY(var, e_ident)					      \
    224   const struct { bool other_byte_order; } var =				      \
    225     { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB)       \
    226        || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) }
    227 
    228 
    229 INTDECL (dwarf_next_cfi)
    230 INTDECL (dwarf_getcfi)
    231 INTDECL (dwarf_getcfi_elf)
    232 INTDECL (dwarf_cfi_end)
    233 INTDECL (dwarf_cfi_addrframe)
    234 
    235 #endif	/* unwindP.h */
    236