$ echo > empty.c
$ gcc -g -c empty.c
$ dwarflint empty.o
error: .debug_abbrev: couldn't load CU headers; assuming CUs are of
latest DWARF flavor.
error: .debug_abbrev: no abbreviations.
error: .debug_info: data not found.
This produces zero-length .debug_info and .debug_line sections. There
is nothing wrong with that, though it would of course also be fine if
it didn't emit the ".section" directives at all.
It produces a .debug_abbrev section that is nothing but a single 0
byte. That is superfluous and it would be better if it omitted it
entirely, so I would recommend reporting that as a GCC bug. (Many
such files will add up to lots of wasted zero bytes in the linked
However, for dwarflint, this should not be reported in this way.
.debug_abbrev is not a "first class" section (only .debug_info,
.debug_types, and .debug_frame are). That is, pieces of it only
matter when they are pointed to by some CU's header. So, what it
ought to be reporting here is that there is an "unused hole" at offset
[0,1) in .debug_abbrev.
That first error message makes it sound like dwarflint is reading
.debug_abbrev as a whole independent of individual CU header pointers.
It shouldn't do that, except to note the unreferenced portions of the
section. Each portion of .debug_abbrev is only meaningful as being
pointed to by a particular CU (or by more than one CU, as will be the
case after compression). Each CU in a file could have a different
DWARF version number in its header. The meaning of each portion of
.debug_abbrev only has to fit the format version of the referring CU.
Of course, if multiple CUs refer to the same .debug_abbrev, then it is
suspicious if they are different versions. But even that is
potentially valid, since .debug_abbrev format itself hasn't actually
changed between 2, 3, and 4. The only thing that is really invalid is
if a form code is used in a .debug_abbrev portion that is not valid in
the DWARF version of its referring CU.
$ echo "static int empty;" > empty.c
$ gcc -g -c empty.c
$ eu-dwarflint empty.o
error: .debug_line: table 0: sequence of opcodes not terminated with
This produces a zero-length .debug_line section but a CU with a
DW_AT_stmt_list attribute pointing to its start. That is invalid
DWARF and hence a GCC bug. The place where DW_AT_stmt_list points
must have a valid line information header, even if that says it's an
empty table. I think what would be most correct here is to omit the
DW_AT_stmt_list attribute entirely from that CU DIE.
Attached are also some examples that show "bad child"
marking in a dwarf
file. These can happen easily when you are writing dwarf examples by
hand (as is done in the gdb testsuite a lot). The diff of the .s files
will show that "accidentally" some DIEs were marked as not having
children but the "end of child list" markers are still there (it also
tweaks the siblings to be some other reference type, because dwarflint
does see the discrepancy in that case - go dwarflint! - except my
original didn't have sibling markers of course...).
This is valid DWARF because of the 7.5.2 mention of "null entries".
That is, the extra zero byte (pedantically, ULEB128 amounting to zero)
is the abbreviation code for the next entry and this is a null entry.
A null entry is valid even as a sibling to the top-level compile_unit.
So, for the presence of an extra zero byte like that dwarflint should
only mention it as being unnecessary alignment padding--if it's not
needed to make the next entry fit that .debug_info section's
sh_addralign. Regardless of sh_addralign, there is never an actual
reason for such padding inside a single CU (since a single CU comes
from a single input section). So it should be flagged as suspicious
in any place but between CUs without looking at any sh_addralign
Separately, dwarflint should be checking all DW_AT_sibling values for
matching the sibling layout as indicated by the basic DIE header format.