Skip to content

Commit a533eb7

Browse files
committed
Revert "[ELF] Apply version script patterns to non-default version symbols"
This reverts commit 7ed22a6. buf is not cleared so the commit misses some cases.
1 parent 26aa1bb commit a533eb7

12 files changed

+224
-121
lines changed

lld/ELF/Config.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ struct SymbolVersion {
8686
struct VersionDefinition {
8787
llvm::StringRef name;
8888
uint16_t id;
89-
std::vector<SymbolVersion> nonLocalPatterns;
90-
std::vector<SymbolVersion> localPatterns;
89+
std::vector<SymbolVersion> patterns;
9190
};
9291

9392
// This struct contains the global configuration for the linker.

lld/ELF/Driver.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,19 +1351,18 @@ static void readConfigs(opt::InputArgList &args) {
13511351
}
13521352

13531353
assert(config->versionDefinitions.empty());
1354+
config->versionDefinitions.push_back({"local", (uint16_t)VER_NDX_LOCAL, {}});
13541355
config->versionDefinitions.push_back(
1355-
{"local", (uint16_t)VER_NDX_LOCAL, {}, {}});
1356-
config->versionDefinitions.push_back(
1357-
{"global", (uint16_t)VER_NDX_GLOBAL, {}, {}});
1356+
{"global", (uint16_t)VER_NDX_GLOBAL, {}});
13581357

13591358
// If --retain-symbol-file is used, we'll keep only the symbols listed in
13601359
// the file and discard all others.
13611360
if (auto *arg = args.getLastArg(OPT_retain_symbols_file)) {
1362-
config->versionDefinitions[VER_NDX_LOCAL].nonLocalPatterns.push_back(
1361+
config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(
13631362
{"*", /*isExternCpp=*/false, /*hasWildcard=*/true});
13641363
if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
13651364
for (StringRef s : args::getLines(*buffer))
1366-
config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(
1365+
config->versionDefinitions[VER_NDX_GLOBAL].patterns.push_back(
13671366
{s, /*isExternCpp=*/false, /*hasWildcard=*/false});
13681367
}
13691368

lld/ELF/ScriptParser.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,9 +1496,9 @@ void ScriptParser::readAnonymousDeclaration() {
14961496
std::vector<SymbolVersion> globals;
14971497
std::tie(locals, globals) = readSymbols();
14981498
for (const SymbolVersion &pat : locals)
1499-
config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat);
1499+
config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
15001500
for (const SymbolVersion &pat : globals)
1501-
config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat);
1501+
config->versionDefinitions[VER_NDX_GLOBAL].patterns.push_back(pat);
15021502

15031503
expect(";");
15041504
}
@@ -1510,12 +1510,13 @@ void ScriptParser::readVersionDeclaration(StringRef verStr) {
15101510
std::vector<SymbolVersion> locals;
15111511
std::vector<SymbolVersion> globals;
15121512
std::tie(locals, globals) = readSymbols();
1513+
for (const SymbolVersion &pat : locals)
1514+
config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
15131515

15141516
// Create a new version definition and add that to the global symbols.
15151517
VersionDefinition ver;
15161518
ver.name = verStr;
1517-
ver.nonLocalPatterns = std::move(globals);
1518-
ver.localPatterns = std::move(locals);
1519+
ver.patterns = globals;
15191520
ver.id = config->versionDefinitions.size();
15201521
config->versionDefinitions.push_back(ver);
15211522

lld/ELF/SymbolTable.cpp

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -150,24 +150,19 @@ std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
150150
return {};
151151
}
152152

