Blame libdw/cfi.h

Packit 032894
/* Internal definitions for libdw CFI interpreter.
Packit 032894
   Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifndef _UNWINDP_H
Packit 032894
#define _UNWINDP_H 1
Packit 032894
Packit 032894
#include "libdwP.h"
Packit 032894
#include "libelfP.h"
Packit 032894
struct ebl;
Packit 032894
Packit 032894
/* Cached CIE representation.  */
Packit 032894
struct dwarf_cie
Packit 032894
{
Packit 032894
  Dwarf_Off offset;	 /* Our position, as seen in FDEs' CIE_pointer.  */
Packit 032894
Packit 032894
  Dwarf_Word code_alignment_factor;
Packit 032894
  Dwarf_Sword data_alignment_factor;
Packit 032894
  Dwarf_Word return_address_register;
Packit 032894
Packit 032894
  size_t fde_augmentation_data_size;
Packit 032894
Packit 032894
  // play out to initial state
Packit 032894
  const uint8_t *initial_instructions;
Packit 032894
  const uint8_t *initial_instructions_end;
Packit 032894
Packit 032894
  const Dwarf_Frame *initial_state;
Packit 032894
Packit 032894
  uint8_t fde_encoding;		/* DW_EH_PE_* for addresses in FDEs.  */
Packit 032894
  uint8_t lsda_encoding;    /* DW_EH_PE_* for LSDA in FDE augmentation.  */
Packit 032894
Packit 032894
  bool sized_augmentation_data;	/* Saw 'z': FDEs have self-sized data.  */
Packit 032894
  bool signal_frame;		/* Saw 'S': FDE is for a signal frame.  */
Packit 032894
};
Packit 032894
Packit 032894
/* Cached FDE representation.  */
Packit 032894
struct dwarf_fde
Packit 032894
{
Packit 032894
  struct dwarf_cie *cie;
Packit 032894
Packit 032894
  /* This FDE describes PC values in [start, end).  */
Packit 032894
  Dwarf_Addr start;
Packit 032894
  Dwarf_Addr end;
Packit 032894
Packit 032894
  const uint8_t *instructions;
Packit 032894
  const uint8_t *instructions_end;
Packit 032894
};
Packit 032894
Packit 032894
/* This holds everything we cache about the CFI from each ELF file's
Packit 032894
   .debug_frame or .eh_frame section.  */
Packit 032894
struct Dwarf_CFI_s
Packit 032894
{
Packit 032894
  /* Dwarf handle we came from.  If null, this is .eh_frame data.  */
Packit 032894
  Dwarf *dbg;
Packit 032894
#define CFI_IS_EH(cfi)	((cfi)->dbg == NULL)
Packit 032894
Packit 032894
  /* Data of the .debug_frame or .eh_frame section.  */
Packit 032894
  Elf_Data_Scn *data;
Packit 032894
  const unsigned char *e_ident;	/* For EI_DATA and EI_CLASS.  */
Packit 032894
Packit 032894
  Dwarf_Addr frame_vaddr;  /* DW_EH_PE_pcrel, address of frame section.  */
Packit 032894
  Dwarf_Addr textrel;		/* DW_EH_PE_textrel base address.  */
Packit 032894
  Dwarf_Addr datarel;		/* DW_EH_PE_datarel base address.  */
Packit 032894
Packit 032894
  /* Location of next unread entry in the section.  */
Packit 032894
  Dwarf_Off next_offset;
Packit 032894
Packit 032894
  /* Search tree for the CIEs, indexed by CIE_pointer (section offset).  */
Packit 032894
  void *cie_tree;
Packit 032894
Packit 032894
  /* Search tree for the FDEs, indexed by PC address.  */
Packit 032894
  void *fde_tree;
Packit 032894
Packit 032894
  /* Search tree for parsed DWARF expressions, indexed by raw pointer.  */
Packit 032894
  void *expr_tree;
Packit 032894
Packit 032894
  /* Backend hook.  */
Packit 032894
  struct ebl *ebl;
Packit 032894
Packit 032894
  /* Binary search table in .eh_frame_hdr section.  */
Packit 032894
  const uint8_t *search_table;
Packit 032894
  size_t search_table_len;
Packit 032894
  Dwarf_Addr search_table_vaddr;
Packit 032894
  size_t search_table_entries;
Packit 032894
  uint8_t search_table_encoding;
Packit 032894
Packit 032894
  /* True if the file has a byte order different from the host.  */
Packit 032894
  bool other_byte_order;
Packit 032894
Packit 032894
  /* Default rule for registers not previously mentioned
Packit 032894
     is same_value, not undefined.  */
Packit 032894
  bool default_same_value;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
enum dwarf_frame_rule
Packit 032894
  {
Packit 032894
    reg_unspecified,		/* Uninitialized state.  */
Packit 032894
    reg_undefined,		/* DW_CFA_undefined */
Packit 032894
    reg_same_value,		/* DW_CFA_same_value */
Packit 032894
    reg_offset,			/* DW_CFA_offset_extended et al */
Packit 032894
    reg_val_offset,		/* DW_CFA_val_offset et al */
Packit 032894
    reg_register,		/* DW_CFA_register */
Packit 032894
    reg_expression,		/* DW_CFA_expression */
Packit 032894
    reg_val_expression,		/* DW_CFA_val_expression */
Packit 032894
  };
Packit 032894
Packit 032894
/* This describes what we know about an individual register.  */
Packit 032894
struct dwarf_frame_register
Packit 032894
{
Packit 032894
  enum dwarf_frame_rule rule:3;
Packit 032894
Packit 032894
  /* The meaning of the value bits depends on the rule:
Packit 032894
Packit 032894
	Rule			Value
Packit 032894
	----			-----
Packit 032894
	undefined		unused
Packit 032894
	same_value		unused
Packit 032894
	offset(N)		N	(register saved at CFA + value)
Packit 032894
	val_offset(N)		N	(register = CFA + value)
Packit 032894
	register(R)		R	(register = register #value)
Packit 032894
	expression(E)		section offset of DW_FORM_block containing E
Packit 032894
					(register saved at address E computes)
Packit 032894
	val_expression(E)	section offset of DW_FORM_block containing E
Packit 032894
					(register = value E computes)
Packit 032894
  */
Packit 032894
  Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3);
Packit 032894
};
Packit 032894
Packit 032894
/* This holds instructions for unwinding frame at a particular PC location
Packit 032894
   described by an FDE.  */
