gdb: Convert language la_watch_location_expression field to a method
[deliverable/binutils-gdb.git] / gdb / dwarf2 / frame.c
index 8cf136e5019b92663db9a862fcb5b53aeb2102ca..a8748e4d7d3fb9b2faa6e5de3daf4b2e52774ca4 100644 (file)
@@ -129,40 +129,45 @@ struct dwarf2_fde
   unsigned char eh_frame_p;
 };
 
-struct dwarf2_fde_table
-{
-  int num_entries;
-  struct dwarf2_fde **entries;
-};
+typedef std::vector<dwarf2_fde *> dwarf2_fde_table;
 
 /* A minimal decoding of DWARF2 compilation units.  We only decode
    what's needed to get to the call frame information.  */
 
 struct comp_unit
 {
+  comp_unit (struct objfile *objf)
+    : abfd (objf->obfd)
+  {
+  }
+
   /* Keep the bfd convenient.  */
   bfd *abfd;
 
-  struct objfile *objfile;
-
   /* Pointer to the .debug_frame section loaded into memory.  */
-  const gdb_byte *dwarf_frame_buffer;
+  const gdb_byte *dwarf_frame_buffer = nullptr;
 
   /* Length of the loaded .debug_frame section.  */
-  bfd_size_type dwarf_frame_size;
+  bfd_size_type dwarf_frame_size = 0;
 
   /* Pointer to the .debug_frame section.  */
-  asection *dwarf_frame_section;
+  asection *dwarf_frame_section = nullptr;
 
   /* Base for DW_EH_PE_datarel encodings.  */
-  bfd_vma dbase;
+  bfd_vma dbase = 0;
 
   /* Base for DW_EH_PE_textrel encodings.  */
-  bfd_vma tbase;
+  bfd_vma tbase = 0;
+
+  /* The FDE table.  */
+  dwarf2_fde_table fde_table;
+
+  /* Hold data used by this module.  */
+  auto_obstack obstack;
 };
 
-static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc,
-                                                CORE_ADDR *out_offset);
+static struct dwarf2_fde *dwarf2_frame_find_fde
+  (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile);
 
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
                                       int eh_frame_p);
@@ -232,7 +237,11 @@ register %s (#%d) at %s"),
 
 class dwarf_expr_executor : public dwarf_expr_context
 {
- public:
+public:
+
+  dwarf_expr_executor (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *this_frame;
 
@@ -306,19 +315,18 @@ class dwarf_expr_executor : public dwarf_expr_context
 
 static CORE_ADDR
 execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
-                 CORE_ADDR offset, struct frame_info *this_frame,
-                 CORE_ADDR initial, int initial_in_stack_memory)
+                 struct frame_info *this_frame, CORE_ADDR initial,
+                 int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
 {
   CORE_ADDR result;
 
-  dwarf_expr_executor ctx;
+  dwarf_expr_executor ctx (per_objfile);
   scoped_value_mark free_values;
 
   ctx.this_frame = this_frame;
   ctx.gdbarch = get_frame_arch (this_frame);
   ctx.addr_size = addr_size;
   ctx.ref_addr_size = -1;
-  ctx.offset = offset;
 
   ctx.push_address (initial, initial_in_stack_memory);
   ctx.eval (exp, len);
@@ -347,7 +355,8 @@ Not implemented: computing unwound register using explicit value operator"));
 static const gdb_byte *
 execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
                     const gdb_byte *insn_end, struct gdbarch *gdbarch,
-                    CORE_ADDR pc, struct dwarf2_frame_state *fs)
+                    CORE_ADDR pc, struct dwarf2_frame_state *fs,
+                    CORE_ADDR text_offset)
 {
   int eh_frame_p = fde->eh_frame_p;
   unsigned int bytes_read;
@@ -384,8 +393,8 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
              fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
                                           fde->cie->ptr_size, insn_ptr,
                                           &bytes_read, fde->initial_location);
-             /* Apply the objfile offset for relocatable objects.  */
-             fs->pc += fde->cie->unit->objfile->text_section_offset ();
+             /* Apply the text offset for relocatable objects.  */
+             fs->pc += text_offset;
              insn_ptr += bytes_read;
              break;
 
@@ -644,7 +653,7 @@ execute_cfa_program_test (struct gdbarch *gdbarch)
 
   const gdb_byte *insn_end = insns + sizeof (insns);
   const gdb_byte *out = execute_cfa_program (&fde, insns, insn_end, gdbarch,
-                                            0, &fs);
+                                            0, &fs, 0);
 
   SELF_CHECK (out == insn_end);
   SELF_CHECK (fs.pc == 0);