153-
std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver,
154-
bool includeNonDefault) {
153+
std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver) {
155154
std::vector<Symbol *> res;
156155
SingleStringMatcher m(ver.name);
157156

158157
if (ver.isExternCpp) {
159158
for (auto &p : getDemangledSyms())
160159
if (m.match(p.first()))
161-
for (Symbol *sym : p.second)
162-
if (includeNonDefault || !sym->getName().contains('@'))
163-
res.push_back(sym);
160+
res.insert(res.end(), p.second.begin(), p.second.end());
164161
return res;
165162
}
166163

167164
for (Symbol *sym : symVector)
168-
if (canBeVersioned(*sym) &&
169-
(includeNonDefault || !sym->getName().contains('@')) &&
170-
m.match(sym->getName()))
165+
if (canBeVersioned(*sym) && m.match(sym->getName()))
171166
res.push_back(sym);
172167
return res;
173168
}
@@ -177,7 +172,7 @@ void SymbolTable::handleDynamicList() {
177172
for (SymbolVersion &ver : config->dynamicList) {
178173
std::vector<Symbol *> syms;
179174
if (ver.hasWildcard)
180-
syms = findAllByVersion(ver, /*includeNonDefault=*/true);
175+
syms = findAllByVersion(ver);
181176
else
182177
syms = findByVersion(ver);
183178

@@ -186,12 +181,21 @@ void SymbolTable::handleDynamicList() {
186181
}
187182
}
188183

189-
// Set symbol versions to symbols. This function handles patterns containing no
190-
// wildcard characters. Return false if no symbol definition matches ver.
191-
bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
184+
// Set symbol versions to symbols. This function handles patterns
185+
// containing no wildcard characters.
186+
void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
192187
StringRef versionName) {
188+
if (ver.hasWildcard)
189+
return;
190+
193191
// Get a list of symbols which we need to assign the version to.
194192
std::vector<Symbol *> syms = findByVersion(ver);
193+
if (syms.empty()) {
194+
if (!config->undefinedVersion)
195+
error("version script assignment of '" + versionName + "' to symbol '" +
196+
ver.name + "' failed: symbol not defined");
197+
return;
198+
}
195199

196200
auto getName = [](uint16_t ver) -> std::string {
197201
if (ver == VER_NDX_LOCAL)
@@ -203,10 +207,10 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
203207

204208
// Assign the version.
205209
for (Symbol *sym : syms) {
206-
// For a non-local versionId, skip symbols containing version info because
207-
// symbol versions specified by symbol names take precedence over version
208-
// scripts. See parseSymbolVersion().
209-
if (versionId != VER_NDX_LOCAL && sym->getName().contains('@'))
210+
// Skip symbols containing version info because symbol versions
211+
// specified by symbol names take precedence over version scripts.
212+
// See parseSymbolVersion().
213+
if (sym->getName().contains('@'))
210214
continue;
211215

212216
// If the version has not been assigned, verdefIndex is -1. Use an arbitrary
@@ -221,15 +225,13 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
221225
warn("attempt to reassign symbol '" + ver.name + "' of " +
222226
getName(sym->versionId) + " to " + getName(versionId));
223227
}
224-
return !syms.empty();
225228
}
226229

227-
void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
228-
bool includeNonDefault) {
230+
void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
229231
// Exact matching takes precedence over fuzzy matching,
230232
// so we set a version to a symbol only if no version has been assigned
231233
// to the symbol. This behavior is compatible with GNU.
232-
for (Symbol *sym : findAllByVersion(ver, includeNonDefault))
234+
for (Symbol *sym : findAllByVersion(ver))
233235
if (sym->verdefIndex == UINT32_C(-1)) {
234236
sym->verdefIndex = 0;
235237
sym->versionId = versionId;
@@ -242,57 +244,26 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
242244
// script file, the script does not actually define any symbol version,
243245
// but just specifies symbols visibilities.
244246
void SymbolTable::scanVersionScript() {
245-
SmallString<128> buf;
246247
// First, we assign versions to exact matching symbols,
247248
// i.e. version definitions not containing any glob meta-characters.
248-
std::vector<Symbol *> syms;
249-
for (VersionDefinition &v : config->versionDefinitions) {
250-
auto assignExact = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
251-
bool found = assignExactVersion(pat, id, ver);
252-
found |= assignExactVersion({(pat.name + "@" + v.name).toStringRef(buf),
253-
pat.isExternCpp, /*hasWildCard=*/false},
254-
id, ver);
255-
if (!found && !config->undefinedVersion)
256-
errorOrWarn("version script assignment of '" + ver + "' to symbol '" +
257-
pat.name + "' failed: symbol not defined");
258-
};
259-
for (SymbolVersion &pat : v.nonLocalPatterns)
260-
if (!pat.hasWildcard)
261-
assignExact(pat, v.id, v.name);
262-
for (SymbolVersion pat : v.localPatterns)
263-
if (!pat.hasWildcard)
264-
assignExact(pat, VER_NDX_LOCAL, "local");
265-
}
249+
for (VersionDefinition &v : config->versionDefinitions)
250+
for (SymbolVersion &pat : v.patterns)
251+
assignExactVersion(pat, v.id, v.name);
266252

267253
// Next, assign versions to wildcards that are not "*". Note that because the
268254
// last match takes precedence over previous matches, we iterate over the
269255
// definitions in the reverse order.
270-
auto assignWildcard = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
271-
assignWildcardVersion(pat, id, /*includeNonDefault=*/false);
272-
assignWildcardVersion({(pat.name + "@" + ver).toStringRef(buf),
273-
pat.isExternCpp, /*hasWildCard=*/true},
274-
id,
275-
/*includeNonDefault=*/true);
276-
};
277-
for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) {
278-
for (SymbolVersion &pat : v.nonLocalPatterns)
256+
for (VersionDefinition &v : llvm::reverse(config->versionDefinitions))
257+
for (SymbolVersion &pat : v.patterns)
279258
if (pat.hasWildcard && pat.name != "*")
280-
assignWildcard(pat, v.id, v.name);
281-
for (SymbolVersion &pat : v.localPatterns)
282-
if (pat.hasWildcard && pat.name != "*")
283-
assignWildcard(pat, VER_NDX_LOCAL, v.name);
284-
}
259+
assignWildcardVersion(pat, v.id);
285260

