Skip to content

Commit 2bb88ab

Browse files
author
George Rimar
committedDec 19, 2016
[ELF] - Implemented --retain-symbols-file option
--retain-symbols-file=filename Retain only the symbols listed in the file filename, discarding all others. filename is simply a flat file, with one symbol name per line. This option is especially useful in environments (such as VxWorks) where a large global symbol table is accumulated gradually, to conserve run-time memory. Note: though documentation says "--retain-symbols-file does not discard undefined symbols, or symbols needed for relocations.", both bfd and gold do that, and this patch too, like testcase show. Differential revision: https://reviews.llvm.org/D27716 llvm-svn: 290122
1 parent 086c90b commit 2bb88ab

File tree

5 files changed

+89
-6
lines changed

5 files changed

+89
-6
lines changed
 

‎lld/ELF/Config.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "llvm/ADT/MapVector.h"
1414
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/ADT/StringSet.h"
1516
#include "llvm/Support/ELF.h"
1617

1718
#include <vector>
@@ -33,8 +34,8 @@ enum ELFKind {
3334
// For --build-id.
3435
enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
3536

36-
// For --discard-{all,locals,none}.
37-
enum class DiscardPolicy { Default, All, Locals, None };
37+
// For --discard-{all,locals,none} and --retain-symbols-file.
38+
enum class DiscardPolicy { Default, All, Locals, RetainFile, None };
3839

3940
// For --strip-{all,debug}.
4041
enum class StripPolicy { None, All, Debug };
@@ -83,6 +84,7 @@ struct Configuration {
8384
llvm::StringRef OutputFile;
8485
llvm::StringRef SoName;
8586
llvm::StringRef Sysroot;
87+
llvm::StringSet<> RetainSymbolsFile;
8688
std::string RPath;
8789
std::vector<VersionDefinition> VersionDefinitions;
8890
std::vector<llvm::StringRef> AuxiliaryList;

‎lld/ELF/Driver.cpp

+31-4
Original file line numberDiff line numberDiff line change
@@ -478,16 +478,35 @@ static SortSectionPolicy getSortKind(opt::InputArgList &Args) {
478478
return SortSectionPolicy::Default;
479479
}
480480

481+
static std::vector<StringRef> getLines(MemoryBufferRef MB) {
482+
std::vector<StringRef> Ret;
483+
SmallVector<StringRef, 0> Arr;
484+
MB.getBuffer().split(Arr, '\n');
485+
for (StringRef S : Arr) {
486+
S = S.trim();
487+
if (!S.empty())
488+
Ret.push_back(S);
489+
}
490+
return Ret;
491+
}
492+
481493
// Parse the --symbol-ordering-file argument. File has form:
482494
// symbolName1
483495
// [...]
484496
// symbolNameN
485497
static void parseSymbolOrderingList(MemoryBufferRef MB) {
486498
unsigned I = 0;
487-
SmallVector<StringRef, 0> Arr;
488-
MB.getBuffer().split(Arr, '\n');
489-
for (StringRef S : Arr)
490-
Config->SymbolOrderingFile.insert({S.trim(), I++});
499+
for (StringRef S : getLines(MB))
500+
Config->SymbolOrderingFile.insert({S, I++});
501+
}
502+
503+
// Parse the --retain-symbols-file argument. File has form:
504+
// symbolName1
505+
// [...]
506+
// symbolNameN
507+
static void parseRetainSymbolsList(MemoryBufferRef MB) {
508+
for (StringRef S : getLines(MB))
509+
Config->RetainSymbolsFile.insert(S);
491510
}
492511

493512
// Initializes Config members by the command line options.
@@ -636,6 +655,14 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
636655
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
637656
parseSymbolOrderingList(*Buffer);
638657

658+
// If --retain-symbol-file is used, we'll retail only the symbols listed in
659+
// the file and discard all others.
660+
if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
661+
Config->Discard = DiscardPolicy::RetainFile;
662+
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
663+
parseRetainSymbolsList(*Buffer);
664+
}
665+
639666
for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
640667
Config->VersionScriptGlobals.push_back(
641668
{Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});

‎lld/ELF/Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ def rpath: S<"rpath">, HelpText<"Add a DT_RUNPATH to the output">;
176176

177177
def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
178178

179+
def retain_symbols_file: J<"retain-symbols-file=">, MetaVarName<"<file>">,
180+
HelpText<"Retain only the symbols listed in the file">;
181+
179182
def script: S<"script">, HelpText<"Read linker script">;
180183

181184
def section_start: S<"section-start">, MetaVarName<"<address>">,
@@ -269,6 +272,7 @@ def alias_o_output: Joined<["--"], "output=">, Alias<o>;
269272
def alias_o_output2 : Separate<["--"], "output">, Alias<o>;
270273
def alias_pie_pic_executable: F<"pic-executable">, Alias<pie>;
271274
def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;
275+
def alias_retain_symbols_file: S<"retain-symbols-file">, Alias<retain_symbols_file>;
272276
def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias<rpath>;
273277
def alias_rpath_rpath: J<"rpath=">, Alias<rpath>;
274278
def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias<script>;

‎lld/ELF/Writer.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,12 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
420420
if (!B.isLocal() && !B.symbol()->IsUsedInRegularObj)
421421
return false;
422422

423+
// If --retain-symbols-file is given, we'll keep only symbols listed in that
424+
// file.
425+
if (Config->Discard == DiscardPolicy::RetainFile &&
426+
!Config->RetainSymbolsFile.count(B.getName()))
427+
return false;
428+
423429
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) {
424430
// Always include absolute symbols.
425431
if (!D->Section)

‎lld/test/ELF/retain-symbols-file.s

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3+
# RUN: echo "bar" > %t_retain.txt
4+
# RUN: echo "foo" >> %t_retain.txt
5+
# RUN: ld.lld -shared --retain-symbols-file=%t_retain.txt %t -o %t2
6+
# RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
7+
8+
## Check separate form.
9+
# RUN: ld.lld -shared --retain-symbols-file %t_retain.txt %t -o %t2
10+
# RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
11+
12+
# CHECK: Symbols [
13+
# CHECK-NEXT: Symbol {
14+
# CHECK-NEXT: Name: (0)
15+
# CHECK: Symbol {
16+
# CHECK-NEXT: Name: bar
17+
# CHECK: Symbol {
18+
# CHECK-NEXT: Name: foo
19+
# CHECK-NOT: Symbol
20+
21+
.text
22+
.globl _start
23+
_start:
24+
call zed@PLT
25+
call und@PLT
26+
27+
.globl foo
28+
.type foo,@function
29+
foo:
30+
retq
31+
32+
.globl bar
33+
.type bar,@function
34+
bar:
35+
retq
36+
37+
.globl zed
38+
.type zed,@function
39+
zed:
40+
retq
41+
42+
.type loc,@function
43+
loc:
44+
retq

0 commit comments

Comments
 (0)
Please sign in to comment.