Blame libdw/cfi.h

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