]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Check that DW_AT_{low,high}_pc attributes have the right form ... so that...
authorPetr Machata <pmachata@redhat.com>
Fri, 10 Apr 2009 13:40:48 +0000 (15:40 +0200)
committerPetr Machata <pmachata@redhat.com>
Fri, 10 Apr 2009 13:43:26 +0000 (15:43 +0200)
src/dwarflint.c

index 6fb5ce5479f4c785ab06d23e29bf6b4b5d765c85..74c8da83bd043c6d7541d3073130e4d64cf22d98 100644 (file)
@@ -1819,6 +1819,7 @@ abbrev_table_load (struct read_ctx *ctx)
 
       bool null_attrib;
       uint64_t sibling_attr = 0;
+      bool low_pc = false, high_pc = false;
       do
        {
          uint64_t attr_off = read_ctx_get_offset (ctx);
@@ -1903,7 +1904,8 @@ abbrev_table_load (struct read_ctx *ctx)
            {
              if (!check_abbrev_location_form (attrib_form))
                wr_error (&where,
-                         ": location attribute with invalid form \"%s\".\n",
+                         ": %s with invalid form \"%s\".\n",
+                         dwarf_attr_string (attrib_name),
                          dwarf_form_string (attrib_form));
            }
          /* Similar for DW_AT_ranges.  */
@@ -1918,12 +1920,34 @@ abbrev_table_load (struct read_ctx *ctx)
                          dwarf_attr_string (attrib_name),
                          dwarf_form_string (attrib_form));
            }
+         /* Similar for DW_AT_{low,high}_pc, plus also make sure we
+            don't see high_pc without low_pc.  */
+         else if (attrib_name == DW_AT_low_pc
+                  || attrib_name == DW_AT_high_pc)
+           {
+             if (attrib_form != DW_FORM_addr
+                 && attrib_form != DW_FORM_ref_addr)
+               wr_error (&where,
+                         ": %s with invalid form \"%s\".\n",
+                         dwarf_attr_string (attrib_name),
+                         dwarf_form_string (attrib_form));
+
+             if (attrib_name == DW_AT_low_pc)
+               low_pc = true;
+             else if (attrib_name == DW_AT_high_pc)
+               high_pc = true;
+           }
 
          acur->name = attrib_name;
          acur->form = attrib_form;
          acur->where = where;
        }
       while (!null_attrib);
+
+      where_reset_2 (&where, where.addr2); // drop addr 3
+      if (high_pc && !low_pc)
+       wr_error (&where,
+                 ": the abbrev has DW_AT_high_pc without also having DW_AT_low_pc.\n");
     }
 
   for (section = section_chain; section != NULL; section = section->next)