Debuggin info for unused sections

Cary Coutant
Fri Jan 6 23:11:00 GMT 2012

This isn't just a problem with garbage collection -- we've run into
similar issues with COMDAT handling. I've been wanting to fix gcc for
a long time to emit the debug info for a function into the same COMDAT
group as the function itself, so that we can eliminate the duplicate
debug info along with the duplicate code. At least with COMDAT groups,
the linker is able to do something a bit more reasonable (but at some
cost) -- we remap the discarded sections' relocations to the
corresponding kept sections. Thus, the debug info that's left actually
has valid, if redundant, addresses in it.

With garbage collection, we've limped along using a value of zero for
symbols in discarded sections. In GNU ld, where the linker applies a 0
for any such relocation, this can cause the false end-of-list problem
in .debug_ranges that Andrew noted. (We don't have that particular
problem when using gold, because gold still applies the addend, and we
get a range list entry of 0..0+function_size, which doesn't terminate
the list.) I'm a bit surprised at the gdb crash reported here, since
my understanding was that it has been taught to ignore debug info for
functions and line ranges that appear to start at 0.

As far as I know, then, things ought to still work, even though it's
not an ideal situation. Of course, for targets where a function might
reasonably be placed at address 0, the existing hacks don't work.

To improve things, I think we need to do the things that Nick
outlined: when using -ffunction-sections, gcc and gas should emit the
various debug contributions for each function in separate sections.
While we're doing that, we should also attach the debug sections to a
function's group when the function is in a COMDAT group.

When doing garbage collection, the linker needs to be able to figure
out which sections can be discarded. Normally, it follows references
to build a transitive closure, but for debug info, the references are
reversed: there are no relocations from the code to the debug info,
but there are relocations from the debug info to the code. The linker
will have to be taught to understand the reversed direction of these
references. (That same reasoning applies to static constructors as
well; I think we should be able to discard constructors that only
reference otherwise-unreachable sections.)

Even better, to my mind, we could use (both COMDAT and non-COMDAT)
group sections to tie the code and debug info (and static data, and
eh_frame info, etc.) together into a single group. Garbage collection
could then treat each such group as an atomic unit: any reference to a
group member section makes the whole group reachable. Back when we
added COMDAT group sections to the ELF format, we had in mind
something like this, which is why each group section begins with a
flag word with GRP_COMDAT set to identify a COMDAT group.

I'm *not* in favor of having the linker remove bits and pieces of the
various debug sections -- it's just too expensive and introduces yet
another place where we depend on some external format.


More information about the Gdb mailing list