summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2018-03-23 17:19:18 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2018-03-23 17:19:18 +0000
commit4376cffb5703410561136132a7799ee4535678fc (patch)
treea8bcec1e59211408b3db33d8ca7f1035cebed7fc
parent256f149bf0f8ef2c83cbb467074f6f62ecb18826 (diff)
downloadbcm5719-llvm-4376cffb5703410561136132a7799ee4535678fc.tar.gz
bcm5719-llvm-4376cffb5703410561136132a7799ee4535678fc.zip
Add a minimal fix for PR36878.
When looking for the output section and the output offset the expectation was that the caller had looked at Repl. That works fine for InputSections, but in the case of MergeInputSections the caller doesn't have the section that is actually replaced. The original testcase was failing because getOutputSection was returning null. The slightly extended testcase also checks that getOffset also checks Repl. I will send a refactoring separetelly. llvm-svn: 328332
-rw-r--r--lld/ELF/InputSection.cpp6
-rw-r--r--lld/test/ELF/icf-merged-sections.s33
2 files changed, 36 insertions, 3 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 713a781206a..9814de9f278 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -156,7 +156,7 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const {
case Merge:
const MergeInputSection *MS = cast<MergeInputSection>(this);
if (InputSection *IS = MS->getParent())
- return IS->OutSecOff + MS->getOffset(Offset);
+ return cast<InputSection>(IS->Repl)->OutSecOff + MS->getOffset(Offset);
return MS->getOffset(Offset);
}
llvm_unreachable("invalid section kind");
@@ -165,14 +165,14 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const {
OutputSection *SectionBase::getOutputSection() {
InputSection *Sec;
if (auto *IS = dyn_cast<InputSection>(this))
- return IS->getParent();
+ Sec = IS;
else if (auto *MS = dyn_cast<MergeInputSection>(this))
Sec = MS->getParent();
else if (auto *EH = dyn_cast<EhInputSection>(this))
Sec = EH->getParent();
else
return cast<OutputSection>(this);
- return Sec ? Sec->getParent() : nullptr;
+ return Sec ? cast<InputSection>(Sec->Repl)->getParent() : nullptr;
}
// Decompress section contents if required. Note that this function
diff --git a/lld/test/ELF/icf-merged-sections.s b/lld/test/ELF/icf-merged-sections.s
new file mode 100644
index 00000000000..e29bd4938d7
--- /dev/null
+++ b/lld/test/ELF/icf-merged-sections.s
@@ -0,0 +1,33 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t --icf=all --ignore-data-address-equality --print-icf-sections | FileCheck %s --check-prefix ICF
+# RUN: llvm-objdump -s -d -print-imm-hex %t | FileCheck %s
+
+# ICF: selected section <internal>:(.rodata)
+# ICF-NEXT: removing identical section <internal>:(.rodata)
+
+# CHECK: {{^}}.text:
+# CHECK-NEXT: movq 0x[[ADDR:[0-9a-f]+]], %rax
+# CHECK-NEXT: movq 0x[[ADDR]], %rax
+# CHECK: Contents of section .rodata:
+# CHECK-NEXT: 2a000000 00000000 67452301 10325476
+
+.section .rodata, "a"
+ .quad 42
+
+.section .rodata.cst4,"aM",@progbits,4
+rodata4:
+ .long 0x01234567
+ .long 0x76543210
+ .long 0x01234567
+ .long 0x76543210
+
+.section .rodata.cst8,"aM",@progbits,8
+rodata8:
+ .long 0x01234567
+ .long 0x76543210
+
+.section .text,"ax"
+ movq rodata4, %rax
+ movq rodata8, %rax
OpenPOWER on IntegriCloud