]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Support special formatting; add special class "CU DIE"
authorPetr Machata <pmachata@redhat.com>
Fri, 27 Mar 2009 15:43:01 +0000 (16:43 +0100)
committerPetr Machata <pmachata@redhat.com>
Fri, 27 Mar 2009 15:39:42 +0000 (16:39 +0100)
* This is used in analysis of aranges, where CU DIE is referred to by
  decimal address (like CUs), not hexadecimal (like DIEs)

src/dwarflint.c
src/dwarflint.h

index 6c8801645b257f7265eeb36b23b0ec02b2ae6dc0..e25e1a0497290143b09fcfa15cfdc7274cf4954f 100644 (file)
@@ -766,6 +766,7 @@ static void ref_record_free (struct ref_record *rr);
 struct cu
 {
   uint64_t offset;
+  uint64_t cudie_offset;
   uint64_t length;
   int address_size;             // Address size in bytes on the target machine.
   uint64_t base;                // DW_AT_low_pc value of CU DIE, 0 if not present.
@@ -875,8 +876,17 @@ where_fmt (const struct where *wh, char *ptr)
       [sec_text] = {"(exec data)", NULL, NULL, NULL, NULL, NULL, NULL},
     };
 
+  static struct section_info special_formats[] =
+    {
+      [wf_cudie] = {".debug_info", "CU DIE", "%"PRId64, NULL, NULL, NULL, NULL}
+    };
+
   assert (wh->section < sizeof (section_names) / sizeof (*section_names));
-  struct section_info *inf = section_names + wh->section;
+  struct section_info *inf
+    = (wh->formatting == wf_plain)
+    ? section_names + wh->section
+    : special_formats + wh->formatting;
+
   assert (inf->name);
 
   assert ((inf->addr1n == NULL) == (inf->addr1f == NULL));
@@ -3437,6 +3447,7 @@ check_cu_structural (struct read_ctx *ctx,
   struct ref_record local_die_refs;
   WIPE (local_die_refs);
 
+  cu->cudie_offset = read_ctx_get_offset (ctx) + cu->offset;
   if (read_die_chain (ctx, cu, abbrevs, strings,
                      dwarf_64, address_size == 8,
                      die_refs, &local_die_refs, strings_coverage,
@@ -3672,19 +3683,20 @@ check_aranges_structural (struct section_data *data, struct cu *cu_chain)
   struct read_ctx ctx;
   read_ctx_init (&ctx, data->file->dwarf, data->data);
 
-  struct where where = WHERE (sec_aranges, NULL);
   bool retval = true;
 
   struct coverage_map *coverage_map;
   if ((coverage_map = coverage_map_alloc_XA (data->file->dwarf->elf,
                                             false)) == NULL)
     {
-      wr_error (&where, ": couldn't read ELF, skipping coverage analysis.\n");
+      wr_error (&WHERE (sec_aranges, NULL),
+               ": couldn't read ELF, skipping coverage analysis.\n");
       retval = false;
     }
 
   while (!read_ctx_eof (&ctx))
     {
+      struct where where = WHERE (sec_aranges, NULL);
       where_reset_1 (&where, read_ctx_get_offset (&ctx));
       const unsigned char *atab_begin = ctx.ptr;
 
@@ -3747,9 +3759,14 @@ check_aranges_structural (struct section_data *data, struct cu *cu_chain)
       struct cu *cu = NULL;
       if (cu_chain != NULL && (cu = cu_find_cu (cu_chain, cu_offset)) == NULL)
        wr_error (&where, ": unresolved reference to " PRI_CU ".\n", cu_offset);
+
+      struct where where_cudie;
       if (cu != NULL)
        {
-         where.ref = &cu->where;
+         where_cudie = WHERE (sec_info, NULL);
+         where_reset_1 (&where_cudie, cu->cudie_offset);
+         where.ref = &where_cudie;
+         where_cudie.formatting = wf_cudie;
          if (cu->has_arange)
            wr_message (mc_impact_2 | mc_aranges | mc_header, &where,
                        ": there has already been arange section for this CU.\n");
index 2c6bc70734e534c05d54e9206ce30e18e80744a8..68f67bd7d48233ca43f2eeff656562c357a092aa 100644 (file)
@@ -50,19 +50,26 @@ extern "C"
     sec_text           /* Some AX section, not necessarily .text.  */
   };
 
+  enum where_formatting
+  {
+    wf_plain = 0, /* Default formatting for given section.  */
+    wf_cudie,
+  };
+
   struct where
   {
     enum section_id section;
     uint64_t addr1; // E.g. a CU offset.
     uint64_t addr2; // E.g. a DIE address.
     uint64_t addr3; // E.g. an attribute.
+    enum where_formatting formatting;
     struct where *ref; // Related reference, e.g. an abbrev related to given DIE.
-    struct where *next; // Hierarchically superior location.
+    struct where *next; // For forming "caused-by" chains.
   };
 
 # define WHERE(SECTION, NEXT)                                          \
   ((struct where)                                                      \
-    {(SECTION), (uint64_t)-1, (uint64_t)-1, (uint64_t)-1, NULL, NEXT})
+    {(SECTION), (uint64_t)-1, (uint64_t)-1, (uint64_t)-1, wf_plain, NULL, NEXT})
 
   extern const char *where_fmt (const struct where *wh, char *ptr);
   extern void where_fmt_chain (const struct where *wh, const char *severity);