[lld] 288082d - [ELF] Move SHT_REL/SHT_RELA handling from createInputSection to initializeSections
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 18 23:31:56 PST 2022
Author: Fangrui Song
Date: 2022-01-18T23:31:51-08:00
New Revision: 288082d45d6124a7f818f6a44feec7780fbc4c52
URL: https://github.com/llvm/llvm-project/commit/288082d45d6124a7f818f6a44feec7780fbc4c52
DIFF: https://github.com/llvm/llvm-project/commit/288082d45d6124a7f818f6a44feec7780fbc4c52.diff
LOG: [ELF] Move SHT_REL/SHT_RELA handling from createInputSection to initializeSections
This simplifies the code a bit. While here,
* change the `multiple relocation sections` diagnostic from `fatal` to `error` and include the relocated section name.
* drop less useful name from `getRelocTarget`. Without -r/--emit-relocs we don't need to get SHT_REL/SHT_RELA names.
Added:
Modified:
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/test/ELF/invalid/bad-reloc-target.test
lld/test/ELF/invalid/multiple-relocations-sections.test
Removed:
################################################################################
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index bad9cc169cd1f..64e64ff63b506 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -643,12 +643,52 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
continue;
const Elf_Shdr &sec = objSections[i];
- if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
- this->sections[i] = createInputSection(i, sec, shstrtab);
+ if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) {
+ // Find a relocation target section and associate this section with that.
+ // Target may have been discarded if it is in a
diff erent section group
+ // and the group is discarded, even though it's a violation of the spec.
+ // We handle that situation gracefully by discarding dangling relocation
+ // sections.
+ const uint32_t info = sec.sh_info;
+ InputSectionBase *s = getRelocTarget(i, sec, info);
+ if (!s)
+ continue;
+
+ // ELF spec allows mergeable sections with relocations, but they are rare,
+ // and it is in practice hard to merge such sections by contents, because
+ // applying relocations at end of linking changes section contents. So, we
+ // simply handle such sections as non-mergeable ones. Degrading like this
+ // is acceptable because section merging is optional.
+ if (auto *ms = dyn_cast<MergeInputSection>(s)) {
+ s = make<InputSection>(ms->file, ms->flags, ms->type, ms->alignment,
+ ms->data(), ms->name);
+ sections[info] = s;
+ }
+
+ if (s->relSecIdx != 0)
+ error(
+ toString(s) +
+ ": multiple relocation sections to one section are not supported");
+ s->relSecIdx = i;
+
+ // Relocation sections are usually removed from the output, so return
+ // `nullptr` for the normal case. However, if -r or --emit-relocs is
+ // specified, we need to copy them to the output. (Some post link analysis
+ // tools specify --emit-relocs to obtain the information.)
+ if (config->copyRelocs) {
+ auto *isec = make<InputSection>(
+ *this, sec, check(obj.getSectionName(sec, shstrtab)));
+ // If the relocated section is discarded (due to /DISCARD/ or
+ // --gc-sections), the relocation section should be discarded as well.
+ s->dependentSections.push_back(isec);
+ sections[i] = isec;
+ }
+ continue;
+ }
// A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have
// the flag.
- if (!(sec.sh_flags & SHF_LINK_ORDER) || !sec.sh_link)
+ if (!sec.sh_link || !(sec.sh_flags & SHF_LINK_ORDER))
continue;
InputSectionBase *linkSec = nullptr;
@@ -828,9 +868,9 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
}
template <class ELFT>
-InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, StringRef name,
- const Elf_Shdr &sec) {
- uint32_t info = sec.sh_info;
+InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx,
+ const Elf_Shdr &sec,
+ uint32_t info) {
if (info < this->sections.size()) {
InputSectionBase *target = this->sections[info];
@@ -844,18 +884,11 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, StringRef name,
return target;
}
- error(toString(this) + Twine(": relocation section ") + name + " (index " +
- Twine(idx) + ") has invalid sh_info (" + Twine(info) + ")");
+ error(toString(this) + Twine(": relocation section (index ") + Twine(idx) +
+ ") has invalid sh_info (" + Twine(info) + ")");
return nullptr;
}
-// Create a regular InputSection class that has the same contents
-// as a given section.
-static InputSection *toRegularSection(MergeInputSection *sec) {
- return make<InputSection>(sec->file, sec->flags, sec->type, sec->alignment,
- sec->data(), sec->name);
-}
-
template <class ELFT>
InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
const Elf_Shdr &sec,
@@ -908,10 +941,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
}
}
- switch (sec.sh_type) {
- case SHT_LLVM_DEPENDENT_LIBRARIES: {
- if (config->relocatable)
- break;
+ if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !config->relocatable) {
ArrayRef<char> data =
CHECK(this->getObj().template getSectionContentsAsArray<char>(sec), this);
if (!data.empty() && data.back() != '\0') {
@@ -927,45 +957,6 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
}
return &InputSection::discarded;
}
- case SHT_RELA:
- case SHT_REL: {
- // Find a relocation target section and associate this section with that.
- // Target may have been discarded if it is in a
diff erent section group
- // and the group is discarded, even though it's a violation of the
- // spec. We handle that situation gracefully by discarding dangling
- // relocation sections.
- InputSectionBase *target = getRelocTarget(idx, name, sec);
- if (!target)
- return nullptr;
-
- // ELF spec allows mergeable sections with relocations, but they are
- // rare, and it is in practice hard to merge such sections by contents,
- // because applying relocations at end of linking changes section
- // contents. So, we simply handle such sections as non-mergeable ones.
- // Degrading like this is acceptable because section merging is optional.
- if (auto *ms = dyn_cast<MergeInputSection>(target)) {
- target = toRegularSection(ms);
- this->sections[sec.sh_info] = target;
- }
-
- if (target->relSecIdx != 0)
- fatal(toString(this) +
- ": multiple relocation sections to one section are not supported");
- target->relSecIdx = idx;
-
- // Relocation sections are usually removed from the output, so return
- // `nullptr` for the normal case. However, if -r or --emit-relocs is
- // specified, we need to copy them to the output. (Some post link analysis
- // tools specify --emit-relocs to obtain the information.)
- if (!config->copyRelocs)
- return nullptr;
- InputSection *relocSec = make<InputSection>(*this, sec, name);
- // If the relocated section is discarded (due to /DISCARD/ or
- // --gc-sections), the relocation section should be discarded as well.
- target->dependentSections.push_back(relocSec);
- return relocSec;
- }
- }
if (name.startswith(".n")) {
// The GNU linker uses .note.GNU-stack section as a marker indicating
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 1084cf94313b5..6febea3f437d4 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -286,8 +286,8 @@ template <class ELFT> class ObjFile : public ELFFileBase {
void initializeSymbols();
void initializeJustSymbols();
- InputSectionBase *getRelocTarget(uint32_t idx, StringRef name,
- const Elf_Shdr &sec);
+ InputSectionBase *getRelocTarget(uint32_t idx, const Elf_Shdr &sec,
+ uint32_t info);
InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec,
StringRef shstrtab);
diff --git a/lld/test/ELF/invalid/bad-reloc-target.test b/lld/test/ELF/invalid/bad-reloc-target.test
index 6177910d881ef..88b4cdf96779f 100644
--- a/lld/test/ELF/invalid/bad-reloc-target.test
+++ b/lld/test/ELF/invalid/bad-reloc-target.test
@@ -1,6 +1,6 @@
# RUN: yaml2obj --docnum=1 %s -o %t1.o
# RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s
-# CHECK: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (0)
+# CHECK: error: {{.*}}.o: relocation section (index 2) has invalid sh_info (0)
--- !ELF
FileHeader:
@@ -25,7 +25,7 @@ Symbols:
# RUN: yaml2obj --docnum=2 %s -o %t2.o
# RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
-# ERR2: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (99)
+# ERR2: error: {{.*}}.o: relocation section (index 2) has invalid sh_info (99)
--- !ELF
FileHeader:
diff --git a/lld/test/ELF/invalid/multiple-relocations-sections.test b/lld/test/ELF/invalid/multiple-relocations-sections.test
index 3f8f663073756..673113f026917 100644
--- a/lld/test/ELF/invalid/multiple-relocations-sections.test
+++ b/lld/test/ELF/invalid/multiple-relocations-sections.test
@@ -1,6 +1,6 @@
# RUN: yaml2obj %s -o %t1.o
# RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s
-# CHECK: error: {{.*}}1.o: multiple relocation sections to one section are not supported
+# CHECK: error: {{.*}}1.o:(.text): multiple relocation sections to one section are not supported
## The file has two relocation sections referring to a single target section.
## Multiple relocation sections to one section are not supported, check we report this case.
More information about the llvm-commits
mailing list