286261
// Then, assign versions to "*". In GNU linkers they have lower priority than
287262
// other wildcards.
288-
for (VersionDefinition &v : config->versionDefinitions) {
289-
for (SymbolVersion &pat : v.nonLocalPatterns)
263+
for (VersionDefinition &v : config->versionDefinitions)
264+
for (SymbolVersion &pat : v.patterns)
290265
if (pat.hasWildcard && pat.name == "*")
291-
assignWildcard(pat, v.id, v.name);
292-
for (SymbolVersion &pat : v.localPatterns)
293-
if (pat.hasWildcard && pat.name == "*")
294-
assignWildcard(pat, VER_NDX_LOCAL, v.name);
295-
}
266+
assignWildcardVersion(pat, v.id);
296267

297268
// Symbol themselves might know their versions because symbols
298269
// can contain versions in the form of <name>@<version>.

lld/ELF/SymbolTable.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,12 @@ class SymbolTable {
6565

6666
private:
6767
std::vector<Symbol *> findByVersion(SymbolVersion ver);
68-
std::vector<Symbol *> findAllByVersion(SymbolVersion ver,
69-
bool includeNonDefault);
68+
std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
7069

7170
llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
72-
bool assignExactVersion(SymbolVersion ver, uint16_t versionId,
71+
void assignExactVersion(SymbolVersion ver, uint16_t versionId,
7372
StringRef versionName);
74-
void assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
75-
bool includeNonDefault);
73+
void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
7674

7775
// The order the global symbols are in is not defined. We can use an arbitrary
7876
// order, but it has to be reproducible. That is true even when cross linking.

lld/ELF/Symbols.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,6 @@ OutputSection *Symbol::getOutputSection() const {
208208
// If a symbol name contains '@', the characters after that is
209209
// a symbol version name. This function parses that.
210210
void Symbol::parseSymbolVersion() {
211-
// Return if localized by a local: pattern in a version script.
212-
if (versionId == VER_NDX_LOCAL)
213-
return;
214211
StringRef s = getName();
215212
size_t pos = s.find('@');
216213
if (pos == 0 || pos == StringRef::npos)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# REQUIRES: x86
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4+
# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; }; };" > %t.script
5+
# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6+
# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s --check-prefix=NOMATCH
7+
8+
# NOMATCH: DynamicSymbols [
9+
# NOMATCH-NOT: _Z3aaaPi@@FOO
10+
# NOMATCH-NOT: _Z3aaaPf@@FOO
11+
# NOMATCH: ]
12+
13+
# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; aaa*; }; };" > %t2.script
14+
# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
15+
# RUN: llvm-readobj --dyn-syms %t2.so | FileCheck %s --check-prefix=MATCH
16+
# MATCH: DynamicSymbols [
17+
# MATCH: _Z3aaaPi@@FOO
18+
# MATCH: _Z3aaaPf@@FOO
19+
# MATCH: ]
20+
21+
.text
22+
.globl _Z3aaaPi
23+
.type _Z3aaaPi,@function
24+
_Z3aaaPi:
25+
retq
26+
27+
.globl _Z3aaaPf
28+
.type _Z3aaaPf,@function
29+
_Z3aaaPf:
30+
retq
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# REQUIRES: x86
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4+
# RUN: echo "FOO { global: extern \"C++\" { foo*; }; };" > %t.script
5+
# RUN: echo "BAR { global: extern \"C++\" { zed*; bar; }; };" >> %t.script
6+
# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
7+
# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck %s
8+
9+
# CHECK: VersionSymbols [
10+
# CHECK: Name: _Z3fooi@@FOO
11+
# CHECK: Name: _Z3bari
12+
# CHECK: Name: _Z3zedi@@BAR
13+
14+
.text
15+
.globl _Z3fooi
16+
.type _Z3fooi,@function
17+
_Z3fooi:
18+
retq
19+
20+
.globl _Z3bari
21+
.type _Z3bari,@function
22+
_Z3bari:
23+
retq
24+
25+
.globl _Z3zedi
26+
.type _Z3zedi,@function
27+
_Z3zedi:
28+
retq

0 commit comments

Comments
 (0)