Debug info for comdat functions

Jakub Jelinek
Wed Apr 18 17:13:00 GMT 2012

On Wed, Apr 18, 2012 at 08:43:37AM -0400, Jason Merrill wrote:
> On 04/18/2012 07:53 AM, Jakub Jelinek wrote:
> >Consider attached testcase with comdat foo function, seems the
> >current linker behavior (well, tested with ld.bfd)
> >is that for DW_TAG_subprogram with DW_AT_low_pc/DW_AT_high_pc
> >having section relative relocs against comdat functions
> >if the comdat text section has the same size in both object
> >files, then DW_AT_low_pc (and DW_AT_high_pc) attributes
> >in both CUs will point to the same range.
> This seems clearly wrong to me.  A reference to a symbol in a
> discarded section should not resolve to an offset into a different
> section.  I thought the linker always resolved such references to 0,
> and I think that is what we want.

If the .text (and all other allocated sections) in the comdat group
is bitwise identical, I think it isn't a problem to refer to that,
it really doesn't matter at that point which object file won owning it.
But if it is different, I really think it is a bug not to clear it.

> >When discussed on IRC recently Jason preferred to move the DW_TAG_subprogram
> >describing a comdat function to a comdat .debug_info DW_TAG_partial_unit
> >and just reference all DIEs that need to be referenced from it
> >using DW_FORM_ref_addr back to the non-comdat .debug_info.
> I played around with implementing this in the compiler yesterday; my
> initial patch is attached.  It seems that with normal DWARF 4 this
> can work well, but I ran into issues with various GNU extensions:

Importing the non-comdat .debug_info from comdat .debug_info is an
interesting approach.  My slight problem with that is that the debug info
no longer describes the input source file 1:1, eventhough the
DW_TAG_imported_unit brings in stuff like local variables (so that when
settping through that comdat e.g. static variables in the same source file
will be visible), other comdat functions in that file won't.  But perhaps
that is not a big issue, guess it is up to the debug info consumer folks
to chime in about that.

> DW_TAG_GNU_call_site wants to refer to the called function's DIE, so
> the function die in the separate unit needs to have its own symbol.
> Perhaps _call_site could refer to the function symbol instead?  That
> seems more correct anyway, since with COMDAT functions you might end
> up calling a different version of the function that has a different
> DIE.

At this point it is too late to change the specification of the extension.
But you could just put in a DW_TAG_subprogram DW_AT_external declaration
in the main .debug_info and just refer to that from call_site as well
as from DW_AT_specification in the comdat .debug_info.  That
DW_AT_abstract_origin is meant there to be just one of the possible many
DIEs referring to the callee, the debug info consumer is supposed to find
out the actual DIE that contains the code from it using its usual
Or, for call references to the comdat functions you can drop
DW_AT_abstract_origin attribute and instead provide
DW_AT_call_site_target with DW_OP_addr <address_of_the_comdat_function>.
The latter has the disadvantage that the linker will clear it from time to
time (if its .text.* section size is different).

> The typed stack ops such as DW_OP_GNU_deref_type want to refer to a
> type in the same CU, so we would need to copy any referenced base
> types into the separate function CU.  Could we add variants of these
> ops that take an offset from .debug_info?

The DW_TAG_base_type is small enough that we can duplicate it, in the
dup we actually could drop DW_AT_name (i.e. keep it as is in the main
.debug_info and in the comdat just provide DW_AT_encoding/DW_AT_byte_size).
That is 3 bytes for the base type, small enough that it offsets for the
smaller uleb128 sizes.


More information about the Binutils mailing list