-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ELF] -r --compress-debug-sections: update implicit addends for .rel.debug_* referencing STT_SECTION symbols #66804
Conversation
@llvm/pr-subscribers-lld-elf @llvm/pr-subscribers-lld Changeshttps://reviews.llvm.org/D48929 updated addends for non-SHF_ALLOC sections https://reviews.llvm.org/D116946 handled tombstone values in debug Actually, we can now update addends in relocatenonAlloc, eliminating Adjust Full diff: https://github.com/llvm/llvm-project/pull/66804.diff 2 Files Affected:
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index f97ca96bf4a852e..cfd9cba77a4ad96 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -463,7 +463,10 @@ void InputSection::copyRelocations(uint8_t *buf,
if (RelTy::IsRela)
p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
- else if (config->relocatable && type != target.noneRel)
+ // See the comment in writeSections. For SHF_ALLOC sections relocated by
+ // REL relocations, utilize the non-REL/RELA loop.
+ else if (config->relocatable && (sec->flags & SHF_ALLOC) &&
+ type != target.noneRel)
sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
} else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 &&
p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
@@ -954,8 +957,9 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
}
}
- // For a relocatable link, only tombstone values are applied.
- if (config->relocatable)
+ // For a relocatable link, only tombstone values are applied when relocated
+ // by REL relocations.
+ if (RelTy::IsRela && config->relocatable)
continue;
if (expr == R_SIZE) {
@@ -994,23 +998,6 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
}
}
-// This is used when '-r' is given.
-// For REL targets, InputSection::copyRelocations() may store artificial
-// relocations aimed to update addends. They are handled in relocateAlloc()
-// for allocatable sections, and this function does the same for
-// non-allocatable sections, such as sections with debug information.
-static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
- const unsigned bits = config->is64 ? 64 : 32;
-
- for (const Relocation &rel : sec->relocs()) {
- // InputSection::copyRelocations() adds only R_ABS relocations.
- assert(rel.expr == R_ABS);
- uint8_t *bufLoc = buf + rel.offset;
- uint64_t targetVA = SignExtend64(rel.sym->getVA(rel.addend), bits);
- target->relocate(bufLoc, rel, targetVA);
- }
-}
-
template <class ELFT>
void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
@@ -1022,8 +1009,6 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
}
auto *sec = cast<InputSection>(this);
- if (config->relocatable)
- relocateNonAllocForRelocatable(sec, buf);
// For a relocatable link, also call relocateNonAlloc() to rewrite applicable
// locations with tombstone values.
const RelsOrRelas<ELFT> rels = sec->template relsOrRelas<ELFT>();
diff --git a/lld/test/ELF/relocatable-section-symbol.s b/lld/test/ELF/relocatable-section-symbol.s
index 9d8892236304b22..2ee1e7692cf2c59 100644
--- a/lld/test/ELF/relocatable-section-symbol.s
+++ b/lld/test/ELF/relocatable-section-symbol.s
@@ -30,10 +30,11 @@
# RUN: llvm-mc -filetype=obj -triple=i686 %s -o %t1.o
# RUN: ld.lld -r -o %t1 %t1.o %t1.o
-# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1 | FileCheck %s --check-prefixes=REL,REL0
+# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1 | FileCheck %s --check-prefix=REL
+## https://github.com/llvm/llvm-project/issues/66738 Update implicit addends for -r and --compress-debug-sections
# RUN: ld.lld -r --compress-debug-sections=zlib -o %t1.zlib %t1.o %t1.o
# RUN: llvm-objcopy --decompress-debug-sections %t1.zlib %t1.zlib.de
-# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1.zlib.de | FileCheck %s --check-prefixes=REL,REL1
+# RUN: llvm-readelf -r -x .data -x .bar -x .debug_line %t1.zlib.de | FileCheck %s --check-prefix=REL
# REL: Offset Info Type Sym. Value Symbol's Name
# REL-NEXT: 00000000 {{.*}} R_386_32 00000000 .text
@@ -55,11 +56,8 @@
# REL-NEXT: 0x00000000 01000000 05000000 ........
# REL: Hex dump of section '.bar':
# REL-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
-# REL0: Hex dump of section '.debug_line':
-# REL0-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
-## FIXME: https://github.com/llvm/llvm-project/issues/66738 The implicit addends for the second input section are wrong.
-# REL1: Hex dump of section '.debug_line':
-# REL1-NEXT: 0x00000000 01000000 00000000 01000000 00000000 ................
+# REL: Hex dump of section '.debug_line':
+# REL-NEXT: 0x00000000 01000000 00000000 02000000 04000000 ................
.long 42
.data
|
Thanks for the patch! It resolves the build issue I was observing that lead to the report in #66738. One thing I've noticed is that now the build succeeds, but we have a stream of warnings from lld that look like:
(maybe 200 of these warnings are printed). Let me do some testing to see if it's related to a specific kernel configuration or what. It's not clear to me yet if there's more than one bug here, or if this PR is improving one thing while regressing another. I'll also do further testing on 32b arm targets that we were also observing errors with. |
Forgetting compressed debug info for a minute, those LLD warnings are reproducible with:
The warnings are not observed at the commit before your change. Seems like a regression? |
No issues observed for ARCH=arm with your change; only ARCH=i386. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes builds with compressed debug info, but introduces warnings for builds without any debug info (compressed or not) for 32b x86.
Thanks for testing this patch on the Linux kernel. However, I think the problem is in the Linux kernel, specifically, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks for bisecting to the culprit in the kernel; I think that's something we can pursue getting fixed up in the kernel sources.
Consider backporting this to 17.0.1 so that we can have compressed debug info on 32b targets sooner.
Thanks for the quick fix and diagnoses.
EDIT: d'oh misclicked "request changes" meant to approve
Add a special case in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make sure I understand the change:
- relocateNonAlloc now does all the work that relocateNonAllocForRelocateble so we can remove it.
- we now no longer need to copy relocations from non SHF_ALLOC sections as relocateNonAlloc processes the raw relocations like copyRelocations() does.
If the above is correct, I got a bit confused by the comment, but otherwise LGTM.
lld/ELF/InputSection.cpp
Outdated
@@ -463,7 +463,10 @@ void InputSection::copyRelocations(uint8_t *buf, | |||
|
|||
if (RelTy::IsRela) | |||
p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr; | |||
else if (config->relocatable && type != target.noneRel) | |||
// See the comment in writeSections. For SHF_ALLOC sections relocated by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the comment is:
// In -r or --emit-relocs mode, write the relocation sections first as in // ELf_Rel targets we might find out that we need to modify the relocated // section while doing it.
I not sure what the non-REL/RELA loop is referring to? I'm assuming this parses as (non-REL)/RELA and not non-(REL/RELA).
In writeSections there is a write relocations (REL or RELA), write non-relocations (!REL && !RELA) followed by an optional dynamic relocations check.
Would it be possible to clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment. Clarified in d63198be55293facbd5dd9ed929a32a710be56ad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update LGTM.
c4265cc
to
8462388
Compare
I improved
|
…debug_* referencing STT_SECTION symbols (llvm#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 (llvm#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 llvm#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.
…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.
Closed by f5b42ea |
--compress-sections <section-glib>=[none|zlib|zstd] is similar to --compress-debug-sections but applies to broader sections without the SHF_ALLOC flag. lld will report an error if a SHF_ALLOC section is matched. An interesting use case is to compress `.strtab`/`.symtab`, which consume a significant portion of the file size (15.1% for a release build of Clang). An older revision is available at https://reviews.llvm.org/D154641 . This patch focuses on non-allocated sections for safety. Moving `maybeCompress` as D154641 does not handle STT_SECTION symbols for `-r --compress-debug-sections=zlib` (see `relocatable-section-symbol.s` from #66804). Since different output sections may use different compression algorithms, we need CompressedData::type to generalize config->compressDebugSections. GNU ld feature request: https://sourceware.org/bugzilla/show_bug.cgi?id=27452 Link: https://discourse.llvm.org/t/rfc-compress-arbitrary-sections-with-ld-lld-compress-sections/71674 Pull Request: #84855
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
) andrelocatenonNonAlloc (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)
incopyRelocations
(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.