]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Drop sec_locexpr, make loci clonable
authorPetr Machata <pmachata@redhat.com>
Wed, 13 Apr 2011 13:27:58 +0000 (15:27 +0200)
committerPetr Machata <pmachata@redhat.com>
Wed, 13 Apr 2011 13:27:58 +0000 (15:27 +0200)
12 files changed:
dwarflint/addr-record.cc
dwarflint/addr-record.hh
dwarflint/check_debug_aranges.cc
dwarflint/check_debug_info.cc
dwarflint/check_debug_line.cc
dwarflint/check_debug_loc_range.cc
dwarflint/check_debug_pub.cc
dwarflint/reloc.cc
dwarflint/reloc.hh
dwarflint/section_id.hh
dwarflint/where.cc
dwarflint/where.h

index 2be2880346c2ec73d5bdb77832d174265d779cc8..50bf8a876ab48a6a4b18532cf1f0abf992d3808b 100644 (file)
@@ -66,3 +66,36 @@ addr_record_add (struct addr_record *ar, uint64_t addr)
   if (a >= ar->size () || (*ar)[a] != addr)
     ar->insert (ar->begin () + a, addr);
 }
+
+ref::ref ()
+  : addr (-1)
+  , who (NULL)
+{}
+
+ref::ref (uint64_t a_addr, locus const &a_who)
+  : addr (a_addr)
+  , who (a_who.clone ())
+{}
+
+ref::ref (ref const &copy)
+  : who (NULL)
+{
+  *this = copy;
+}
+
+ref &
+ref::operator= (ref const &copy)
+{
+  if (&copy != this)
+    {
+      addr = copy.addr;
+      delete who;
+      who = copy.who ? copy.who->clone () : NULL;
+    }
+  return *this;
+}
+
+ref::~ref ()
+{
+  delete who;
+}
index b0be7a965aa92dd0c96c7973ce90c64ddaf77f02..1b1559d0d494232132b9799c6bcc90e35bb49a2b 100644 (file)
@@ -62,18 +62,14 @@ void addr_record_add (struct addr_record *ar, uint64_t addr);
 
 struct ref
 {
-  uint64_t addr; // Referree address
-  ::where who;  // Referrer
-
-  ref ()
-    : addr (-1)
-    , who ()
-  {}
-
-  ref (uint64_t a_addr, where const &a_who)
-    : addr (a_addr)
-    , who (a_who)
-  {}
+  uint64_t addr; // Referee address
+  locus *who;    // Referrer
+
+  ref ();
+  ref (uint64_t a_addr, locus const &a_who);
+  ref (ref const &copy);
+  ~ref ();
+  ref &operator= (ref const &copy);
 };
 
 class ref_record
index 7373626ec736352b4039e1ddd93294c8d708a9e5..23bcecb3f67c1b8ccf921c3130785e16faf304c4 100644 (file)
@@ -258,9 +258,9 @@ check_aranges_structural (struct elf_file *file,
 
       struct relocation *rel;
       if ((rel = relocation_next (&sec->rel, ctx_offset,
-                                 &where, skip_mismatched)))
+                                 where, skip_mismatched)))
        relocate_one (file, &sec->rel, rel, offset_size,
-                     &cu_offset, &where, sec_info, NULL);
+                     &cu_offset, where, sec_info, NULL);
       else if (file->ehdr.e_type == ET_REL)
        wr_message (mc_impact_2 | mc_aranges | mc_reloc | mc_header, &where,
                    PRI_LACK_RELOCATION, "debug info offset");
@@ -289,6 +289,12 @@ check_aranges_structural (struct elf_file *file,
            ss << "unknown CU";
          return ss.str ();
        }
+
+       locus *
+       clone () const
+       {
+         return new cudie_locus (*this);
+       }
       };
 
       cudie_locus cudie_loc (cu != NULL ? cu->cudie_offset : -1);
