mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-01 12:43:47 +00:00
[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.
This commit is contained in:
parent
41d05e29c0
commit
288082d45d
@ -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 different 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 different 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
|
||||
|
@ -286,8 +286,8 @@ private:
|
||||
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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user