diff options
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 15 | ||||
-rw-r--r-- | lld/ELF/Driver.h | 1 | ||||
-rw-r--r-- | lld/ELF/DriverUtils.cpp | 26 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 14 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.h | 2 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 7 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.h | 1 | ||||
-rw-r--r-- | lld/test/ELF/gc-sections-shared.s | 9 | ||||
-rw-r--r-- | lld/test/ELF/invalid-dynamic-list.test | 2 | ||||
-rw-r--r-- | lld/test/ELF/reproduce.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/version-script.s | 36 |
12 files changed, 30 insertions, 86 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 9d7be7d4b03..890e33afbab 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -87,7 +87,6 @@ struct Configuration { std::string RPath; std::vector<VersionDefinition> VersionDefinitions; std::vector<llvm::StringRef> AuxiliaryList; - std::vector<llvm::StringRef> DynamicList; std::vector<llvm::StringRef> SearchPaths; std::vector<llvm::StringRef> Undefined; std::vector<SymbolVersion> VersionScriptGlobals; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 0bfc093a8bf..2095e7384dd 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -627,14 +627,24 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_dynamic_list)) if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) - parseDynamicList(*Buffer); + readDynamicList(*Buffer); if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) parseSymbolOrderingList(*Buffer); for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) - Config->DynamicList.push_back(Arg->getValue()); + Config->VersionScriptGlobals.push_back( + {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); + + // Dynamic lists are a simplified linker script that doesn't need the + // "global:" and implicitly ends with a "local:*". Set the variables needed to + // simulate that. + if (Args.hasArg(OPT_dynamic_list) || Args.hasArg(OPT_export_dynamic_symbol)) { + Config->ExportDynamic = true; + if (!Config->Shared) + Config->DefaultSymbolVersion = VER_NDX_LOCAL; + } if (auto *Arg = Args.getLastArg(OPT_version_script)) if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) @@ -793,7 +803,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { Symtab.scanUndefinedFlags(); Symtab.scanShlibUndefined(); - Symtab.scanDynamicList(); Symtab.scanVersionScript(); Symtab.addCombinedLTOObject(); diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h index 74d465e2a52..a3a3a84add8 100644 --- a/lld/ELF/Driver.h +++ b/lld/ELF/Driver.h @@ -69,7 +69,6 @@ enum { void printHelp(const char *Argv0); std::vector<uint8_t> parseHexstring(StringRef S); -void parseDynamicList(MemoryBufferRef MB); std::string createResponseFile(const llvm::opt::InputArgList &Args); diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp index d56dfbae47d..6a270a6d09d 100644 --- a/lld/ELF/DriverUtils.cpp +++ b/lld/ELF/DriverUtils.cpp @@ -90,32 +90,6 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { return Args; } -// Parse the --dynamic-list argument. A dynamic list is in the form -// -// { symbol1; symbol2; [...]; symbolN }; -// -// Multiple groups can be defined in the same file, and they are merged -// into a single group. -void elf::parseDynamicList(MemoryBufferRef MB) { - class Parser : public ScriptParserBase { - public: - Parser(MemoryBufferRef MB) : ScriptParserBase(MB) {} - - void run() { - while (!atEOF()) { - expect("{"); - while (!Error && !consume("}")) { - Config->DynamicList.push_back(unquote(next())); - expect(";"); - } - expect(";"); - } - } - }; - - Parser(MB).run(); -} - void elf::printHelp(const char *Argv0) { ELFOptTable Table; Table.PrintHelp(outs(), Argv0, "lld", false); diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index f62cdcea12c..50ce95506c8 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -987,6 +987,7 @@ public: void readLinkerScript(); void readVersionScript(); + void readDynamicList(); private: void addFile(StringRef Path); @@ -1040,6 +1041,13 @@ private: std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs; }; +void ScriptParser::readDynamicList() { + expect("{"); + readAnonymousDeclaration(); + if (!atEOF()) + setError("EOF expected, but got " + next()); +} + void ScriptParser::readVersionScript() { readVersionScriptCommand(); if (!atEOF()) @@ -1932,7 +1940,7 @@ std::vector<SymbolVersion> ScriptParser::readVersionExtern() { StringRef Tok = next(); bool IsCXX = Tok == "\"C++\""; if (!IsCXX && Tok != "\"C\"") - setError("Unknown Language"); + setError("Unknown language"); expect("{"); std::vector<SymbolVersion> Ret; @@ -1956,6 +1964,10 @@ void elf::readVersionScript(MemoryBufferRef MB) { ScriptParser(MB).readVersionScript(); } +void elf::readDynamicList(MemoryBufferRef MB) { + ScriptParser(MB).readDynamicList(); +} + template class elf::LinkerScript<ELF32LE>; template class elf::LinkerScript<ELF32BE>; template class elf::LinkerScript<ELF64LE>; diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 3bcfc57045c..f6428e19954 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -66,6 +66,8 @@ void readLinkerScript(MemoryBufferRef MB); // Parses a version script. void readVersionScript(MemoryBufferRef MB); +void readDynamicList(MemoryBufferRef MB); + // This enum is used to implement linker script SECTIONS command. // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS enum SectionsCommandKind { diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 4fb611de7a2..078fbb30943 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -535,13 +535,6 @@ template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() { Sym->symbol()->ExportDynamic = true; } -// This function processes --export-dynamic-symbol and --dynamic-list. -template <class ELFT> void SymbolTable<ELFT>::scanDynamicList() { - for (StringRef S : Config->DynamicList) - if (SymbolBody *B = find(S)) - B->symbol()->ExportDynamic = true; -} - // Initialize DemangledSyms with a map from demangled symbols to symbol // objects. Used to handle "extern C++" directive in version scripts. // diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 0e1b62f2166..cd9bef30bbd 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -81,7 +81,6 @@ public: void scanUndefinedFlags(); void scanShlibUndefined(); - void scanDynamicList(); void scanVersionScript(); SymbolBody *find(StringRef Name); diff --git a/lld/test/ELF/gc-sections-shared.s b/lld/test/ELF/gc-sections-shared.s index f1ac9cd345d..a88f2b44347 100644 --- a/lld/test/ELF/gc-sections-shared.s +++ b/lld/test/ELF/gc-sections-shared.s @@ -19,15 +19,6 @@ # CHECK-NEXT: Section: Undefined (0x0) # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: bar -# CHECK-NEXT: Value: -# CHECK-NEXT: Size: -# CHECK-NEXT: Binding: Global -# CHECK-NEXT: Type: -# CHECK-NEXT: Other: -# CHECK-NEXT: Section: .text -# CHECK-NEXT: } -# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: bar2 # CHECK-NEXT: Value: # CHECK-NEXT: Size: diff --git a/lld/test/ELF/invalid-dynamic-list.test b/lld/test/ELF/invalid-dynamic-list.test index 5c478a9e5c7..f560ceed0f8 100644 --- a/lld/test/ELF/invalid-dynamic-list.test +++ b/lld/test/ELF/invalid-dynamic-list.test @@ -34,4 +34,4 @@ # RUN: echo "{ extern \"BOGUS\" { test }; };" > %t1 # RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR6 %s -# ERR6: {{.*}}:1: ; expected, but got "BOGUS" +# ERR6: {{.*}}:1: Unknown language diff --git a/lld/test/ELF/reproduce.s b/lld/test/ELF/reproduce.s index 9166fb4bd0f..a29971b420a 100644 --- a/lld/test/ELF/reproduce.s +++ b/lld/test/ELF/reproduce.s @@ -30,7 +30,7 @@ # RUN: diff %t.dir/build2/foo.o repro/%:t.dir/build2/foo.o # RUN: echo "{ local: *; };" > ver -# RUN: echo > dyn +# RUN: echo "{};" > dyn # RUN: echo > file # RUN: echo > file2 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar' diff --git a/lld/test/ELF/version-script.s b/lld/test/ELF/version-script.s index 2825f0fa0cc..7453981ab9c 100644 --- a/lld/test/ELF/version-script.s +++ b/lld/test/ELF/version-script.s @@ -14,11 +14,6 @@ # RUN: ld.lld --version-script %t3.script -shared %t.o %t2.so -o %t3.so # RUN: llvm-readobj -dyn-symbols %t3.so | FileCheck --check-prefix=DSO2 %s -# --version-script filters --dynamic-list. -# RUN: echo "{ foo1; foo2; };" > %t.list -# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t -# RUN: llvm-readobj -dyn-symbols %t | FileCheck --check-prefix=EXE %s - # RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t4.script # RUN: echo "VERSION_2.0 { global: foo3; local: *; };" >> %t4.script # RUN: ld.lld --version-script %t4.script -shared %t.o %t2.so -o %t4.so @@ -42,6 +37,7 @@ # RUN: FileCheck -check-prefix=WARN2 %s # WARN2: duplicate symbol 'foo1' in version script +# RUN: echo "{ foo1; foo2; };" > %t.list # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 # RUN: llvm-readobj %t2 > /dev/null @@ -105,36 +101,6 @@ # DSO2-NEXT: } # DSO2-NEXT: ] -# EXE: DynamicSymbols [ -# EXE-NEXT: Symbol { -# EXE-NEXT: Name: @ -# EXE-NEXT: Value: 0x0 -# EXE-NEXT: Size: 0 -# EXE-NEXT: Binding: Local (0x0) -# EXE-NEXT: Type: None (0x0) -# EXE-NEXT: Other: 0 -# EXE-NEXT: Section: Undefined (0x0) -# EXE-NEXT: } -# EXE-NEXT: Symbol { -# EXE-NEXT: Name: bar@ -# EXE-NEXT: Value: 0x0 -# EXE-NEXT: Size: 0 -# EXE-NEXT: Binding: Global (0x1) -# EXE-NEXT: Type: Function (0x2) -# EXE-NEXT: Other: 0 -# EXE-NEXT: Section: Undefined (0x0) -# EXE-NEXT: } -# EXE-NEXT: Symbol { -# EXE-NEXT: Name: foo1@ -# EXE-NEXT: Value: 0x201000 -# EXE-NEXT: Size: 0 -# EXE-NEXT: Binding: Global (0x1) -# EXE-NEXT: Type: None (0x0) -# EXE-NEXT: Other: 0 -# EXE-NEXT: Section: .text -# EXE-NEXT: } -# EXE-NEXT: ] - # VERDSO: DynamicSymbols [ # VERDSO-NEXT: Symbol { # VERDSO-NEXT: Name: @ |