@@ -380,11 +386,11 @@ check_aranges_structural (struct elf_file *file,
            }
 
          if ((rel = relocation_next (&sec->rel, ctx_offset,
-                                     &where, skip_mismatched)))
+                                     where, skip_mismatched)))
            {
              address_relocated = true;
              relocate_one (file, &sec->rel, rel, address_size,
-                           &address, &where, rel_address, NULL);
+                           &address, where, rel_address, NULL);
            }
          else if (file->ehdr.e_type == ET_REL && address != 0)
            wr_message (mc_impact_2 | mc_aranges | mc_reloc, &where,
index 04344851241458c2b27e7bc9a428498c43a1248d..ce93aa56c95e122aee897bd4aa55be10eafd3546 100644 (file)
@@ -117,7 +117,7 @@ namespace
         it != die_refs->end (); ++it)
       if (!addr_record_has_addr (&cu->die_addrs, it->addr))
        {
-         wr_error (it->who)
+         wr_error (*it->who)
            << "unresolved reference to " << pri::DIE (it->addr)
            << '.' << std::endl;
          retval = false;
@@ -143,7 +143,7 @@ namespace
 
          if (ref_cu == NULL)
            {
-             wr_error (rt->who)
+             wr_error (*rt->who)
                << "unresolved (non-CU-local) reference to "
                << pri::hex (rt->addr) << '.' << std::endl;
              retval = false;
@@ -153,7 +153,7 @@ namespace
               reference is valid, which it is.  But warn about this
               anyway, perhaps local reference could be formed on
               smaller number of bytes.  */
-           wr_message (rt->who, mc_impact_2 | mc_acc_suboptimal | mc_die_rel)
+           wr_message (*rt->who, mc_impact_2 | mc_acc_suboptimal | mc_die_rel)
              << "local reference to " << pri::DIE (rt->addr)
              << " formed as global." << std::endl;
        }
@@ -262,11 +262,11 @@ namespace
          }
 
        struct relocation *rel
-         = relocation_next (reloc, ctx_offset, &head.where, skip_ok);
+         = relocation_next (reloc, ctx_offset, head.where, skip_ok);
        if (rel != NULL)
          {
            relocate_one (file, reloc, rel, head.offset_size,
-                         &head.abbrev_offset, &head.where, sec_abbrev, NULL);
+                         &head.abbrev_offset, head.where, sec_abbrev, NULL);
            rel->invalid = true; // mark as invalid so it's skipped
                                 // next time we pass by this
          }
@@ -487,8 +487,7 @@ namespace
     if (ctx->cu->stmt_list.addr != (uint64_t)-1)
       wr_error (*ctx->where)
        << "DW_AT_stmt_list mentioned twice in a CU." << std::endl;
-    ctx->cu->stmt_list.addr = value;
-    ctx->cu->stmt_list.who = *ctx->where;
+    ctx->cu->stmt_list = ref (value, *ctx->where);
   }
 
   /* Callback for locptr values.  */
