Squashed 'third_party/elfutils/' content from commit 555e15e

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