@@ -150,24 +150,19 @@ std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
150
150
return {};
151
151
}
152
152
153
- std::vector<Symbol *> SymbolTable::findAllByVersion (SymbolVersion ver,
154
- bool includeNonDefault) {
153
+ std::vector<Symbol *> SymbolTable::findAllByVersion (SymbolVersion ver) {
155
154
std::vector<Symbol *> res;
156
155
SingleStringMatcher m (ver.name );
157
156
158
157
if (ver.isExternCpp ) {
159
158
for (auto &p : getDemangledSyms ())
160
159
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 ());
164
161
return res;
165
162
}
166
163
167
164
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 ()))
171
166
res.push_back (sym);
172
167
return res;
173
168
}
@@ -177,7 +172,7 @@ void SymbolTable::handleDynamicList() {
177
172
for (SymbolVersion &ver : config->dynamicList ) {
178
173
std::vector<Symbol *> syms;
179
174
if (ver.hasWildcard )
180
- syms = findAllByVersion (ver, /* includeNonDefault= */ true );
175
+ syms = findAllByVersion (ver);
181
176
else
182
177
syms = findByVersion (ver);
183
178
@@ -186,12 +181,21 @@ void SymbolTable::handleDynamicList() {
186
181
}
187
182
}
188
183
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,
192
187
StringRef versionName) {
188
+ if (ver.hasWildcard )
189
+ return ;
190
+
193
191
// Get a list of symbols which we need to assign the version to.
194
192
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
+ }
195
199
196
200
auto getName = [](uint16_t ver) -> std::string {
197
201
if (ver == VER_NDX_LOCAL)
@@ -203,10 +207,10 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
203
207
204
208
// Assign the version.
205
209
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 (' @' ))
210
214
continue ;
211
215
212
216
// 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,
221
225
warn (" attempt to reassign symbol '" + ver.name + " ' of " +
222
226
getName (sym->versionId ) + " to " + getName (versionId));
223
227
}
224
- return !syms.empty ();
225
228
}
226
229
227
- void SymbolTable::assignWildcardVersion (SymbolVersion ver, uint16_t versionId,
228
- bool includeNonDefault) {
230
+ void SymbolTable::assignWildcardVersion (SymbolVersion ver, uint16_t versionId) {
229
231
// Exact matching takes precedence over fuzzy matching,
230
232
// so we set a version to a symbol only if no version has been assigned
231
233
// to the symbol. This behavior is compatible with GNU.
232
- for (Symbol *sym : findAllByVersion (ver, includeNonDefault ))
234
+ for (Symbol *sym : findAllByVersion (ver))
233
235
if (sym->verdefIndex == UINT32_C (-1 )) {
234
236
sym->verdefIndex = 0 ;
235
237
sym->versionId = versionId;
@@ -242,57 +244,26 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
242
244
// script file, the script does not actually define any symbol version,
243
245
// but just specifies symbols visibilities.
244
246
void SymbolTable::scanVersionScript () {
245
- SmallString<128 > buf;
246
247
// First, we assign versions to exact matching symbols,
247
248
// 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 );
266
252
267
253
// Next, assign versions to wildcards that are not "*". Note that because the
268
254
// last match takes precedence over previous matches, we iterate over the
269
255
// 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 )
279
258
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 );
285
260
286
261
// Then, assign versions to "*". In GNU linkers they have lower priority than
287
262
// 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 )
290
265
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 );
296
267
297
268
// Symbol themselves might know their versions because symbols
298
269
// can contain versions in the form of <name>@<version>.
0 commit comments