@@ -872,7 +871,7 @@ namespace
            /* Relocate the value if appropriate.  */
            struct relocation *rel;
            if ((rel = relocation_next (reloc, ctx_offset,
-                                       &where, skip_mismatched)))
+                                       where, skip_mismatched)))
              {
                if (relocate == rel_no)
                  wr_message (where, (mc_impact_4 | mc_die_other
@@ -884,7 +883,7 @@ namespace
                if (attribute != NULL)
                  {
                    form_width_t width = form->width (cu->head);
-                   relocate_one (&file, reloc, rel, width, &value, &where,
+                   relocate_one (&file, reloc, rel, width, &value, where,
                                  reloc_target (form, attribute), symbolp);
                  }
 
@@ -1263,12 +1262,12 @@ check_debug_info_refs::check_debug_info_refs (checkstack &stack,
       if (it->stmt_list.addr == (uint64_t)-1)
        for (ref_record::const_iterator jt = it->decl_file_refs.begin ();
             jt != it->decl_file_refs.end (); ++jt)
-         wr_error (jt->who)
+         wr_error (*jt->who)
            << "references .debug_line table, but CU DIE lacks DW_AT_stmt_list."
            << std::endl;
       else if (_m_line == NULL
               || !_m_line->has_line_table (it->stmt_list.addr))
-       wr_error (it->stmt_list.who)
+       wr_error (*it->stmt_list.who)
          << "unresolved reference to .debug_line table "
          << pri::hex (it->stmt_list.addr) << '.' << std::endl;
 
index 7dc722ab354c0cb6211153f65f26641b31634c43..222ffcfa86c5f087dd92923f21a1e40fa15d6f7c 100644 (file)
@@ -128,11 +128,11 @@ namespace
 
   bool
   use_file (files_t &files, uint64_t file_idx,
-           where const &where, char const *msg = "")
+           locus const &loc, char const *msg = "")
   {
     if (file_idx == 0 || file_idx > files.size ())
       {
-       wr_error (where)
+       wr_error (loc)
          << msg << "invalid file index " << file_idx << '.'
          << std::endl;
        return false;
@@ -343,7 +343,7 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
                for (ref_record::const_iterator
                       jt = it->decl_file_refs.begin ();
                     jt != it->decl_file_refs.end (); ++jt)
-                 if (!use_file (files, jt->addr, jt->who))
+                 if (!use_file (files, jt->addr, *jt->who))
                    success = false;
              }
          if (!found)
@@ -440,10 +440,10 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
 
                      struct relocation *rel;
                      if ((rel = relocation_next (&_m_sec->sect.rel, ctx_offset,
-                                                 &where, skip_mismatched)))
+                                                 where, skip_mismatched)))
                        relocate_one (&_m_sec->file, &_m_sec->sect.rel, rel,
                                      addr_64 ? 8 : 4,
-                                     &addr, &where, rel_address, NULL);
+                                     &addr, where, rel_address, NULL);
                      else if (_m_sec->file.ehdr.e_type == ET_REL)
                        {
                          wr_message (where, mc_impact_2 | mc_line | mc_reloc)
index 153f427b1e38711e4758127dc94e9349b12d1690..9aadb2479bcb54174e55dcadea0c56666dd505de 100644 (file)
@@ -354,7 +354,7 @@ namespace
                          struct coverage_map *coverage_map,
                          struct coverage *pc_coverage,
                          uint64_t addr,
-                         struct where const *wh,
+                         locus const &loc,
                          enum message_category cat)
   {
     char buf[128]; // messages
@@ -368,7 +368,7 @@ namespace
     read_ctx_init (&ctx, parent_ctx->data, file->other_byte_order);
     if (!read_ctx_skip (&ctx, addr))
       {
-       wr_error (wh, ": invalid reference outside the section "
+       wr_error (&loc, ": invalid reference outside the section "
                  "%#" PRIx64 ", size only %#tx.\n",
                  addr, ctx.end - ctx.begin);
        return false;
@@ -379,7 +379,7 @@ namespace
 
     if (coverage->is_covered (addr, 1))
       {
-       wr_error (wh, ": reference to %#" PRIx64
+       wr_error (&loc, ": reference to %#" PRIx64
                  " points into another location or range list.\n", addr);
        retval = false;
       }
@@ -391,7 +391,7 @@ namespace
     uint64_t base = cu->low_pc;
     while (!read_ctx_eof (&ctx))
       {
-       struct where where = WHERE (sec->id, wh);
+       struct where where = WHERE (sec->id, &loc);
        uint64_t offset = read_ctx_get_offset (&ctx);
        where_reset_1 (&where, offset);
 
@@ -419,11 +419,11 @@ namespace
 
        struct relocation *rel;
        if ((rel = relocation_next (&sec->rel, begin_off,
-                                   &where, skip_mismatched)))
+                                   where, skip_mismatched)))
          {
            begin_relocated = true;
            relocate_one (file, &sec->rel, rel, cu->head->address_size,
-                         &begin_addr, &where, rel_value,       &begin_symbol);
+                         &begin_addr, where, rel_value, &begin_symbol);
          }
 
        /* end address */
@@ -443,11 +443,11 @@ namespace
          }
 
        if ((rel = relocation_next (&sec->rel, end_off,
-                                   &where, skip_mismatched)))
+                                   where, skip_mismatched)))
          {
            end_relocated = true;
            relocate_one (file, &sec->rel, rel, cu->head->address_size,
-                         &end_addr, &where, rel_value, &end_symbol);
+                         &end_addr, where, rel_value, &end_symbol);
            if (begin_addr != escape)
              {
                if (!begin_relocated)
@@ -638,7 +638,7 @@ namespace
           Perhaps that's undesirable.  */
        if (!check_loc_or_range_ref (ver, file, &ctx, it->cu, sec,
                                     &coverage, coverage_map, pc_coverage,
-                                    off, &it->ref.who, cat))
+                                    off, *it->ref.who, cat))
          retval = false;
        last_off = off;
       }
@@ -787,7 +787,7 @@ namespace
                form const *form,
                uint64_t *valuep,
                char const *str,
-               struct where const &where)
+               locus const &where)
   {
     if (form == NULL)
       return true;
@@ -812,11 +812,11 @@ namespace
 
     struct relocation *rel;
     if ((rel = relocation_next (reloc, off,
-                               &where, skip_mismatched)))
+                               where, skip_mismatched)))
       {
        if (storclass != sc_block)
          relocate_one (&file, reloc, rel,
-                       cu->head->address_size, valuep, &where,
+                       cu->head->address_size, valuep, where,
                        reloc_target_loc (opcode), NULL);
        else
          wr_error (where) << "relocation relocates a length field.\n";
@@ -824,13 +824,45 @@ namespace
     if (storclass == sc_block)
       {
        uint64_t off_block_end = read_ctx_get_offset (ctx) + init_off - 1;
-       relocation_next (reloc, off_block_end, &where, skip_ok);
+       relocation_next (reloc, off_block_end, where, skip_ok);
       }
 
     return true;
   }
 }
 
+class locexpr_locus
+  : public locus
+{
+  uint64_t const _m_offset;
+  locus const *const _m_context;
+
+public:
+  explicit locexpr_locus (uint64_t offset, locus const *context)
+    : _m_offset (offset)
+    , _m_context (context)
+  {}
+
+  std::string
+  format (bool) const
+  {
+    std::stringstream ss;
+    ss << "location expression offset 0x" << std::hex << _m_offset;
+    return ss.str ();
+  }
+
+  locus *
+  clone () const
+  {
+    return new locexpr_locus (*this);
+  }
+
+  virtual locus const *next () const
+  {
+    return _m_context;
+  }
+};
+
 bool
 check_location_expression (dwarf_version const *ver,
                           elf_file const &file,
@@ -854,9 +886,8 @@ check_location_expression (dwarf_version const *ver,
 
   while (!read_ctx_eof (&ctx))
     {
-      struct where where = WHERE (sec_locexpr, wh);
       uint64_t opcode_off = read_ctx_get_offset (&ctx) + init_off;
-      where_reset_1 (&where, opcode_off);
+      locexpr_locus where (opcode_off, wh);
       addr_record_add (&opaddrs, opcode_off);
 
       uint8_t opcode;
@@ -939,8 +970,8 @@ check_location_expression (dwarf_version const *ver,
   for (ref_record::const_iterator it = oprefs.begin ();
        it != oprefs.end (); ++it)
     if (!addr_record_has_addr (&opaddrs, it->addr))
-      wr_error (it->who) << "unresolved reference to opcode at "
-                        << pri::hex (it->addr) << ".\n";
+      wr_error (*it->who) << "unresolved reference to opcode at "
+                         << pri::hex (it->addr) << ".\n";
 
   return true;
 }
index 7bd9a7f59587b0d91208f3563fe19fc95c48b92d..6b8b1ebc9fce6c4fd4fa81312309fb91c9189f7f 100644 (file)
@@ -144,9 +144,9 @@ check_debug_pub<sec_id>::check_pub_structural ()
 
       struct relocation *rel;
       if ((rel = relocation_next (&_m_sec->sect.rel, ctx_offset,
-                                 &where, skip_mismatched)))
+                                 where, skip_mismatched)))
        relocate_one (&_m_file, &_m_sec->sect.rel, rel, offset_size,
-                     &cu_offset, &where, sec_info, NULL);
+                     &cu_offset, where, sec_info, NULL);
       else if (_m_file.ehdr.e_type == ET_REL)
        wr_message (mc_impact_2 | mc_pubtables | mc_reloc | mc_header, &where,
                    PRI_LACK_RELOCATION, "debug info offset");
index 602a6aa3f666c93a2787b04c707e465f74c4de94..45df78fbb9d24501faa1c6cd1e31215740e4bb91 100644 (file)
@@ -88,12 +88,18 @@ namespace
       ss << " of " << _m_ref.format ();
       return ss.str ();
     }