@@ -877,14 +886,16 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
                       const gdb_byte **cfa_end_out)
 {
   struct dwarf2_fde *fde;
-  CORE_ADDR text_offset;
+  dwarf2_per_objfile *per_objfile;
   CORE_ADDR pc1 = pc;
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &per_objfile);
   if (fde == NULL)
     error (_("Could not compute CFA; needed to translate this expression"));
 
+  gdb_assert (per_objfile != nullptr);
+
   dwarf2_frame_state fs (pc1, fde->cie);
 
   /* Check for "quirks" - known bugs in producers.  */
@@ -892,13 +903,15 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
 
   /* First decode all the insns in the CIE.  */
   execute_cfa_program (fde, fde->cie->initial_instructions,
-                      fde->cie->end, gdbarch, pc, &fs);
+                      fde->cie->end, gdbarch, pc, &fs,
+                      per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
 
   /* Then decode the insns in the FDE up to our target PC.  */
-  execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs);
+  execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs,
+                      per_objfile->objfile->text_section_offset ());
 
   /* Calculate the CFA.  */
   switch (fs.regs.cfa_how)
@@ -916,7 +929,7 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
       }
 
     case CFA_EXP:
-      *text_offset_out = text_offset;
+      *text_offset_out = per_objfile->objfile->text_section_offset ();
       *cfa_start_out = fs.regs.cfa_exp;
       *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
       return 0;
@@ -949,12 +962,8 @@ struct dwarf2_frame_cache
   /* Target address size in bytes.  */
   int addr_size;
 
-  /* The .text offset.  */
-  CORE_ADDR text_offset;
-
-  /* True if we already checked whether this frame is the bottom frame
-     of a virtual tail call frame chain.  */
-  int checked_tailcall_bottom;
+  /* The dwarf2_per_objfile from which this frame description came.  */
+  dwarf2_per_objfile *per_objfile;
 
   /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
      sequence.  If NULL then it is a normal case with no TAILCALL_FRAME
@@ -962,12 +971,6 @@ struct dwarf2_frame_cache
      dwarf2_tailcall_frame_unwind unwinder so this field does not apply for
      them.  */
   void *tailcall_cache;
-
-  /* The number of bytes to subtract from TAILCALL_FRAME frames frame
-     base to get the SP, to simulate the return address pushed on the
-     stack.  */
-  LONGEST entry_cfa_sp_offset;
-  int entry_cfa_sp_offset_p;
 };
 
 static struct dwarf2_frame_cache *
@@ -1006,8 +1009,9 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   CORE_ADDR pc1 = get_frame_address_in_block (this_frame);
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &cache->per_objfile);
   gdb_assert (fde != NULL);
+  gdb_assert (cache->per_objfile != nullptr);
 
   /* Allocate and initialize the frame state.  */
   struct dwarf2_frame_state fs (pc1, fde->cie);
@@ -1020,7 +1024,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   /* First decode all the insns in the CIE.  */
   execute_cfa_program (fde, fde->cie->initial_instructions,
                       fde->cie->end, gdbarch,
-                      get_frame_address_in_block (this_frame), &fs);
+                      get_frame_address_in_block (this_frame), &fs,
+                      cache->per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
@@ -1029,20 +1034,23 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
      in an address that's within the range of FDE locations.  This
      is due to the possibility of the function occupying non-contiguous
      ranges.  */
+  LONGEST entry_cfa_sp_offset;
+  int entry_cfa_sp_offset_p = 0;
   if (get_frame_func_if_available (this_frame, &entry_pc)
       && fde->initial_location <= entry_pc
       && entry_pc < fde->initial_location + fde->address_range)
     {
       /* Decode the insns in the FDE up to the entry PC.  */
-      instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
-                                  entry_pc, &fs);
+      instr = execute_cfa_program
+       (fde, fde->instructions, fde->end, gdbarch, entry_pc, &fs,
+        cache->per_objfile->objfile->text_section_offset ());
 
       if (fs.regs.cfa_how == CFA_REG_OFFSET
          && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
              == gdbarch_sp_regnum (gdbarch)))
        {
-         cache->entry_cfa_sp_offset = fs.regs.cfa_offset;
-         cache->entry_cfa_sp_offset_p = 1;
+         entry_cfa_sp_offset = fs.regs.cfa_offset;
+         entry_cfa_sp_offset_p = 1;
        }
     }
   else
