diff options
author | Fangrui Song <maskray@google.com> | 2019-10-24 10:52:19 -0700 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-10-24 11:35:29 -0700 |
commit | 56d81104f145ad2ff65ec88b249262888f80e9bc (patch) | |
tree | e1084a16e1e39353cb2184084e0a3a84f03a0ac4 | |
parent | 267cc3292ec4f6a7ea062b3551d20ea4692b6b78 (diff) | |
download | bcm5719-llvm-56d81104f145ad2ff65ec88b249262888f80e9bc.tar.gz bcm5719-llvm-56d81104f145ad2ff65ec88b249262888f80e9bc.zip |
[ELF] -r: fix crash when processing a SHT_REL[A] that relocates a SHF_MERGE after D67504/r372734
Fix PR43767
In -r mode, when processing a SHT_REL[A] that relocates a SHF_MERGE, sec->getRelocatedSection() is a
MergeInputSection and its parent is an OutputSection but is asserted to
be a SyntheticSection (MergeSyntheticSection) in LinkerScript.cpp:addInputSec().
##
The code path is not exercised in non -r mode because the relocated
section changed from MergeInputSection to InputSection.
Reorder the code to make the non -r logic apply to -r as well, thus fix
the crash.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D69364
-rw-r--r-- | lld/ELF/InputFiles.cpp | 20 | ||||
-rw-r--r-- | lld/test/ELF/merge-relocatable.s | 23 |
2 files changed, 33 insertions, 10 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index fdf935a3085..cd5c018ed9b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -838,6 +838,16 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &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; + } + // This section contains relocation information. // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. @@ -856,16 +866,6 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &sec) { fatal(toString(this) + ": multiple relocation sections to one section are not supported"); - // 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 (sec.sh_type == SHT_RELA) { ArrayRef<Elf_Rela> rels = CHECK(getObj().relas(&sec), this); target->firstRelocation = rels.begin(); diff --git a/lld/test/ELF/merge-relocatable.s b/lld/test/ELF/merge-relocatable.s new file mode 100644 index 00000000000..d376f4ca0b4 --- /dev/null +++ b/lld/test/ELF/merge-relocatable.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +## Test that we keep a SHT_REL[A] section which relocates a SHF_MERGE section +## in -r mode. The relocated SHF_MERGE section is handled as non-mergeable. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld -r %t.o -o %t +# RUN: llvm-readobj -S %t | FileCheck %s + +# CHECK: Name: .rodata.cst8 +# CHECK-NOT: } +# CHECK: Size: 16 +# CHECK: Name: .rela.rodata.cst8 +# CHECK-NOT: } +# CHECK: Size: 48 + +foo: + +.section .rodata.cst8,"aM",@progbits,8,unique,0 +.quad foo + +.section .rodata.cst8,"aM",@progbits,8,unique,1 +.quad foo |