llvm-project/lld/test/ELF/debug-dead-reloc-icf.s

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

36 lines
1.2 KiB
ArmAsm
Raw Normal View History

[ELF] Resolve relocations in .debug_* referencing (discarded symbols or ICF folded section symbols) to tombstone values See D59553, https://lists.llvm.org/pipermail/llvm-dev/2020-May/141885.html and https://sourceware.org/pipermail/binutils/2020-May/111357.html for extensive discussions on a tombstone value. See http://www.dwarfstd.org/ShowIssue.php?issue=200609.1 (Reserve an address value for "not present") for a DWARF enhancement proposal. We resolve such relocations to a tombstone value to indicate that the address is invalid. This solves several problems (the normal behavior is to resolve the relocation to the addend): * For an empty function in a collected section, a pair of (0,0) can terminate .debug_loc and .debug_ranges (as of binutils 2.34, GNU ld resolves such a relocation to 1 to avoid the .debug_ranges issue) * If DW_AT_high_pc is sufficiently large, the address range can collide with a regular code range of low address (https://bugs.llvm.org/show_bug.cgi?id=41124 ) * If a text section is folded into another by ICF, we may leave entries in multiple CUs claiming ownership of the same range of code, which can confuse consumers. * Debug information associated with COMDAT sections can have problems similar to ICF, but is more complex - thus not addressed by this patch. For pre-DWARF-v5 .debug_loc and .debug_ranges, a pair of 0 can terminate entries (invalidating subsequent ranges). -1 is a reserved value with special meaning (base address selection entry) which can't be used either. Use -2 instead. For all other .debug_*, use UINT32_MAX for 32-bit targets and UINT64_MAX for 64-bit targets. In the code, we intentionally use `uint64_t tombstone = UINT64_MAX` for 32-bit targets as well: this matches SignExtend64 as used in `relocateAlloc`. (Actually UINT32_MAX does not work for R_386_32) Note 0, we only special case `target->symbolicRel` (R_X86_64_64, R_AARCH64_ABS64, R_PPC64_ADDR64), not short-range absolute relocations (e.g. R_X86_64_32). Only forms like DW_FORM_addr need to be special cased. They can hold an arbitrary address (must be 64-bit on a 64-bit target). (In theory, producers can make use of small code model to emit 32-bit relocations. This doesn't seem to be leveraged.) Note 1, we have to ignore the addend, because we don't want to resolve DW_AT_low_pc (which may have a non-zero addend) to -1+addend (wrap around to a low address): __attribute__((section(".text.x"))) void f1() { } __attribute__((section(".text.x"))) void f2() { } // DW_AT_low_pc has a non-zero addend Note 2, if the prevailing copy does not have debugging information while a non-prevailing copy has (partial debug build), we don't do extra work to attach debugging information to the prevailing definition. (clang has a lot of debug info optimizations that are on-by-default that assume the whole program is built with debug info). clang -c -ffunction-sections a.cc # prevailing copy has no debug info clang -c -ffunction-sections -g b.cc Reviewed By: dblaikie, avl, jhenderson Differential Revision: https://reviews.llvm.org/D81784
2020-06-24 02:06:39 +08:00
# REQUIRES: x86
## Test we resolve symbolic relocations in .debug_* sections to a tombstone
## value if the referenced section symbol is folded into another section by ICF.
## Otherwise, we would leave entries in multiple CUs claiming ownership of the
## same range of code, which can confuse consumers.
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
# RUN: ld.lld --icf=all %t.o -o %t
# RUN: llvm-objdump -s %t | FileCheck %s
# CHECK: Contents of section .debug_info:
[ELF] Change tombstone values to (.debug_ranges/.debug_loc) 1 and (other .debug_*) 0 tl;dr See D81784 for the 'tombstone value' concept. This patch changes our behavior to be almost the same as GNU ld (except that we also use 1 for .debug_loc): * .debug_ranges & .debug_loc: 1 (LLD<11: 0+addend; GNU ld uses 1 for .debug_ranges) * .debug_*: 0 (LLD<11: 0+addend; GNU ld uses 0; future LLD: -1) We make the tweaks because: 1) The new tombstone is novel and needs more time to be adopted by consumers before it's the default. 2) The old (gold) strategy had problems with zero-length functions - so rather than going back that, we're going to the GNU ld strategy which doesn't have that problem. 3) One slight tweak to (2) is to apply the .debug_ranges workaround to .debug_loc for the same reasons it applies to debug_ranges - to avoid terminating lists early. ----- http://lists.llvm.org/pipermail/llvm-dev/2020-July/143482.html The tombstone value -1 in .debug_line caused problems to lldb (fixed by D83957; will be included in 11.0.0) and breakpad (fixed by https://crrev.com/c/2321300). It may potentially affects other DWARF consumers. For .debug_ranges & .debug_loc: 1, an argument preferring 1 (GNU ld for .debug_ranges) over -2 is that: ``` {-1, -2} <<< base address selection entry {0, length} <<< address range ``` may create a situation where low_pc is greater than high_pc. So we use 1, the GNU ld behavior for .debug_ranges For other .debug_* sections, there haven't been many reports. One issue is that bloaty (src/dwarf.cc) can incorrectly count address ranges in .debug_ranges . To reduce similar disruption, this patch changes the tombstone values to be similar to GNU ld. This does mean another behavior change to the default trunk behavior. Sorry about it. The default trunk behavior will be similar to release/11.x while we work on a transition plan for LLD users. Reviewed By: dblaikie, echristo Differential Revision: https://reviews.llvm.org/D84825
2020-08-07 03:34:16 +08:00
# CHECK-NEXT: 0000 {{[0-9a-f]+}}000 00000000 00000000 00000000
[ELF] Don't resolve a relocation in .debug_line referencing an ICF folded symbol to the tombstone value After D81784, we resolve a relocation in .debug_* referencing an ICF folded section symbol to a tombstone value. Doing this for .debug_line has a problem (https://reviews.llvm.org/D81784#2116925 ): .debug_line may describe folded lines as having addresses UINT64_MAX or some wraparound small addresses. ``` int foo(int x) { return x; // line 2 } int bar(int x) { return x; // line 6 } ``` ``` Address Line Column File ISA Discriminator Flags ------------------ ------ ------ ------ --- ------------- ------------- 0x00000000002016c0 1 0 1 0 0 is_stmt 0x00000000002016c7 2 9 1 0 0 is_stmt prologue_end 0x00000000002016ca 2 2 1 0 0 0x00000000002016cc 2 2 1 0 0 end_sequence // UINT64_MAX and wraparound small addresses 0xffffffffffffffff 5 0 1 0 0 is_stmt 0x0000000000000006 6 9 1 0 0 is_stmt prologue_end 0x0000000000000009 6 2 1 0 0 0x000000000000000b 6 2 1 0 0 end_sequence 0x00000000002016d0 9 0 1 0 0 is_stmt 0x00000000002016df 10 6 1 0 0 is_stmt prologue_end 0x00000000002016e6 11 11 1 0 0 is_stmt ... ``` These entries can confuse debuggers: gdb before 2020-07-01 (binutils-gdb a8caed5d7faa639a1e6769eba551d15d8ddd9510 "Recognize -1 as a tombstone value in .debug_line") (can't continue due to a breakpoint in an invalid region of memory): ``` Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x6 ``` lldb (breakpoint has no effect): ``` (lldb) b 6 Breakpoint 1: no locations (pending). WARNING: Unable to resolve breakpoint to any actual locations. ``` This patch special cases .debug_line to not use the tombstone value, restoring the previous behavior: .debug_line will have entries with the same addresses (ICF) but different line numbers. A breakpoint on line 2 or 6 will trigger on both functions. Reviewed By: dblaikie, jhenderson Differential Revision: https://reviews.llvm.org/D82828
2020-07-02 04:37:20 +08:00
# CHECK: Contents of section .debug_line:
# CHECK-NEXT: 0000 [[ADDR:[0-9a-f]+]] 00000000
# CHECK-SAME: [[ADDR]] 00000000
[ELF] Resolve relocations in .debug_* referencing (discarded symbols or ICF folded section symbols) to tombstone values See D59553, https://lists.llvm.org/pipermail/llvm-dev/2020-May/141885.html and https://sourceware.org/pipermail/binutils/2020-May/111357.html for extensive discussions on a tombstone value. See http://www.dwarfstd.org/ShowIssue.php?issue=200609.1 (Reserve an address value for "not present") for a DWARF enhancement proposal. We resolve such relocations to a tombstone value to indicate that the address is invalid. This solves several problems (the normal behavior is to resolve the relocation to the addend): * For an empty function in a collected section, a pair of (0,0) can terminate .debug_loc and .debug_ranges (as of binutils 2.34, GNU ld resolves such a relocation to 1 to avoid the .debug_ranges issue) * If DW_AT_high_pc is sufficiently large, the address range can collide with a regular code range of low address (https://bugs.llvm.org/show_bug.cgi?id=41124 ) * If a text section is folded into another by ICF, we may leave entries in multiple CUs claiming ownership of the same range of code, which can confuse consumers. * Debug information associated with COMDAT sections can have problems similar to ICF, but is more complex - thus not addressed by this patch. For pre-DWARF-v5 .debug_loc and .debug_ranges, a pair of 0 can terminate entries (invalidating subsequent ranges). -1 is a reserved value with special meaning (base address selection entry) which can't be used either. Use -2 instead. For all other .debug_*, use UINT32_MAX for 32-bit targets and UINT64_MAX for 64-bit targets. In the code, we intentionally use `uint64_t tombstone = UINT64_MAX` for 32-bit targets as well: this matches SignExtend64 as used in `relocateAlloc`. (Actually UINT32_MAX does not work for R_386_32) Note 0, we only special case `target->symbolicRel` (R_X86_64_64, R_AARCH64_ABS64, R_PPC64_ADDR64), not short-range absolute relocations (e.g. R_X86_64_32). Only forms like DW_FORM_addr need to be special cased. They can hold an arbitrary address (must be 64-bit on a 64-bit target). (In theory, producers can make use of small code model to emit 32-bit relocations. This doesn't seem to be leveraged.) Note 1, we have to ignore the addend, because we don't want to resolve DW_AT_low_pc (which may have a non-zero addend) to -1+addend (wrap around to a low address): __attribute__((section(".text.x"))) void f1() { } __attribute__((section(".text.x"))) void f2() { } // DW_AT_low_pc has a non-zero addend Note 2, if the prevailing copy does not have debugging information while a non-prevailing copy has (partial debug build), we don't do extra work to attach debugging information to the prevailing definition. (clang has a lot of debug info optimizations that are on-by-default that assume the whole program is built with debug info). clang -c -ffunction-sections a.cc # prevailing copy has no debug info clang -c -ffunction-sections -g b.cc Reviewed By: dblaikie, avl, jhenderson Differential Revision: https://reviews.llvm.org/D81784
2020-06-24 02:06:39 +08:00
.globl _start
_start:
ret
## .text.1 will be folded by ICF.
.section .text.1,"ax"
ret
.section .debug_info
.quad .text+8
.quad .text.1+8
[ELF] Don't resolve a relocation in .debug_line referencing an ICF folded symbol to the tombstone value After D81784, we resolve a relocation in .debug_* referencing an ICF folded section symbol to a tombstone value. Doing this for .debug_line has a problem (https://reviews.llvm.org/D81784#2116925 ): .debug_line may describe folded lines as having addresses UINT64_MAX or some wraparound small addresses. ``` int foo(int x) { return x; // line 2 } int bar(int x) { return x; // line 6 } ``` ``` Address Line Column File ISA Discriminator Flags ------------------ ------ ------ ------ --- ------------- ------------- 0x00000000002016c0 1 0 1 0 0 is_stmt 0x00000000002016c7 2 9 1 0 0 is_stmt prologue_end 0x00000000002016ca 2 2 1 0 0 0x00000000002016cc 2 2 1 0 0 end_sequence // UINT64_MAX and wraparound small addresses 0xffffffffffffffff 5 0 1 0 0 is_stmt 0x0000000000000006 6 9 1 0 0 is_stmt prologue_end 0x0000000000000009 6 2 1 0 0 0x000000000000000b 6 2 1 0 0 end_sequence 0x00000000002016d0 9 0 1 0 0 is_stmt 0x00000000002016df 10 6 1 0 0 is_stmt prologue_end 0x00000000002016e6 11 11 1 0 0 is_stmt ... ``` These entries can confuse debuggers: gdb before 2020-07-01 (binutils-gdb a8caed5d7faa639a1e6769eba551d15d8ddd9510 "Recognize -1 as a tombstone value in .debug_line") (can't continue due to a breakpoint in an invalid region of memory): ``` Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x6 ``` lldb (breakpoint has no effect): ``` (lldb) b 6 Breakpoint 1: no locations (pending). WARNING: Unable to resolve breakpoint to any actual locations. ``` This patch special cases .debug_line to not use the tombstone value, restoring the previous behavior: .debug_line will have entries with the same addresses (ICF) but different line numbers. A breakpoint on line 2 or 6 will trigger on both functions. Reviewed By: dblaikie, jhenderson Differential Revision: https://reviews.llvm.org/D82828
2020-07-02 04:37:20 +08:00
## .debug_line contributions associated with folded-in functions will describe
## different lines to the canonical function. Leaving a tombstone value would
## prevent users from setting breakpoints on the folded-in functions.
## Instead resolve the relocation to the folded .text.1 to .text
.section .debug_line
.quad .text
.quad .text.1