Skip to content

Commit 20b6598

Browse files
author
George Rimar
committedAug 31, 2016
[ELF] - Remove VersionScriptParser class and move the members to ScriptParser
Patch removes VersionScriptParser class and moves the members to ScriptParser It opens road for implementation of VERSION linkerscript command. Differential revision: https://reviews.llvm.org/D23774 llvm-svn: 280212
1 parent ebf1da5 commit 20b6598

File tree

5 files changed

+100
-116
lines changed

5 files changed

+100
-116
lines changed
 

Diff for: ‎lld/ELF/Driver.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
504504

505505
if (auto *Arg = Args.getLastArg(OPT_version_script))
506506
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
507-
parseVersionScript(*Buffer);
507+
readVersionScript(*Buffer);
508508
}
509509

510510
void LinkerDriver::createFiles(opt::InputArgList &Args) {

Diff for: ‎lld/ELF/LinkerScript.cpp

+97-4
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,8 @@ class elf::ScriptParser : public ScriptParserBase {
625625
public:
626626
ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
627627

628-
void run();
628+
void readLinkerScript();
629+
void readVersionScript();
629630

630631
private:
631632
void addFile(StringRef Path);
@@ -663,6 +664,12 @@ class elf::ScriptParser : public ScriptParserBase {
663664
Expr readTernary(Expr Cond);
664665
Expr readParenExpr();
665666

667+
// For parsing version script.
668+
void readExtern(std::vector<SymbolVersion> *Globals);
669+
void readVersion(StringRef VerStr);
670+
void readGlobal(StringRef VerStr);
671+
void readLocal();
672+
666673
const static StringMap<Handler> Cmd;
667674
ScriptConfiguration &Opt = *ScriptConfig;
668675
StringSaver Saver = {ScriptConfig->Alloc};
@@ -683,7 +690,28 @@ const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
683690
{"SECTIONS", &ScriptParser::readSections},
684691
{";", &ScriptParser::readNothing}};
685692

686-
void ScriptParser::run() {
693+
void ScriptParser::readVersionScript() {
694+
StringRef Msg = "anonymous version definition is used in "
695+
"combination with other version definitions";
696+
if (skip("{")) {
697+
readVersion("");
698+
if (!atEOF())
699+
setError(Msg);
700+
return;
701+
}
702+
703+
while (!atEOF() && !Error) {
704+
StringRef VerStr = next();
705+
if (VerStr == "{") {
706+
setError(Msg);
707+
return;
708+
}
709+
expect("{");
710+
readVersion(VerStr);
711+
}
712+
}
713+
714+
void ScriptParser::readLinkerScript() {
687715
while (!atEOF()) {
688716
StringRef Tok = next();
689717
if (Handler Fn = Cmd.lookup(Tok))
@@ -1335,6 +1363,68 @@ unsigned ScriptParser::readPhdrType() {
13351363
return Ret;
13361364
}
13371365

1366+
void ScriptParser::readVersion(StringRef VerStr) {
1367+
// Identifiers start at 2 because 0 and 1 are reserved
1368+
// for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
1369+
size_t VersionId = Config->VersionDefinitions.size() + 2;
1370+
Config->VersionDefinitions.push_back({VerStr, VersionId});
1371+
1372+
if (skip("global:") || peek() != "local:")
1373+
readGlobal(VerStr);
1374+
if (skip("local:"))
1375+
readLocal();
1376+
expect("}");
1377+
1378+
// Each version may have a parent version. For example, "Ver2" defined as
1379+
// "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This
1380+
// version hierarchy is, probably against your instinct, purely for human; the
1381+
// runtime doesn't care about them at all. In LLD, we simply skip the token.
1382+
if (!VerStr.empty() && peek() != ";")
1383+
next();
1384+
expect(";");
1385+
}
1386+
1387+
void ScriptParser::readLocal() {
1388+
Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1389+
expect("*");
1390+
expect(";");
1391+
}
1392+
1393+
void ScriptParser::readExtern(std::vector<SymbolVersion> *Globals) {
1394+
expect("C++");
1395+
expect("{");
1396+
1397+
for (;;) {
1398+
if (peek() == "}" || Error)
1399+
break;
1400+
Globals->push_back({next(), true});
1401+
expect(";");
1402+
}
1403+
1404+
expect("}");
1405+
expect(";");
1406+
}
1407+
1408+
void ScriptParser::readGlobal(StringRef VerStr) {
1409+
std::vector<SymbolVersion> *Globals;
1410+
if (VerStr.empty())
1411+
Globals = &Config->VersionScriptGlobals;
1412+
else
1413+
Globals = &Config->VersionDefinitions.back().Globals;
1414+
1415+
for (;;) {
1416+
if (skip("extern"))
1417+
readExtern(Globals);
1418+
1419+
StringRef Cur = peek();
1420+
if (Cur == "}" || Cur == "local:" || Error)
1421+
return;
1422+
next();
1423+
Globals->push_back({Cur, false});
1424+
expect(";");
1425+
}
1426+
}
1427+
13381428
static bool isUnderSysroot(StringRef Path) {
13391429
if (Config->Sysroot == "")
13401430
return false;
@@ -1344,10 +1434,13 @@ static bool isUnderSysroot(StringRef Path) {
13441434
return false;
13451435
}
13461436

1347-
// Entry point.
13481437
void elf::readLinkerScript(MemoryBufferRef MB) {
13491438
StringRef Path = MB.getBufferIdentifier();
1350-
ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run();
1439+
ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).readLinkerScript();
1440+
}
1441+
1442+
void elf::readVersionScript(MemoryBufferRef MB) {
1443+
ScriptParser(MB.getBuffer(), false).readVersionScript();
13511444
}
13521445

13531446
template class elf::LinkerScript<ELF32LE>;

Diff for: ‎lld/ELF/LinkerScript.h

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ typedef std::function<uint64_t(uint64_t)> Expr;
3434
// Config and ScriptConfig.
3535
void readLinkerScript(MemoryBufferRef MB);
3636

37+
void readVersionScript(MemoryBufferRef MB);
38+
3739
// This enum is used to implement linker script SECTIONS command.
3840
// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
3941
enum SectionsCommandKind {

Diff for: ‎lld/ELF/SymbolListFile.cpp

-110
Original file line numberDiff line numberDiff line change
@@ -55,113 +55,3 @@ void DynamicListParser::run() {
5555
void elf::parseDynamicList(MemoryBufferRef MB) {
5656
DynamicListParser(MB.getBuffer()).run();
5757
}
58-
59-
// Parse the --version-script argument. We currently only accept the following
60-
// version script syntax:
61-
//
62-
// { [ global: symbol1; symbol2; [...]; symbolN; ] local: *; };
63-
//
64-
// No wildcards are supported, other than for the local entry. Symbol versioning
65-
// is also not supported.
66-
67-
namespace {
68-
class VersionScriptParser final : public ScriptParserBase {
69-
public:
70-
VersionScriptParser(StringRef S) : ScriptParserBase(S) {}
71-
72-
void run();
73-
74-
private:
75-
void parseExtern(std::vector<SymbolVersion> *Globals);
76-
void parseVersion(StringRef VerStr);
77-
void parseGlobal(StringRef VerStr);
78-
void parseLocal();
79-
};
80-
} // end anonymous namespace
81-
82-
void VersionScriptParser::parseVersion(StringRef VerStr) {
83-
// Identifiers start at 2 because 0 and 1 are reserved
84-
// for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
85-
size_t VersionId = Config->VersionDefinitions.size() + 2;
86-
Config->VersionDefinitions.push_back({VerStr, VersionId});
87-
88-
if (skip("global:") || peek() != "local:")
89-
parseGlobal(VerStr);
90-
if (skip("local:"))
91-
parseLocal();
92-
expect("}");
93-
94-
// Each version may have a parent version. For example, "Ver2" defined as
95-
// "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" as a parent. This
96-
// version hierarchy is, probably against your instinct, purely for human; the
97-
// runtime doesn't care about them at all. In LLD, we simply skip the token.
98-
if (!VerStr.empty() && peek() != ";")
99-
next();
100-
expect(";");
101-
}
102-
103-
void VersionScriptParser::parseLocal() {
104-
Config->DefaultSymbolVersion = VER_NDX_LOCAL;
105-
expect("*");
106-
expect(";");
107-
}
108-
109-
void VersionScriptParser::parseExtern(std::vector<SymbolVersion> *Globals) {
110-
expect("C++");
111-
expect("{");
112-
113-
for (;;) {
114-
if (peek() == "}" || Error)
115-
break;
116-
Globals->push_back({next(), true});
117-
expect(";");
118-
}
119-
120-
expect("}");
121-
expect(";");
122-
}
123-
124-
void VersionScriptParser::parseGlobal(StringRef VerStr) {
125-
std::vector<SymbolVersion> *Globals;
126-
if (VerStr.empty())
127-
Globals = &Config->VersionScriptGlobals;
128-
else
129-
Globals = &Config->VersionDefinitions.back().Globals;
130-
131-
for (;;) {
132-
if (skip("extern"))
133-
parseExtern(Globals);
134-
135-
StringRef Cur = peek();
136-
if (Cur == "}" || Cur == "local:" || Error)
137-
return;
138-
next();
139-
Globals->push_back({Cur, false});
140-
expect(";");
141-
}
142-
}
143-
144-
void VersionScriptParser::run() {
145-
StringRef Msg = "anonymous version definition is used in "
146-
"combination with other version definitions";
147-
if (skip("{")) {
148-
parseVersion("");
149-
if (!atEOF())
150-
setError(Msg);
151-
return;
152-
}
153-
154-
while (!atEOF() && !Error) {
155-
StringRef VerStr = next();
156-
if (VerStr == "{") {
157-
setError(Msg);
158-
return;
159-
}
160-
expect("{");
161-
parseVersion(VerStr);
162-
}
163-
}
164-
165-
void elf::parseVersionScript(MemoryBufferRef MB) {
166-
VersionScriptParser(MB.getBuffer()).run();
167-
}

Diff for: ‎lld/ELF/SymbolListFile.h

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ namespace lld {
1717
namespace elf {
1818

1919
void parseDynamicList(MemoryBufferRef MB);
20-
void parseVersionScript(MemoryBufferRef MB);
2120

2221
} // namespace elf
2322
} // namespace lld

0 commit comments

Comments
 (0)
Please sign in to comment.