Packit 032894
struct Dwarf_Frame_s
Packit 032894
{
Packit 032894
  /* This frame description covers PC values in [start, end).  */
Packit 032894
  Dwarf_Addr start;
Packit 032894
  Dwarf_Addr end;
Packit 032894
Packit 032894
  Dwarf_CFI *cache;
Packit 032894
Packit 032894
  /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state,
Packit 032894
     or NULL in an initial_state pseudo-frame.  */
Packit 032894
  Dwarf_Frame *prev;
Packit 032894
Packit 032894
  /* The FDE that generated this frame state.  This points to its CIE,
Packit 032894
     which has the return_address_register and signal_frame flag.  */
Packit 032894
  struct dwarf_fde *fde;
Packit 032894
Packit 032894
  /* The CFA is unknown, is R+N, or is computed by a DWARF expression.
Packit 032894
     A bogon in the CFI can indicate an invalid/incalculable rule.
Packit 032894
     We store that as cfa_invalid rather than barfing when processing it,
Packit 032894
     so callers can ignore the bogon unless they really need that CFA.  */
Packit 032894
  enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule;
Packit 032894
  union
Packit 032894
  {
Packit 032894
    Dwarf_Op offset;
Packit 032894
    Dwarf_Block expr;
Packit 032894
  } cfa_data;
Packit 032894
  /* We store an offset rule as a DW_OP_bregx operation.  */
Packit 032894
#define cfa_val_reg	cfa_data.offset.number
Packit 032894
#define cfa_val_offset	cfa_data.offset.number2
Packit 032894
Packit 032894
  size_t nregs;
Packit 032894
  struct dwarf_frame_register regs[];
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
/* Clean up the data structure and all it points to.  */
Packit 032894
extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
Packit 032894
  __nonnull_attribute__ (1) internal_function;
Packit 032894
Packit 032894
/* Enter a CIE encountered while reading through for FDEs.  */
Packit 032894
extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset,
Packit 032894
				const Dwarf_CIE *info)
Packit 032894
  __nonnull_attribute__ (1, 3) internal_function;
Packit 032894
Packit 032894
/* Look up a CIE_pointer for random access.  */
Packit 032894
extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
Packit 032894
  __nonnull_attribute__ (1) internal_function;
Packit 032894
Packit 032894
Packit 032894
/* Look for an FDE covering the given PC address.  */
Packit 032894
extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache,
Packit 032894
					   Dwarf_Addr address)
Packit 032894
  __nonnull_attribute__ (1) internal_function;
Packit 032894
Packit 032894
/* Look for an FDE by its offset in the section.  */
Packit 032894
extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache,
Packit 032894
						Dwarf_Off offset)
Packit 032894
  __nonnull_attribute__ (1) internal_function;
Packit 032894
Packit 032894
/* Process the FDE that contains the given PC address,
Packit 032894
   to yield the frame state when stopped there.
Packit 032894
   The return value is a DWARF_E_* error code.  */
Packit 032894
extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
Packit 032894
				     Dwarf_Addr address, Dwarf_Frame **frame)
Packit 032894
  __nonnull_attribute__ (1, 2, 4) internal_function;
Packit 032894
Packit 032894
Packit 032894
/* Dummy struct for memory-access.h macros.  */
Packit 032894
#define BYTE_ORDER_DUMMY(var, e_ident)					      \
Packit 032894
  const struct { bool other_byte_order; } var =				      \
Packit 032894
    { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB)       \
Packit 032894
       || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) }
Packit 032894
Packit 032894
Packit 032894
INTDECL (dwarf_next_cfi)
Packit 032894
INTDECL (dwarf_getcfi)
Packit 032894
INTDECL (dwarf_getcfi_elf)
Packit 032894
INTDECL (dwarf_cfi_end)
Packit 032894
INTDECL (dwarf_cfi_addrframe)
Packit 032894
Packit 032894
#endif	/* unwindP.h */