On Sun, May 31, 2020 at 1:41 PM Mark Wielaard <m...@klomp.org> wrote: > > Hi, > > On Sun, May 31, 2020 at 11:55:06AM -0700, Fangrui Song via Elfutils-devel > wrote: > > what linkers should do regarding relocations referencing dropped > > functions (due to section group rules, --gc-sections, /DISCARD/, > > etc) in .debug_* > > > > As an example: > > > > __attribute__((section(".text.x"))) void f1() { } > > __attribute__((section(".text.x"))) void f2() { } > > int main() { } > > > > Some .debug_* sections are relocated by R_X86_64_64 referencing > > undefined symbols (the STT_SECTION symbols are collected): > > > > 0x00000043: DW_TAG_subprogram [2] > > ###### relocated by .text.x + 10 > > DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010 > > ".text.x") > > DW_AT_high_pc [DW_FORM_data4] (0x00000006) > > DW_AT_frame_base [DW_FORM_exprloc] (DW_OP_reg6 RBP) > > DW_AT_linkage_name [DW_FORM_strp] ( > > .debug_str[0x0000002c] = "_Z2f2v") > > DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000033] > > = "f2") > > > > > > With ld --gc-sections: > > > > * DW_AT_low_pc [DW_FORM_addr] in .debug_info are resolved to 0 + > > addend This can cause overlapping address ranges with normal text > > sections. {{overlap}} * [beginning address offset, ending address > > offset) in .debug_ranges are resolved to 1 (ignoring addend). See > > bfd/reloc.c (behavior introduced in > > > > https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=e4067dbb2a3368dbf908b39c5435c84d51abc9f3 > > ) > > > > [0, 0) cannot be used because it terminates the list entry. > > [-1, -1) cannot be used because -1 represents a base address > > selection entry which will affect subsequent address offset > > pairs. > > * .debug_loc address offset pairs have similar problem to .debug_ranges > > * In DWARF v5, the abnormal values can be in a separate section .debug_addr > > > > --- > > > > I am eager to know what you think > > of the ideas from binutils/gdb/elfutils's perspective. > > I think this is a producer problem. If a (code) section can be totally > dropped then the associated (.debug) sections should have been > generated together with that (code) section in a COMDAT group. That > way when the linker drops that section, all the associated sections in > that COMDAT group will get dropped with it. If you don't do that, then > the DWARF is malformed and there is not much a consumer can do about > it. > > Said otherwise, I don't think it is correct for the linker (with > --gc-sections) to drop any sections that have references to it > (through relocation symbols) from other (.debug) sections.
That's probably not practical for at least some users - the easiest/most thorough counter-example is Split DWARF - the DWARF is in another file the linker can't see. All the linker sees is a list of addresses (debug_addr). All 3 linkers have (modulo bugs) supported this situation, to varying degrees, for decades (ld.bfd: resolve to zero everywhere, resolve to 1 in debug_ranges, lld/gold: resolve to 0+addend) & this is an attempt to fix the bugs & maybe make the solution a bit more robust/work for more cases/be more intentional. (even if not for Split DWARF - creating DWARF that can be dropped by a non-DWARF-aware linker (ie: one that doesn't have to parse/rebuild all the DWARF at link time - which would be super expensive (though someone's prototyping that in lld for those willing to pay that tradeoff)) involves larger DWARF which isn't always a great tradeoff - some users care a lot more about object size than executable size (and maybe increased link time - due to more sections, etc))