diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-12-11 18:49:29 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-12-11 18:49:29 +0000 |
commit | a6763e838602ca3ebc7b44013297303b59f2867f (patch) | |
tree | 2f044106bd96a02bd2854a7d379ace2a19756273 | |
parent | d7634fc91d4bc2415e463d9dc6176f77e21c76b2 (diff) | |
download | bcm5719-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.cpp | 17 | ||||
-rw-r--r-- | lld/test/ELF/discard-merge-locals.s | 24 |
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: ] |