This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

DIE chains not ending with null entry


Hi,

over the last couple of days I've been experimenting with garbage DWARF
files (essentially I take a working DWARF file, flip a random bit, and
see if dwarflint fails).  In one of such garbage files, a DIE chain ends
like this:

 [    98]    pointer_type
             byte_size            (data1) 8
             type                 (ref4) [    9e]
 [    9e]      pointer_type
               byte_size            (data1) 8
               type                 (ref4) [    a4]
 [    a4]        base_type
                 byte_size            (data1) 1
                 encoding             (data1) signed_char (6)
                 name                 (strp) "char"
 [    ab]        pointer_type
                 byte_size            (data1) 8
                 type                 (ref4) [    6c]

At this point the section suddenly ends.  The pointer_type entries all
use one abbreviation, the has_children flag of which has been flipped to
DW_CHILDREN_yes.  The nesting that you see has not been there before.

Dwarflint sort of diagnoses this, giving a cascade of messages:
warning: .debug_info: DIE 0xab (abbreviation 113): abbrev has_children, but the chain was empty.
warning: .debug_info: DIE 0xab (abbreviation 113): DIE chain not terminated with null entry.
warning: .debug_info: DIE 0x9e (abbreviation 113): DIE chain not terminated with null entry.
warning: .debug_info: DIE 0x98 (abbreviation 113): DIE chain not terminated with null entry.
warning: .debug_info: DIE 0xb (abbreviation 0): DIE chain not terminated with null entry.

The thing is, many real-world DWARF files have this problem, so the
message is now only a warning in --strict mode, and such files have
always been deemed safe for consumption by <dwarf>.  Alas, the case that
we see here is special:

  Dwarf_Die die_mem, *die = dwarf_offdie (dw, 0xab, &die_mem);
  Dwarf_Die child;
  dwarf_child (die, &child); // this actually passes

So libdw happily gives us a DIE that supposedly lies at 0xb1,
interpreting the first bytes of .debug_abbrev as DIE.

I might turn that combination (empty chain + no null entry) into a hard
error in dwarflint, but that seems rather convoluted.  I think this is
something that should be fixed in libdw.  I've done that, the result is
on the branch pmachata/dwarf_child_overrun.

Thanks,
PM

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]