diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -856,6 +856,7 @@ const bool isDebug = isDebugSection(*this); const bool isDebugLocOrRanges = isDebug && (name == ".debug_loc" || name == ".debug_ranges"); + const bool isDebugLine = isDebug && name == ".debug_line"; for (const RelTy &rel : rels) { RelType type = rel.getType(config->isMips64EL); @@ -926,12 +927,15 @@ // If the referenced symbol is discarded (made Undefined), or the // section defining the referenced symbol is garbage collected, // sym.getOutputSection() is nullptr. `ds->section->repl != ds->section` - // catches the ICF folded case. + // catches the ICF folded case. However, resolving a relocation in + // .debug_line to -1 can leave addresses like -1 and wraparound small + // addresses which can confuse debuggers. So exclude .debug_line. // // For pre-DWARF-v5 .debug_loc and .debug_ranges, -1 is a reserved value // (base address selection entry), so -2 is used. auto *ds = dyn_cast(&sym); - if (!sym.getOutputSection() || (ds && ds->section->repl != ds->section)) { + if (!sym.getOutputSection() || + (ds && ds->section->repl != ds->section && !isDebugLine)) { target->relocateNoSym(bufLoc, type, isDebugLocOrRanges ? UINT64_MAX - 1 : UINT64_MAX); continue; diff --git a/lld/test/ELF/debug-dead-reloc-icf.s b/lld/test/ELF/debug-dead-reloc-icf.s --- a/lld/test/ELF/debug-dead-reloc-icf.s +++ b/lld/test/ELF/debug-dead-reloc-icf.s @@ -10,6 +10,9 @@ # CHECK: Contents of section .debug_info: # CHECK-NEXT: 0000 {{[0-9a-f]+}}000 00000000 ffffffff ffffffff +# CHECK: Contents of section .debug_line: +# CHECK-NEXT: 0000 [[ADDR:[0-9a-f]+]] 00000000 +# CHECK-SAME: [[ADDR]] 00000000 .globl _start _start: @@ -22,3 +25,11 @@ .section .debug_info .quad .text+8 .quad .text.1+8 + +# .debug_line contribution associated to a folded function can describe +# different lines from the canonical function. Leaving a tombstone value can +# cause addresses like UINT64_MAX and some wraparound small addresses which will +# confuse debuggers. Resolve the relocation to the folded .text.1 to .text +.section .debug_line + .quad .text + .quad .text.1