@@ -1050,7 +1058,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
 
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, instr, fde->end, gdbarch,
-                      get_frame_address_in_block (this_frame), &fs);
+                      get_frame_address_in_block (this_frame), &fs,
+                      cache->per_objfile->objfile->text_section_offset ());
 
   try
     {
@@ -1068,8 +1077,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
        case CFA_EXP:
          cache->cfa =
            execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
-                             cache->addr_size, cache->text_offset,
-                             this_frame, 0, 0);
+                             cache->addr_size, this_frame, 0, 0,
+                             cache->per_objfile);
          break;
 
        default:
@@ -1186,6 +1195,10 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
       && fs.regs.reg[fs.retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED)
     cache->undefined_retaddr = 1;
 
+  dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
+                                (entry_cfa_sp_offset_p
+                                 ? &entry_cfa_sp_offset : NULL));
+
   return cache;
 }
 
@@ -1230,16 +1243,6 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
   CORE_ADDR addr;
   int realnum;
 
-  /* Check whether THIS_FRAME is the bottom frame of a virtual tail
-     call frame chain.  */
-  if (!cache->checked_tailcall_bottom)
-    {
-      cache->checked_tailcall_bottom = 1;
-      dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
-                                    (cache->entry_cfa_sp_offset_p
-                                     ? &cache->entry_cfa_sp_offset : NULL));
-    }
-
   /* Non-bottom frames of a virtual tail call frames chain use
      dwarf2_tailcall_frame_unwind unwinder so this code does not apply for
      them.  If dwarf2_tailcall_prev_register_first does not have specific value
@@ -1275,8 +1278,9 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
                               cache->reg[regnum].loc.exp.len,
-                              cache->addr_size, cache->text_offset,
-                              this_frame, cache->cfa, 1);
+                              cache->addr_size,
+                              this_frame, cache->cfa, 1,
+                              cache->per_objfile);
       return frame_unwind_got_memory (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
@@ -1286,8 +1290,9 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_VAL_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
                               cache->reg[regnum].loc.exp.len,
-                              cache->addr_size, cache->text_offset,
-                              this_frame, cache->cfa, 1);
+                              cache->addr_size,
+                              this_frame, cache->cfa, 1,
+                              cache->per_objfile);
       return frame_unwind_got_constant (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
@@ -1401,10 +1406,6 @@ static const struct frame_unwind dwarf2_signal_frame_unwind =
 void
 dwarf2_append_unwinders (struct gdbarch *gdbarch)
 {
-  /* TAILCALL_FRAME must be first to find the record by
-     dwarf2_tailcall_sniffer_first.  */
-  frame_unwind_append_unwinder (gdbarch, &dwarf2_tailcall_frame_unwind);
-
   frame_unwind_append_unwinder (gdbarch, &dwarf2_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &dwarf2_signal_frame_unwind);
 }
@@ -1471,28 +1472,14 @@ dwarf2_frame_cfa (struct frame_info *this_frame)
   return get_frame_base (this_frame);
 }
 \f
-const struct objfile_key<dwarf2_fde_table,
-                        gdb::noop_deleter<dwarf2_fde_table>>
-  dwarf2_frame_objfile_data;
-
-
-static ULONGEST
-read_initial_length (bfd *abfd, const gdb_byte *buf,
-                    unsigned int *bytes_read_ptr)
-{
-  ULONGEST result;
-
-  result = bfd_get_32 (abfd, buf);
-  if (result == 0xffffffff)
-    {
-      result = bfd_get_64 (abfd, buf + 4);
-      *bytes_read_ptr = 12;
-    }
-  else
-    *bytes_read_ptr = 4;
-
-  return result;
-}
+/* We store the frame data on the BFD.  This is only done if it is
+   independent of the address space and so can be shared.  */
+static const struct bfd_key<comp_unit> dwarf2_frame_bfd_data;
+
+/* If any BFD sections require relocations (note; really should be if
+   any debug info requires relocations), then we store the frame data
+   on the objfile instead, and do not share it.  */
+const struct objfile_key<comp_unit> dwarf2_frame_objfile_data;
 \f
 
 /* Pointer encoding helper functions.  */
