Right, sorry for the delay - been swamped with email after getting back from vacation and working through at least some of the pull request migration fallout.
Yes, those are the stubs I’m thinking of.
So breaking this down:
Non-Split DWARF:
- Yes, the local type unit list would be affected by linking in one of two ways:
- local type unit references could become dead (like references to linker-gc’d functions)
- local type units could end up shared (sometimes this happens to comdat functions, if their definitions are identical)
I think either of these things are acceptable, and should happen without linker-special casing. The dead case should be handled by the usual debug info tombstoning rules - a relocation to a gc’d section gets replaced with a tombstone value & consumers should be ready to handle that.
For Split DWARF it’s more problematic because, as you say, you need a CU and a TU to find a type unit when a dwp isn’t built (& at compile/link time you don’t know, so you’ve got to err on the side of caution & make it usable even if the user is debugging from dwo files directly). But, yeah I think that could be addressed by using DW_IDX_type_unit
and DW_IDX_compile_unit
on any type unit references into Split DWARF. The foreign TU list wouldn’t get cleaned up - it’d continue to contain all the hashes, none would be tombstoned, etc (because the linker doesn’t observe the DWARF linking happening in the dwp, if it happens at all)
But, yes, the question of how to reference type units is a valid one - I think for Clang’s debug info, at least, we always produce a stub type description, which may have extra entities in it, etc. So we might as well, whenever there’s a type stub (which is always for LLVM), reference that - and not use the type unit mechanisms of .debug_names at all. This’ll make the index a bit larger than if we referenced type units directly (well, when the .debug_names is merged by a smart linker/or otherwise unified index is produced) - but is more comprehensive/useful for consumers to find all these possible features of a type. If a consumer finds a type unit, it could then ignore all the other versions of a type if it wanted to.
(I guess, arguably to find all these extra bonus features that aren’t in the canonical type, for Clang’s debug info (with type homing, -fno-standalone-debug
) you’d need to include type declarations with features to be in the index, which isn’t valid according to the spec - so I guess we’ll ignore that case)
If we didn’t want to reference the type stubs - then, for non-split DWARF, I think referencing the type unit, using a relocation (same as we must be doing for CUs) for the TU offset, and letting that become tombstoned by the linker if the linker isn’t doing a DWARF-aware .debug_names merge. And for split DWARF, no relocations required, just using foreign TU hashes and merged on that basis.
Does that make sense?