Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -87,7 +87,6 @@ std::string RPath; std::vector VersionDefinitions; std::vector AuxiliaryList; - std::vector DynamicList; std::vector SearchPaths; std::vector Undefined; std::vector VersionScriptGlobals; Index: ELF/Driver.h =================================================================== --- ELF/Driver.h +++ ELF/Driver.h @@ -69,7 +69,6 @@ void printHelp(const char *Argv0); std::vector parseHexstring(StringRef S); -void parseDynamicList(MemoryBufferRef MB); std::string createResponseFile(const llvm::opt::InputArgList &Args); Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -633,14 +633,24 @@ if (auto *Arg = Args.getLastArg(OPT_dynamic_list)) if (Optional Buffer = readFile(Arg->getValue())) - parseDynamicList(*Buffer); + readDynamicList(*Buffer); if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) if (Optional 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 Buffer = readFile(Arg->getValue())) @@ -800,7 +810,6 @@ Symtab.scanUndefinedFlags(); Symtab.scanShlibUndefined(); - Symtab.scanDynamicList(); Symtab.scanVersionScript(); Symtab.addCombinedLTOObject(); Index: ELF/DriverUtils.cpp =================================================================== --- ELF/DriverUtils.cpp +++ ELF/DriverUtils.cpp @@ -90,32 +90,6 @@ 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); Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -66,6 +66,8 @@ // 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 { Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -987,6 +987,7 @@ void readLinkerScript(); void readVersionScript(); + void readDynamicList(); private: void addFile(StringRef Path); @@ -1040,6 +1041,13 @@ std::vector> OwningMBs; }; +void ScriptParser::readDynamicList() { + expect("{"); + readAnonymousDeclaration(); + if (!atEOF()) + setError("EOF expected, but got " + next()); +} + void ScriptParser::readVersionScript() { readVersionScriptCommand(); if (!atEOF()) @@ -1932,7 +1940,7 @@ StringRef Tok = next(); bool IsCXX = Tok == "\"C++\""; if (!IsCXX && Tok != "\"C\"") - setError("Unknown Language"); + setError("Unknown language"); expect("{"); std::vector Ret; @@ -1956,6 +1964,10 @@ ScriptParser(MB).readVersionScript(); } +void elf::readDynamicList(MemoryBufferRef MB) { + ScriptParser(MB).readDynamicList(); +} + template class elf::LinkerScript; template class elf::LinkerScript; template class elf::LinkerScript; Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -81,7 +81,6 @@ void scanUndefinedFlags(); void scanShlibUndefined(); - void scanDynamicList(); void scanVersionScript(); SymbolBody *find(StringRef Name); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -535,13 +535,6 @@ Sym->symbol()->ExportDynamic = true; } -// This function processes --export-dynamic-symbol and --dynamic-list. -template void SymbolTable::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. // Index: test/ELF/gc-sections-shared.s =================================================================== --- test/ELF/gc-sections-shared.s +++ 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: Index: test/ELF/invalid-dynamic-list.test =================================================================== --- test/ELF/invalid-dynamic-list.test +++ 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 Index: test/ELF/reproduce.s =================================================================== --- test/ELF/reproduce.s +++ 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' Index: test/ELF/version-script.s =================================================================== --- test/ELF/version-script.s +++ 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: @