From 5445b2de5070f935113880eed2b7843399fbbcbf Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Sun, 20 Sep 2015 21:58:12 +0000 Subject: [PATCH] [ELF2] Implement support for -discard-locals. This is not on by default, but it may make sense to change it in future. llvm-svn: 248133 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 3 ++ lld/ELF/Options.td | 3 ++ lld/ELF/Writer.cpp | 4 ++- lld/test/elf2/discard-locals.s | 52 ++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 lld/test/elf2/discard-locals.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 7af0fa738e07..7c9a7eb07995 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -21,6 +21,7 @@ struct Configuration { std::string RPath; bool Shared = false; bool DiscardAll = false; + bool DiscardLocals = false; }; extern Configuration *Config; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 8328ba5effbf..6537e13da991 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -85,6 +85,9 @@ void LinkerDriver::link(ArrayRef ArgsArr) { if (Args.hasArg(OPT_discard_all)) Config->DiscardAll = true; + if (Args.hasArg(OPT_discard_locals)) + Config->DiscardLocals = true; + // Create a list of input files. std::vector Inputs; diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index fed2e9993e07..e9a2213b4e3d 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -18,3 +18,6 @@ def shared : Flag<["-"], "shared">, def discard_all : Flag<["-"], "discard-all">, HelpText<"Delete all local symbols">; + +def discard_locals : Flag<["-"], "discard-locals">, + HelpText<"Delete temporary local symbols">; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1e54a29c3a9c..de18c927b18a 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -820,6 +820,8 @@ template void SymbolTableSection::writeTo(uint8_t *Buf) { auto *ESym = reinterpret_cast(Buf); uint32_t SecIndex = Sym.st_shndx; ErrorOr SymName = Sym.getName(File.getStringTable()); + if (Config->DiscardLocals && SymName->startswith(".L")) + continue; ESym->st_name = (SymName) ? StrTabSec.getFileOff(*SymName) : 0; ESym->st_size = Sym.st_size; ESym->setBindingAndType(Sym.getBinding(), Sym.getType()); @@ -1044,7 +1046,7 @@ template void Writer::createSections() { Elf_Sym_Range Syms = File.getLocalSymbols(); for (const Elf_Sym &Sym : Syms) { ErrorOr SymName = Sym.getName(File.getStringTable()); - if (SymName) + if (SymName && !(Config->DiscardLocals && SymName->startswith(".L"))) SymTabSec.addSymbol(*SymName, true); } } diff --git a/lld/test/elf2/discard-locals.s b/lld/test/elf2/discard-locals.s new file mode 100644 index 000000000000..e1ffea11702e --- /dev/null +++ b/lld/test/elf2/discard-locals.s @@ -0,0 +1,52 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t +// RUN: lld -flavor gnu2 -discard-locals %t -o %t2 +// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s +// REQUIRES: x86 + +.global _start +_start: + +.text +.Lmyvar: +.Lmyothervar: + +// CHECK: Section { +// CHECK: Name: .strtab +// CHECK-NEXT: Type: SHT_STRTAB +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 002E7465 7874005F 73746172 74002E62 +// CHECK-NEXT: 0010: 7373002E 73747274 6162002E 73796D74 +// CHECK-NEXT: 0020: 6162002E 64617461 00 +// CHECK-NEXT: ) +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// CHECK: Symbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: +// 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: Symbol { +// CHECK-NEXT: Name: _start +// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECk-NEXT: ]