+
+    locus *
+    clone () const
+    {
+      return new reloc_locus (*this);
+    }
   };
 }
 
 relocation *
 relocation_next (relocation_data *reloc, uint64_t offset,
-                struct where const *where, enum skip_type st)
+                locus const &loc, enum skip_type st)
 {
   if (reloc == NULL || reloc->rel == NULL)
     return NULL;
@@ -115,7 +121,7 @@ relocation_next (relocation_data *reloc, uint64_t offset,
        {
          if (st != skip_ok)
            {
-             reloc_locus reloc_where (reloc->type, *where, rel->offset);
+             reloc_locus reloc_where (reloc->type, loc, rel->offset);
              wr_error (reloc_where)
                << (st == skip_unref
                    ? "relocation targets unreferenced portion of the section."
@@ -140,7 +146,7 @@ relocation_skip (struct relocation_data *reloc, uint64_t offset,
                 struct where const *where, enum skip_type st)
 {
   if (reloc != NULL && reloc->rel != NULL)
-    relocation_next (reloc, offset - 1, where, st);
+    relocation_next (reloc, offset - 1, *where, st);
 }
 
 void
@@ -158,7 +164,7 @@ relocation_skip_rest (struct relocation_data *reloc,
   if (reloc->rel != NULL)
     {
       where wh = WHERE (id, NULL);
-      relocation_next (reloc, (uint64_t)-1, &wh,
+      relocation_next (reloc, (uint64_t)-1, wh,
                       skip_mismatched);
     }
 }
@@ -300,13 +306,13 @@ relocate_one (struct elf_file const *file,
              struct relocation_data *reloc,
              struct relocation *rel,
              unsigned width, uint64_t *value,
-             struct where const *where,
+             locus const &loc,
              enum section_id offset_into, GElf_Sym **symptr)
 {
   if (rel->invalid)
     return;
 
-  reloc_locus reloc_where (reloc->type, *where, rel->offset);
+  reloc_locus reloc_where (reloc->type, loc, rel->offset);
 
   GElf_Sym symbol_mem, *symbol;
   if (symptr != NULL)
index 137642e53bfba98a8ffc10e52e59b8d2fcbcbdd1..10f156a20078ee9ee6ec58c74f6ef1b2a9ac2487 100644 (file)
@@ -85,7 +85,7 @@ bool read_rel (struct elf_file *file, struct sec *sec,
 
 relocation *relocation_next (struct relocation_data *reloc,
                             uint64_t offset,
-                            struct where const *where,
+                            locus const &loc,
                             enum skip_type st);
 
 void relocation_reset (struct relocation_data *reloc);
@@ -100,7 +100,7 @@ void relocate_one (struct elf_file const *file,
                   struct relocation_data *reloc,
                   struct relocation *rel,
                   unsigned width, uint64_t *value,
-                  struct where const *where,
+                  locus const &loc,
                   enum section_id offset_into, GElf_Sym **symptr);
 
 #define PRI_LACK_RELOCATION ": %s seems to lack a relocation.\n"
index ec9c4daea5cbf6cdd04d5ff3cea796197eef6554..d5203744c433c3e3c77784ce664ce72fbe5216bd 100644 (file)
@@ -52,8 +52,6 @@ enum section_id
 
     // XXX the following should really be split out to different enum
     /* Non-sections:  */
-    sec_locexpr,       /* Not a section, but a portion of file that
-                          contains a location expression.  */
     rel_value,         /* For relocations, this denotes that the
                           relocation is applied to taget value, not a
                           section offset.  */
index bef4a53077376714e7e389d62d0da19fcf7d1dce..e069450fad4fc6829c14130b54f8a4da5b377a47 100644 (file)
@@ -148,8 +148,6 @@ namespace
       add (sec_mac, ".debug_mac");
 
       add (sec_ranges, ".debug_ranges", "rangelist %#"PRIx64, "offset %#"PRIx64);
-
-      add (sec_locexpr, "location expression", "offset %#"PRIx64);
     }
   } const section_names;
 }
@@ -164,7 +162,7 @@ namespace
 }
 
 where
-WHERE (section_id sec, where const *next)
+WHERE (section_id sec, locus const *next)
 {
   where::formatter const *fmt = wf_for_section (sec);
   return where (fmt, next);
index c2dab46463b20bde7e048bce19cec68f78335321..d12d6f6c68c33eae01edee91591b60c60b09567d 100644 (file)
@@ -38,6 +38,7 @@ class locus
 {
 public:
   virtual std::string format (bool brief = false) const = 0;
+  virtual locus *clone () const = 0;
 
   virtual locus const *next () const
   {
@@ -84,6 +85,12 @@ public:
     return _m_next;
   }
 
+  locus *
+  clone () const
+  {
+    return new where (*this);
+  }
+
   void
   set_next (locus const *nxt)
   {
@@ -114,7 +121,7 @@ where_reset_3 (struct where *wh, uint64_t addr)
   wh->reset_3 (addr);
 }
 
-where WHERE (section_id sec, where const *next = NULL);
+where WHERE (section_id sec, locus const *next = NULL);
 
 inline std::ostream &
 operator << (std::ostream &os, where const &wh)