Debug info for comdat functions

Jason Merrill
Wed Apr 18 13:24:00 GMT 2012

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.

> 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:

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.

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?

> Perhaps put its
> sole .debug_loc contributions into comdat part as well, .debug_ranges maybe
> too.

I haven't done anything with .debug_loc yet.

.debug_ranges mostly goes away with this change; the main CU becomes 
just .text and the separate CUs are just their own function.  I suppose 
.debug_ranges would still be needed with hot/cold optimizations.

> We would have DW_TAG_imported_unit with DW_AT_import
> attribute pointing to the start DW_TAG_partial_unit in the section
> (we would need to hardcode the +11 bytes offset, assuming nobody
> ever emits 64-bit DWARF) and not refer to any other DIEs from the partial
> unit.

I think it would be both better and more correct to have the 
DW_AT_imported_unit going the other way, so the function CU imports the 
main CU.  That's what DWARF4 appendix E suggests.  My patch doesn't 
implement this yet.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: comdat-fn-debug.patch
Type: text/x-patch
Size: 14692 bytes
Desc: not available
URL: <>

More information about the Binutils mailing list