summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-12-11 18:49:29 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-12-11 18:49:29 +0000
commita6763e838602ca3ebc7b44013297303b59f2867f (patch)
tree2f044106bd96a02bd2854a7d379ace2a19756273
parentd7634fc91d4bc2415e463d9dc6176f77e21c76b2 (diff)
downloadbcm5719-llvm-a6763e838602ca3ebc7b44013297303b59f2867f.tar.gz
bcm5719-llvm-a6763e838602ca3ebc7b44013297303b59f2867f.zip
Discard local symbols from SHF_MERGE sections.
This matches the behavior of both gold and bfd ld. llvm-svn: 255355
-rw-r--r--lld/ELF/OutputSections.cpp17
-rw-r--r--lld/test/ELF/discard-merge-locals.s24
2 files changed, 38 insertions, 3 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index ade65979be2..ab7e337deb4 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -1168,15 +1168,26 @@ bool lld::elf2::shouldKeepInSymtab(const ObjectFile<ELFT> &File,
if (Sym.getType() == STT_SECTION)
return false;
+ InputSectionBase<ELFT> *Sec = File.getSection(Sym);
// If sym references a section in a discarded group, don't keep it.
- if (File.getSection(Sym) == &InputSection<ELFT>::Discarded)
+ if (Sec == &InputSection<ELFT>::Discarded)
return false;
if (Config->DiscardNone)
return true;
- // ELF defines dynamic locals as symbols which name starts with ".L".
- return !(Config->DiscardLocals && SymName.startswith(".L"));
+ // In ELF assembly .L symbols are normally discarded by the assembler.
+ // If the assembler fails to do so, the linker discards them if
+ // * --discard-locals is used.
+ // * The symbol is in a SHF_MERGE section, which is normally the reason for
+ // the assembler keeping the .L symbol.
+ if (!SymName.startswith(".L"))
+ return true;
+
+ if (Config->DiscardLocals)
+ return false;
+
+ return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
}
template <class ELFT>
diff --git a/lld/test/ELF/discard-merge-locals.s b/lld/test/ELF/discard-merge-locals.s
new file mode 100644
index 00000000000..51676da192c
--- /dev/null
+++ b/lld/test/ELF/discard-merge-locals.s
@@ -0,0 +1,24 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: ld.lld %t -o %t2 -shared
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: x86
+
+ leaq .L.str(%rip), %rdi
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+.L.str:
+ .asciz "foobar"
+
+// Test that the .L symbol is omitted
+
+// CHECK: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: (0)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
OpenPOWER on IntegriCloud