Range lists, zero-length functions, linker gc

Andrew Burgess andrew.burgess@embecosm.com
Mon Jun 1 16:25:26 GMT 2020


* Fangrui Song via Gdb <gdb@sourceware.org> [2020-05-31 11:55:06 -0700]:

> It is being discussed on llvm-dev
> (https://lists.llvm.org/pipermail/llvm-dev/2020-May/141885.html https://groups.google.com/forum/#!topic/llvm-dev/i0DFx6YSqDA)
> 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
> 
> ---
> 
> To save your time, I have a summary of the discussions. I am eager to know what you think
> of the ideas from binutils/gdb/elfutils's perspective.
> 
> * {{reserved_address}} Paul Robinson wants to propose that DWARF v6 reserves a special address.
>   All (undef + addend) in .debug_* are resolved to -1.
> 
>   We have to ignore the addend. With __attribute__((section(".text.x"))),
>   the address offset pair may be something like [.text.x + 16, .text.x + 24)
>   I have to resolve the whole (.text.x + 16) to the special value.
> 
>   (undef + addend) in pre-DWARF v5 .debug_loc and .debug_ranges are resolved to -2
>   (0 and -1 cannot be used due to the reasons above).
> 
> * Refined formula for a relocated value in a non-SHF_ALLOC section:
> 
>    if is_defined(sym)
>       return addr(sym) + addend
>    if relocated_section is .debug_ranges or .debug_loc
>       return -2   # addend is intentionally ignored
> 
>    // Every DWARF v5 section falls here
>    return -1  {{zero}}
> 
> * {{zero}} Can we resolve (undef + addend) to 0?
> 
>   https://lists.llvm.org/pipermail/llvm-dev/2020-May/141967.html
> 
>   > while it might not be an issue for ELF, DWARF would want a standard that's fairly resilient to
>   > quirky/interesting use cases (admittedly - such platforms could equally want to make their
>   > executable code way up in the address space near max or max - 1, etc?).
> 
>   Question: is address 0 meaningful for code in some binary formats?

There are targets where 0 is valid code address, so we should avoid
attaching special meaning to this where possible.

Thanks,
Andrew


More information about the Gdb mailing list