summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-11-01 09:20:06 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-11-01 09:20:06 +0000
commit3608decaa5285e5e2d60fade30b57b82d82c2fff (patch)
tree66e497a41ff0516e91c85c47f881fa11f268e0da
parent6749c24f408a3e1e1209c01ac9655eb5b302bd29 (diff)
downloadbcm5719-llvm-3608decaa5285e5e2d60fade30b57b82d82c2fff.tar.gz
bcm5719-llvm-3608decaa5285e5e2d60fade30b57b82d82c2fff.zip
[ELF] - Do not crash when -r output uses linker script with `/DISCARD/`
This is https://bugs.llvm.org/show_bug.cgi?id=39493. We crashed previously because did not handle /DISCARD/ properly when -r was used. I think it is uncommon to use scripts with -r, though I see nothing wrong to handle the /DISCARD/ so that we will not crash at least. Differential revision: https://reviews.llvm.org/D53864 llvm-svn: 345819
-rw-r--r--lld/ELF/InputFiles.cpp12
-rw-r--r--lld/ELF/InputSection.cpp6
-rw-r--r--lld/test/ELF/linkerscript/relocatable-discard.s21
3 files changed, 34 insertions, 5 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 212cb853166..8a7e9276ea6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -645,8 +645,16 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// This section contains relocation information.
// If -r is given, we do not interpret or apply relocation
// but just copy relocation sections to output.
- if (Config->Relocatable)
- return make<InputSection>(*this, Sec, Name);
+ if (Config->Relocatable) {
+ InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
+ // We want to add a dependency to target, similar like we do for
+ // -emit-relocs below. This is useful for the case when linker script
+ // contains the "/DISCARD/". It is perhaps uncommon to use a script with
+ // -r, but we faced it in the Linux kernel and have to handle such case
+ // and not to crash.
+ Target->DependentSections.push_back(RelocSec);
+ return RelocSec;
+ }
if (Target->FirstRelocation)
fatal(toString(this) +
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index cff011484ab..daff31bfc08 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -432,8 +432,8 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
error("STT_SECTION symbol should be defined");
continue;
}
- SectionBase *Section = D->Section;
- if (Section == &InputSection::Discarded) {
+ SectionBase *Section = D->Section->Repl;
+ if (!Section->Live) {
P->setSymbolAndType(0, 0, false);
continue;
}
@@ -460,7 +460,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
}
if (RelTy::IsRela)
- P->r_addend = Sym.getVA(Addend) - Section->Repl->getOutputSection()->Addr;
+ P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
else if (Config->Relocatable)
Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
}
diff --git a/lld/test/ELF/linkerscript/relocatable-discard.s b/lld/test/ELF/linkerscript/relocatable-discard.s
new file mode 100644
index 00000000000..d4f5826b72d
--- /dev/null
+++ b/lld/test/ELF/linkerscript/relocatable-discard.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.discard.*) }}" > %t.script
+# RUN: ld.lld -o %t --script %t.script -r %t.o
+# RUN: llvm-readobj -sections %t | FileCheck %s
+
+## Test shows that we do not crash after discarding the .discard.foo with -r.
+## Previously it happened because of 2 reasons:
+## 1) .rela.discard.foo was not handled properly and was not discarded.
+## Remaining reference was invalid and caused the crash.
+## 2) Third-party section .debug_info referencing discarded section
+## did not handle this case properly and tried to apply the
+## relocation instead of ignoring it.
+
+# CHECK-NOT: .discard
+
+.section .discard.foo,"ax"
+callq fn@PLT
+
+.section .debug_info,"",@progbits
+.long .discard.foo
OpenPOWER on IntegriCloud