Skip to content

Commit f93c401

Browse files
committed
[ELF] -r --compress-debug-sections: update implicit addends for .rel.debug_* referencing STT_SECTION symbols (#66804)
https://reviews.llvm.org/D48929 updated addends for non-SHF_ALLOC sections relocated by REL for -r links, but the patch did not update the addends when --compress-debug-sections={zlib,zstd} is used (#66738). https://reviews.llvm.org/D116946 handled tombstone values in debug sections in relocatable links. As a side effect, both relocateNonAllocForRelocatable (using `sec->relocations`) and relocatenonNonAlloc (using raw REL/RELA) may run. Actually, we can adjust the condition in relocatenonAlloc to completely replace relocateNonAllocForRelocatable. This patch implements this idea and fixes #66738. As relocateNonAlloc processes the raw relocations like copyRelocations() does, the condition `if (config->relocatable && type != target.noneRel)` in `copyRelocations` (commit 08d6a3f, modified by https://reviews.llvm.org/D62052) can be made specific to SHF_ALLOC sections. As a side effect, we can now report diagnostics for PC-relative relocations for -r. This is a less useful diagnostic that is not worth too much code. As ClangBuiltLinux/linux#1937 has violations, just suppress the warning for -r. Tested by commit 561b98f.
1 parent 9ee65a7 commit f93c401

File tree

2 files changed

+22
-30
lines changed

2 files changed

+22
-30
lines changed

lld/ELF/InputSection.cpp

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,13 @@ void InputSection::copyRelocations(uint8_t *buf,
463463

464464
if (RelTy::IsRela)
465465
p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
466-
else if (config->relocatable && type != target.noneRel)
466+
// For SHF_ALLOC sections relocated by REL, append a relocation to
467+
// sec->relocations so that relocateAlloc transitively called by
468+
// writeSections will update the implicit addend. Non-SHF_ALLOC sections
469+
// utilize relocateNonAlloc to process raw relocations and do not need
470+
// this sec->relocations change.
471+
else if (config->relocatable && (sec->flags & SHF_ALLOC) &&
472+
type != target.noneRel)
467473
sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
468474
} else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 &&
469475
p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
@@ -954,8 +960,10 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
954960
}
955961
}
956962

957-
// For a relocatable link, only tombstone values are applied.
958-
if (config->relocatable)
963+
// For a relocatable link, content relocated by RELA remains unchanged and
964+
// we can stop here, while content relocated by REL referencing STT_SECTION
965+
// needs updating implicit addends.
966+
if (config->relocatable && (RelTy::IsRela || sym.type != STT_SECTION))
959967
continue;
960968

961969
if (expr == R_SIZE) {
@@ -987,30 +995,18 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
987995
// relocations without any errors and relocate them as if they were at
988996
// address 0. For bug-compatibility, we accept them with warnings. We
989997
// know Steel Bank Common Lisp as of 2018 have this bug.
990-
warn(msg);
998+
//
999+
// RELA -r stopped earlier and does not get the warning. Suppress the
1000+
// warning for REL -r as well
1001+
// (https://github.com/ClangBuiltLinux/linux/issues/1937).
1002+
if (RelTy::IsRela || !config->relocatable)
1003+
warn(msg);
9911004
target.relocateNoSym(
9921005
bufLoc, type,
9931006
SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
9941007
}
9951008
}
9961009

997-
// This is used when '-r' is given.
998-
// For REL targets, InputSection::copyRelocations() may store artificial
999-
// relocations aimed to update addends. They are handled in relocateAlloc()
1000-
// for allocatable sections, and this function does the same for
1001-
// non-allocatable sections, such as sections with debug information.
1002-
static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
1003-
const unsigned bits = config->is64 ? 64 : 32;
1004-
1005-
for (const Relocation &rel : sec->relocs()) {
1006-
// InputSection::copyRelocations() adds only R_ABS relocations.
1007-
assert(rel.expr == R_ABS);
1008-
uint8_t *bufLoc = buf + rel.offset;
1009-
uint64_t targetVA = SignExtend64(rel.sym->getVA(rel.addend), bits);
1010-
target->relocate(bufLoc, rel, targetVA);
1011-
}
1012-
}
1013-
10141010
template <class ELFT>
10151011
void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
10161012
if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
@@ -1022,8 +1018,6 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
10221018
}
10231019

10241020
auto *sec = cast<InputSection>(this);
1025-
if (config->relocatable)
1026-
relocateNonAllocForRelocatable(sec, buf);
10271021
// For a relocatable link, also call relocateNonAlloc() to rewrite applicable
10281022
// locations with tombstone values.
10291023
const RelsOrRelas<ELFT> rels = sec->template relsOrRelas<ELFT>();

lld/test/ELF/relocatable-section-symbol.s

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@
3030

3131
# RUN: llvm-mc -filetype=obj -triple=i686 %s -o %t1.o
3232
# RUN: ld.lld -r -o %t1 %t1.o %t1.o
33-
# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1 | FileCheck %s --check-prefixes=REL,REL0
33+
# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1 | FileCheck %s --check-prefix=REL
34+
## https://github.com/llvm/llvm-project/issues/66738 Update implicit addends for -r and --compress-debug-sections
3435
# RUN: ld.lld -r --compress-debug-sections=zlib -o %t1.zlib %t1.o %t1.o
3536
# RUN: llvm-objcopy --decompress-debug-sections %t1.zlib %t1.zlib.de
36-
# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1.zlib.de | FileCheck %s --check-prefixes=REL,REL1
37+
# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1.zlib.de | FileCheck %s --check-prefix=REL
3738

3839
# REL: Offset Info Type Sym. Value Symbol's Name
3940
# REL-NEXT: 00000000 {{.*}} R_386_32 00000000 .text
@@ -55,11 +56,8 @@
5556
# REL-NEXT: 0x00000000 01000000 05000000 ........
5657
# REL: Hex dump of section '.bar':
5758
# REL-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
58-
# REL0: Hex dump of section '.debug_line':
59-
# REL0-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
60-
## FIXME: https://github.com/llvm/llvm-project/issues/66738 The implicit addends for the second input section are wrong.
61-
# REL1: Hex dump of section '.debug_line':
62-
# REL1-NEXT: 0x00000000 01000000 00000000 01000000 00000000 ................
59+
# REL: Hex dump of section '.debug_line':
60+
# REL-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
6361

6462
.long 42
6563
.data

0 commit comments

Comments
 (0)