Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace lld; @@ -50,6 +51,7 @@ void readOutputArch(); void readOutputFormat(); void readSearchDir(); + void readVersion(); StringSaver Saver; std::vector Tokens; @@ -78,6 +80,8 @@ readOutputFormat(); } else if (Tok == "SEARCH_DIR") { readSearchDir(); + } else if (Tok == "VERSION") { + readVersion(); } else { error("unknown directive: " + Tok); } @@ -255,6 +259,46 @@ expect(")"); } +void LinkerScript::readVersion() { + StringRef Tok, TokNext; + expect("{"); + for (;;) { + Tok = next(); + if (Tok == "}") + break; + expect("{"); + Tok = next(); + + // Neither global or local is specified. + // Just parse the list of the symbols. + if (Tok != "global:" && Tok != "local:") { + expect(";"); + while ((Tok = next()) != "}") + TokNext = next(); + TokNext = next(); + } else { + TokNext = next(); + + // Parse global symbols. + if (Tok == "global:") + do { + Tok = next(); // Symbol name + TokNext = next(); + } while (Tok != "}"); + + // Parse local symbols. + if (Tok == "local:") + do { + Tok = next(); // Symbol name + TokNext = next(); + } while (Tok != "}"); + } + if (TokNext != ";") + // Dependency on another version. + expect(";"); + } +} + // Entry point. The other functions or classes are private to this file. void lld::elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) { LinkerScript(A, MB.getBuffer()).run(); Index: test/elf2/Inputs/version.script =================================================================== --- test/elf2/Inputs/version.script +++ test/elf2/Inputs/version.script @@ -0,0 +1,20 @@ +VERSION { + VERS_1.1 { + global: + x; + *; + local: + q; + }; + VERS_1.2 { + local: + z; + }; + VERS_1.3 { + global: + y; + } VERS_1.1; + VERS_1.4 { + x; + } VERS_1.3; +} Index: test/elf2/linkerscript-version.s =================================================================== --- test/elf2/linkerscript-version.s +++ test/elf2/linkerscript-version.s @@ -0,0 +1,3 @@ +// RUN: llvm-mc %s -filetype=obj -triple=x86_64-unknown-freebsd -o %s.o +// RUN: ld.lld2 -shared -T %p/Inputs/version.script %s.o -o %t.so +// RUN: llvm-objdump %t > /dev/null