@@ -1646,62 +1633,83 @@ bsearch_fde_cmp (const dwarf2_fde *fde, CORE_ADDR seek_pc)
   return 1;
 }
 
+/* Find an existing comp_unit for an objfile, if any.  */
+
+static comp_unit *
+find_comp_unit (struct objfile *objfile)
+{
+  bfd *abfd = objfile->obfd;
+  if (gdb_bfd_requires_relocations (abfd))
+    return dwarf2_frame_bfd_data.get (abfd);
+  return dwarf2_frame_objfile_data.get (objfile);
+}
+
+/* Store the comp_unit on OBJFILE, or the corresponding BFD, as
+   appropriate.  */
+
+static void
+set_comp_unit (struct objfile *objfile, struct comp_unit *unit)
+{
+  bfd *abfd = objfile->obfd;
+  if (gdb_bfd_requires_relocations (abfd))
+    return dwarf2_frame_bfd_data.set (abfd, unit);
+  return dwarf2_frame_objfile_data.set (objfile, unit);
+}
+
 /* Find the FDE for *PC.  Return a pointer to the FDE, and store the
    initial location associated with it into *PC.  */
 
 static struct dwarf2_fde *
-dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset)
+dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
 {
   for (objfile *objfile : current_program_space->objfiles ())
     {
-      struct dwarf2_fde_table *fde_table;
       CORE_ADDR offset;
       CORE_ADDR seek_pc;
 
-      fde_table = dwarf2_frame_objfile_data.get (objfile);
-      if (fde_table == NULL)
+      comp_unit *unit = find_comp_unit (objfile);
+      if (unit == NULL)
        {
          dwarf2_build_frame_info (objfile);
-         fde_table = dwarf2_frame_objfile_data.get (objfile);
+         unit = find_comp_unit (objfile);
        }
-      gdb_assert (fde_table != NULL);
+      gdb_assert (unit != NULL);
 
-      if (fde_table->num_entries == 0)
+      dwarf2_fde_table *fde_table = &unit->fde_table;
+      if (fde_table->empty ())
        continue;
 
       gdb_assert (!objfile->section_offsets.empty ());
       offset = objfile->text_section_offset ();
 
-      gdb_assert (fde_table->num_entries > 0);
-      if (*pc < offset + fde_table->entries[0]->initial_location)
+      gdb_assert (!fde_table->empty ());
+      if (*pc < offset + (*fde_table)[0]->initial_location)
         continue;
 
       seek_pc = *pc - offset;
-      auto end = fde_table->entries + fde_table->num_entries;
-      auto it = gdb::binary_search (fde_table->entries, end, seek_pc, bsearch_fde_cmp);
-      if (it != end)
+      auto it = gdb::binary_search (fde_table->begin (), fde_table->end (),
+                                   seek_pc, bsearch_fde_cmp);
+      if (it != fde_table->end ())
         {
           *pc = (*it)->initial_location + offset;
-         if (out_offset)
-           *out_offset = offset;
+         if (out_per_objfile != nullptr)
+           *out_per_objfile = get_dwarf2_per_objfile (objfile);
+
           return *it;
         }
     }
   return NULL;
 }
 
-/* Add a pointer to new FDE to the FDE_TABLE, allocating space for it.  */
+/* Add FDE to FDE_TABLE.  */
 static void
-add_fde (struct dwarf2_fde_table *fde_table, struct dwarf2_fde *fde)
+add_fde (dwarf2_fde_table *fde_table, struct dwarf2_fde *fde)
 {
   if (fde->address_range == 0)
     /* Discard useless FDEs.  */
     return;
 
-  fde_table->num_entries += 1;
-  fde_table->entries = XRESIZEVEC (struct dwarf2_fde *, fde_table->entries,
-                                  fde_table->num_entries);
-  fde_table->entries[fde_table->num_entries - 1] = fde;
+  fde_table->push_back (fde);
 }
 
 #define DW64_CIE_ID 0xffffffffffffffffULL
@@ -1716,24 +1724,25 @@ enum eh_frame_type
   EH_CIE_OR_FDE_TYPE_ID = EH_CIE_TYPE_ID | EH_FDE_TYPE_ID
 };
 
