Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -12,6 +12,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/ELF.h" #include @@ -33,8 +34,8 @@ // For --build-id. enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; -// For --discard-{all,locals,none}. -enum class DiscardPolicy { Default, All, Locals, None }; +// For --discard-{all,locals,none} and --retain-symbols-file. +enum class DiscardPolicy { Default, All, Locals, RetainFile, None }; // For --strip-{all,debug}. enum class StripPolicy { None, All, Debug }; @@ -83,6 +84,7 @@ llvm::StringRef OutputFile; llvm::StringRef SoName; llvm::StringRef Sysroot; + llvm::StringSet<> RetainSymbolsFile; std::string RPath; std::vector VersionDefinitions; std::vector AuxiliaryList; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -478,16 +478,35 @@ return SortSectionPolicy::Default; } +static std::vector getLines(MemoryBufferRef MB) { + std::vector Ret; + SmallVector Arr; + MB.getBuffer().split(Arr, '\n'); + for (StringRef S : Arr) { + S = S.trim(); + if (!S.empty()) + Ret.push_back(S); + } + return Ret; +} + // Parse the --symbol-ordering-file argument. File has form: // symbolName1 // [...] // symbolNameN static void parseSymbolOrderingList(MemoryBufferRef MB) { unsigned I = 0; - SmallVector Arr; - MB.getBuffer().split(Arr, '\n'); - for (StringRef S : Arr) - Config->SymbolOrderingFile.insert({S.trim(), I++}); + for (StringRef S : getLines(MB)) + Config->SymbolOrderingFile.insert({S, I++}); +} + +// Parse the --retain-symbols-file argument. File has form: +// symbolName1 +// [...] +// symbolNameN +static void parseRetainSymbolsList(MemoryBufferRef MB) { + for (StringRef S : getLines(MB)) + Config->RetainSymbolsFile.insert(S); } // Initializes Config members by the command line options. @@ -636,6 +655,14 @@ if (Optional Buffer = readFile(Arg->getValue())) parseSymbolOrderingList(*Buffer); + // If --retain-symbol-file is used, we'll retail only the symbols listed in + // the file and discard all others. + if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) { + Config->Discard = DiscardPolicy::RetainFile; + if (Optional Buffer = readFile(Arg->getValue())) + parseRetainSymbolsList(*Buffer); + } + for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) Config->VersionScriptGlobals.push_back( {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); Index: lld/trunk/ELF/Options.td =================================================================== --- lld/trunk/ELF/Options.td +++ lld/trunk/ELF/Options.td @@ -176,6 +176,9 @@ def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; +def retain_symbols_file: J<"retain-symbols-file=">, MetaVarName<"">, + HelpText<"Retain only the symbols listed in the file">; + def script: S<"script">, HelpText<"Read linker script">; def section_start: S<"section-start">, MetaVarName<"
">, @@ -269,6 +272,7 @@ def alias_o_output2 : Separate<["--"], "output">, Alias; def alias_pie_pic_executable: F<"pic-executable">, Alias; def alias_relocatable_r: Flag<["-"], "r">, Alias; +def alias_retain_symbols_file: S<"retain-symbols-file">, Alias; def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias; def alias_rpath_rpath: J<"rpath=">, Alias; def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias