[PR ld/22269] arm: Avoid dynamic relocs for undefweak symbols in static PIE
[deliverable/binutils-gdb.git] / gdb / dwarf2-frame.h
index d2b34f090aa20a08aeeb14fdbadd4b413761dd51..a0ec3615a45d2cd6db30fdbcaf50818c4fef8e6a 100644 (file)
@@ -1,7 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
@@ -26,6 +25,9 @@
 struct gdbarch;
 struct objfile;
 struct frame_info;
+struct dwarf2_per_cu_data;
+struct agent_expr;
+struct axs_value;
 
 /* Register rule.  */
 
@@ -39,7 +41,7 @@ enum dwarf2_frame_reg_rule
   DWARF2_FRAME_REG_UNSPECIFIED = 0,
 
   /* The term "undefined" comes from the DWARF2 CFI spec which this
-     code is moddeling; it indicates that the register's value is
+     code is modeling; it indicates that the register's value is
      "undefined".  GCC uses the less formal term "unsaved".  Its
      definition is a combination of REG_UNDEFINED and REG_UNSPECIFIED.
      The failure to differentiate the two helps explain a few problems
@@ -72,14 +74,135 @@ struct dwarf2_frame_state_reg
   union {
     LONGEST offset;
     ULONGEST reg;
-    unsigned char *exp;
+    struct
+    {
+      const gdb_byte *start;
+      ULONGEST len;
+    } exp;
     struct value *(*fn) (struct frame_info *this_frame, void **this_cache,
                         int regnum);
   } loc;
-  ULONGEST exp_len;
   enum dwarf2_frame_reg_rule how;
 };
 
+enum cfa_how_kind
+{
+  CFA_UNSET,
+  CFA_REG_OFFSET,
+  CFA_EXP
+};
+
+struct dwarf2_frame_state_reg_info
+{
+  dwarf2_frame_state_reg_info () = default;
+  ~dwarf2_frame_state_reg_info ()
+  {
+    delete prev;
+  }
+
+  /* Copy constructor.  */
+  dwarf2_frame_state_reg_info (const dwarf2_frame_state_reg_info &src)
+    : reg (src.reg), cfa_offset (src.cfa_offset),
+      cfa_reg (src.cfa_reg), cfa_how (src.cfa_how), cfa_exp (src.cfa_exp),
+      prev (src.prev)
+  {
+  }
+
+  /* Assignment operator for both move-assignment and copy-assignment.  */
+  dwarf2_frame_state_reg_info&
+  operator= (dwarf2_frame_state_reg_info rhs)
+  {
+    swap (*this, rhs);
+    return *this;
+  }
+
+  /* Move constructor.  */
+  dwarf2_frame_state_reg_info (dwarf2_frame_state_reg_info &&rhs) noexcept
+    : reg (std::move (rhs.reg)), cfa_offset (rhs.cfa_offset),
+      cfa_reg (rhs.cfa_reg), cfa_how (rhs.cfa_how), cfa_exp (rhs.cfa_exp),
+      prev (rhs.prev)
+  {
+    rhs.prev = nullptr;
+  }
+
+  /* If necessary, enlarge the register set to hold NUM_REGS_REQUESTED
+     registers.  */
+  void alloc_regs (int num_regs_requested)
+  {
+    gdb_assert (num_regs_requested > 0);
+
+    if (num_regs_requested <= reg.size ())
+      return;
+
+    reg.resize (num_regs_requested);
+  }
+
+  std::vector<struct dwarf2_frame_state_reg> reg;
+
+  LONGEST cfa_offset = 0;
+  ULONGEST cfa_reg = 0;
+  enum cfa_how_kind cfa_how = CFA_UNSET;
+  const gdb_byte *cfa_exp = NULL;
+
+  /* Used to implement DW_CFA_remember_state.  */
+  struct dwarf2_frame_state_reg_info *prev = NULL;
+
+private:
+  friend void swap (dwarf2_frame_state_reg_info& lhs,
+                   dwarf2_frame_state_reg_info& rhs)
+  {
+    using std::swap;
+
+    swap (lhs.reg, rhs.reg);
+    swap (lhs.cfa_offset, rhs.cfa_offset);
+    swap (lhs.cfa_reg, rhs.cfa_reg);
+    swap (lhs.cfa_how, rhs.cfa_how);
+    swap (lhs.cfa_exp, rhs.cfa_exp);
+    swap (lhs.prev, rhs.prev);
+  }
+};
+
+struct dwarf2_cie;
+
+/* Structure describing a frame state.  */
+
+struct dwarf2_frame_state
+{
+  dwarf2_frame_state (CORE_ADDR pc, struct dwarf2_cie *cie);
+
+  /* Each register save state can be described in terms of a CFA slot,
+     another register, or a location expression.  */
+  struct dwarf2_frame_state_reg_info regs {};
+
+  /* The PC described by the current frame state.  */
+  CORE_ADDR pc;
+
+  /* Initial register set from the CIE.
+     Used to implement DW_CFA_restore.  */
+  struct dwarf2_frame_state_reg_info initial {};
+
+  /* The information we care about from the CIE.  */
+  const LONGEST data_align;
+  const ULONGEST code_align;
+  const ULONGEST retaddr_column;
+
+  /* Flags for known producer quirks.  */
+
+  /* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa
+     and DW_CFA_def_cfa_offset takes a factored offset.  */
+  bool armcc_cfa_offsets_sf = false;
+
+  /* The ARM compilers, in DWARF2 or DWARF3 mode, may assume that
+     the CFA is defined as REG - OFFSET rather than REG + OFFSET.  */
+  bool armcc_cfa_offsets_reversed = false;
+};
+
+/* When this is true the DWARF frame unwinders can be used if they are
+   registered with the gdbarch.  Not all architectures can or do use the
+   DWARF unwinders.  Setting this to true on a target that does not
+   otherwise support the DWARF unwinders has no effect.  */
+extern bool dwarf2_frame_unwinders_enabled_p;
+
 /* Set the architecture-specific register state initialization
    function for GDBARCH to INIT_REG.  */
 
@@ -114,12 +237,30 @@ void dwarf2_append_unwinders (struct gdbarch *gdbarch);
 extern const struct frame_base *
   dwarf2_frame_base_sniffer (struct frame_info *this_frame);
 
-/* Register the DWARF CFI for OBJFILE.  */
-
-void dwarf2_frame_build_info (struct objfile *objfile);
-
 /* Compute the DWARF CFA for a frame.  */
 
 CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
 
+/* Find the CFA information for PC.
+
+   Return 1 if a register is used for the CFA, or 0 if another
+   expression is used.  Throw an exception on error.
+
+   GDBARCH is the architecture to use.
+   DATA is the per-CU data.
+
+   REGNUM_OUT is an out parameter that is set to the register number.
+   OFFSET_OUT is the offset to use from this register.
+   These are only filled in when 1 is returned.
+
+   TEXT_OFFSET_OUT, CFA_START_OUT, and CFA_END_OUT describe the CFA
+   in other cases.  These are only used when 0 is returned.  */
+
+extern int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
+                                 struct dwarf2_per_cu_data *data,
+                                 int *regnum_out, LONGEST *offset_out,
+                                 CORE_ADDR *text_offset_out,
+                                 const gdb_byte **cfa_start_out,
+                                 const gdb_byte **cfa_end_out);
+
 #endif /* dwarf2-frame.h */
This page took 0.028934 seconds and 4 git commands to generate.