-static const gdb_byte *decode_frame_entry (struct comp_unit *unit,
+static const gdb_byte *decode_frame_entry (struct gdbarch *gdbarch,
+                                          struct comp_unit *unit,
                                           const gdb_byte *start,
                                           int eh_frame_p,
                                           dwarf2_cie_table &cie_table,
-                                          struct dwarf2_fde_table *fde_table,
+                                          dwarf2_fde_table *fde_table,
                                           enum eh_frame_type entry_type);
 
 /* Decode the next CIE or FDE, entry_type specifies the expected type.
    Return NULL if invalid input, otherwise the next byte to be processed.  */
 
 static const gdb_byte *
-decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
+decode_frame_entry_1 (struct gdbarch *gdbarch,
+                     struct comp_unit *unit, const gdb_byte *start,
                      int eh_frame_p,
                       dwarf2_cie_table &cie_table,
-                      struct dwarf2_fde_table *fde_table,
+                      dwarf2_fde_table *fde_table,
                       enum eh_frame_type entry_type)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (unit->objfile);
   const gdb_byte *buf, *end;
   ULONGEST length;
   unsigned int bytes_read;
@@ -1744,7 +1753,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
   uint64_t uleb128;
 
   buf = start;
-  length = read_initial_length (unit->abfd, buf, &bytes_read);
+  length = read_initial_length (unit->abfd, buf, &bytes_read, false);
   buf += bytes_read;
   end = buf + (size_t) length;
 
@@ -1795,7 +1804,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
       if (find_cie (cie_table, cie_pointer))
        return end;
 
-      cie = XOBNEW (&unit->objfile->objfile_obstack, struct dwarf2_cie);
+      cie = XOBNEW (&unit->obstack, struct dwarf2_cie);
       cie->initial_instructions = NULL;
       cie->cie_pointer = cie_pointer;
 
@@ -1974,11 +1983,12 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
       if (cie_pointer >= unit->dwarf_frame_size)
        return NULL;
 
-      fde = XOBNEW (&unit->objfile->objfile_obstack, struct dwarf2_fde);
+      fde = XOBNEW (&unit->obstack, struct dwarf2_fde);
       fde->cie = find_cie (cie_table, cie_pointer);
       if (fde->cie == NULL)
        {
-         decode_frame_entry (unit, unit->dwarf_frame_buffer + cie_pointer,
+         decode_frame_entry (gdbarch, unit,
+                             unit->dwarf_frame_buffer + cie_pointer,
                              eh_frame_p, cie_table, fde_table,
                              EH_CIE_TYPE_ID);
          fde->cie = find_cie (cie_table, cie_pointer);
@@ -2029,10 +2039,11 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
    expect an FDE or a CIE.  */
 
 static const gdb_byte *
-decode_frame_entry (struct comp_unit *unit, const gdb_byte *start,
+decode_frame_entry (struct gdbarch *gdbarch,
+                   struct comp_unit *unit, const gdb_byte *start,
                    int eh_frame_p,
                    dwarf2_cie_table &cie_table,
-                    struct dwarf2_fde_table *fde_table,
+                    dwarf2_fde_table *fde_table,
                     enum eh_frame_type entry_type)
 {
   enum { NONE, ALIGN4, ALIGN8, FAIL } workaround = NONE;
@@ -2041,7 +2052,7 @@ decode_frame_entry (struct comp_unit *unit, const gdb_byte *start,
 
   while (1)
     {
-      ret = decode_frame_entry_1 (unit, start, eh_frame_p,
+      ret = decode_frame_entry_1 (gdbarch, unit, start, eh_frame_p,
                                  cie_table, fde_table, entry_type);
       if (ret != NULL)
        break;
@@ -2101,21 +2112,21 @@ decode_frame_entry (struct comp_unit *unit, const gdb_byte *start,
     case ALIGN4:
       complaint (_("\
 Corrupt data in %s:%s; align 4 workaround apparently succeeded"),
-                unit->dwarf_frame_section->owner->filename,
-                unit->dwarf_frame_section->name);
+                bfd_get_filename (unit->dwarf_frame_section->owner),
+                bfd_section_name (unit->dwarf_frame_section));
       break;
 
     case ALIGN8:
       complaint (_("\
 Corrupt data in %s:%s; align 8 workaround apparently succeeded"),
-                unit->dwarf_frame_section->owner->filename,
-                unit->dwarf_frame_section->name);
+                bfd_get_filename (unit->dwarf_frame_section->owner),
+                bfd_section_name (unit->dwarf_frame_section));
       break;
 
     default:
       complaint (_("Corrupt data in %s:%s"),
-                unit->dwarf_frame_section->owner->filename,
-                unit->dwarf_frame_section->name);
+                bfd_get_filename (unit->dwarf_frame_section->owner),
+                bfd_section_name (unit->dwarf_frame_section));
       break;
     }
 
@@ -2143,21 +2154,14 @@ fde_is_less_than (const dwarf2_fde *aa, const dwarf2_fde *bb)
 void
 dwarf2_build_frame_info (struct objfile *objfile)
 {
-  struct comp_unit *unit;
   const gdb_byte *frame_ptr;
   dwarf2_cie_table cie_table;
-  struct dwarf2_fde_table fde_table;
-  struct dwarf2_fde_table *fde_table2;
+  dwarf2_fde_table fde_table;
 
-  fde_table.num_entries = 0;
-  fde_table.entries = NULL;
+  struct gdbarch *gdbarch = objfile->arch ();
 
   /* Build a minimal decoding of the DWARF2 compilation unit.  */
-  unit = XOBNEW (&objfile->objfile_obstack, comp_unit);
-  unit->abfd = objfile->obfd;
-  unit->objfile = objfile;
-  unit->dbase = 0;
-  unit->tbase = 0;
+  std::unique_ptr<comp_unit> unit (new comp_unit (objfile));
 
   if (objfile->separate_debug_objfile_backlink == NULL)
     {
@@ -2189,7 +2193,8 @@ dwarf2_build_frame_info (struct objfile *objfile)
            {
              frame_ptr = unit->dwarf_frame_buffer;
              while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
-               frame_ptr = decode_frame_entry (unit, frame_ptr, 1,
+               frame_ptr = decode_frame_entry (gdbarch, unit.get (),
+                                               frame_ptr, 1,
                                                cie_table, &fde_table,
                                                EH_CIE_OR_FDE_TYPE_ID);
            }
@@ -2199,12 +2204,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
              warning (_("skipping .eh_frame info of %s: %s"),
                       objfile_name (objfile), e.what ());
 
-             if (fde_table.num_entries != 0)
-               {
-                  xfree (fde_table.entries);
-                 fde_table.entries = NULL;
-                 fde_table.num_entries = 0;
-               }
+             fde_table.clear ();
              /* The cie_table is discarded below.  */
            }
 
@@ -2218,13 +2218,13 @@ dwarf2_build_frame_info (struct objfile *objfile)
                            &unit->dwarf_frame_size);
   if (unit->dwarf_frame_size)
     {
-      int num_old_fde_entries = fde_table.num_entries;
+      size_t num_old_fde_entries = fde_table.size ();
 
       try
        {
          frame_ptr = unit->dwarf_frame_buffer;
          while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
-           frame_ptr = decode_frame_entry (unit, frame_ptr, 0,
+           frame_ptr = decode_frame_entry (gdbarch, unit.get (), frame_ptr, 0,
                                            cie_table, &fde_table,
                                            EH_CIE_OR_FDE_TYPE_ID);
        }
@@ -2233,97 +2233,58 @@ dwarf2_build_frame_info (struct objfile *objfile)
          warning (_("skipping .debug_frame info of %s: %s"),
                   objfile_name (objfile), e.what ());
 
-         if (fde_table.num_entries != 0)
-           {
-             fde_table.num_entries = num_old_fde_entries;
-             if (num_old_fde_entries == 0)
-               {
-                 xfree (fde_table.entries);
-                 fde_table.entries = NULL;
-               }
-             else
-               {
-                 fde_table.entries
-                   = XRESIZEVEC (struct dwarf2_fde *, fde_table.entries,
-                                 fde_table.num_entries);
-               }
-           }
-         fde_table.num_entries = num_old_fde_entries;
+         fde_table.resize (num_old_fde_entries);
        }
     }
 
-  /* Copy fde_table to obstack: it is needed at runtime.  */
-  fde_table2 = XOBNEW (&objfile->objfile_obstack, struct dwarf2_fde_table);
-
-  if (fde_table.num_entries == 0)
-    {
-      fde_table2->entries = NULL;
-      fde_table2->num_entries = 0;
-    }
-  else
+  struct dwarf2_fde *fde_prev = NULL;
+  struct dwarf2_fde *first_non_zero_fde = NULL;
+
+  /* Prepare FDE table for lookups.  */
+  std::sort (fde_table.begin (), fde_table.end (), fde_is_less_than);
+
+  /* Check for leftovers from --gc-sections.  The GNU linker sets
+     the relevant symbols to zero, but doesn't zero the FDE *end*
+     ranges because there's no relocation there.  It's (offset,
+     length), not (start, end).  On targets where address zero is
+     just another valid address this can be a problem, since the
+     FDEs appear to be non-empty in the output --- we could pick
+     out the wrong FDE.  To work around this, when overlaps are
+     detected, we prefer FDEs that do not start at zero.
+
+     Start by finding the first FDE with non-zero start.  Below
+     we'll discard all FDEs that start at zero and overlap this
+     one.  */
+  for (struct dwarf2_fde *fde : fde_table)
     {
-      struct dwarf2_fde *fde_prev = NULL;
-      struct dwarf2_fde *first_non_zero_fde = NULL;
-      int i;
-
-      /* Prepare FDE table for lookups.  */
-      std::sort (fde_table.entries, fde_table.entries + fde_table.num_entries,
-                fde_is_less_than);
-
-      /* Check for leftovers from --gc-sections.  The GNU linker sets
-        the relevant symbols to zero, but doesn't zero the FDE *end*
-        ranges because there's no relocation there.  It's (offset,
-        length), not (start, end).  On targets where address zero is
-        just another valid address this can be a problem, since the
-        FDEs appear to be non-empty in the output --- we could pick
-        out the wrong FDE.  To work around this, when overlaps are
-        detected, we prefer FDEs that do not start at zero.
-
-        Start by finding the first FDE with non-zero start.  Below
-        we'll discard all FDEs that start at zero and overlap this
-        one.  */
-      for (i = 0; i < fde_table.num_entries; i++)
+      if (fde->initial_location != 0)
        {
-         struct dwarf2_fde *fde = fde_table.entries[i];
-
-         if (fde->initial_location != 0)
-           {
-             first_non_zero_fde = fde;
-             break;
-           }
+         first_non_zero_fde = fde;
+         break;
        }
+    }
 
-      /* Since we'll be doing bsearch, squeeze out identical (except
-        for eh_frame_p) fde entries so bsearch result is predictable.
-        Also discard leftovers from --gc-sections.  */
-      fde_table2->num_entries = 0;
-      for (i = 0; i < fde_table.num_entries; i++)
-       {
-         struct dwarf2_fde *fde = fde_table.entries[i];
-
-         if (fde->initial_location == 0
-             && first_non_zero_fde != NULL
-             && (first_non_zero_fde->initial_location
-                 < fde->initial_location + fde->address_range))
-           continue;
-
-         if (fde_prev != NULL
-             && fde_prev->initial_location == fde->initial_location)
-           continue;
-
-         obstack_grow (&objfile->objfile_obstack, &fde_table.entries[i],
-                       sizeof (fde_table.entries[0]));
-         ++fde_table2->num_entries;
-         fde_prev = fde;
-       }
-      fde_table2->entries
-       = (struct dwarf2_fde **) obstack_finish (&objfile->objfile_obstack);
+  /* Since we'll be doing bsearch, squeeze out identical (except
+     for eh_frame_p) fde entries so bsearch result is predictable.
+     Also discard leftovers from --gc-sections.  */
+  for (struct dwarf2_fde *fde : fde_table)
+    {
+      if (fde->initial_location == 0
+         && first_non_zero_fde != NULL
+         && (first_non_zero_fde->initial_location
+             < fde->initial_location + fde->address_range))
+       continue;
+
+      if (fde_prev != NULL
+         && fde_prev->initial_location == fde->initial_location)
+       continue;
 
-      /* Discard the original fde_table.  */
-      xfree (fde_table.entries);
+      unit->fde_table.push_back (fde);
+      fde_prev = fde;
     }
+  unit->fde_table.shrink_to_fit ();
 
-  dwarf2_frame_objfile_data.set (objfile, fde_table2);
+  set_comp_unit (objfile, unit.release ());
 }
 
 /* Handle 'maintenance show dwarf unwinders'.  */
This page took 0.033026 seconds and 4 git commands to generate.