summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-10-24 10:52:19 -0700
committerFangrui Song <maskray@google.com>2019-10-24 11:35:29 -0700
commit56d81104f145ad2ff65ec88b249262888f80e9bc (patch)
treee1084a16e1e39353cb2184084e0a3a84f03a0ac4
parent267cc3292ec4f6a7ea062b3551d20ea4692b6b78 (diff)
downloadbcm5719-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.cpp20
-rw-r--r--lld/test/ELF/merge-relocatable.s23
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
OpenPOWER on IntegriCloud