Pull in r365760 from upstream lld trunk (by Fangrui Song):
[ELF] Handle non-glob patterns before glob patterns in version scripts & fix a corner case of --dynamic-list This fixes PR38549, which is silently accepted by ld.bfd. This seems correct because it makes sense to let non-glob patterns take precedence over glob patterns. lld issues an error because `assignWildcardVersion(ver, VER_NDX_LOCAL);` is processed before `assignExactVersion(ver, v.id, v.name);`. Move all assignWildcardVersion() calls after assignExactVersion() calls to fix this. Also, move handleDynamicList() to the bottom. computeBinding() called by includeInDynsym() has this cryptic rule: if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible) return STB_LOCAL; Before the change: * foo's version is set to VER_NDX_LOCAL due to `local: *` * handleDynamicList() is called - foo.computeBinding() is STB_LOCAL - foo.includeInDynsym() is false - foo.isPreemptible is not set (wrong) * foo's version is set to V1 After the change: * foo's version is set to VER_NDX_LOCAL due to `local: *` * foo's version is set to V1 * handleDynamicList() is called - foo.computeBinding() is STB_GLOBAL - foo.includeInDynsym() is true - foo.isPreemptible is set (correct) Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D64550 This makes it longer necessary to patch the version scripts for the samba ports, to avoid "duplicate symbol 'pdb_search_init' in version script" errors. PR: 230602 MFC after: 3 days
This commit is contained in:
parent
409a80e5a4
commit
f7e8f5d439
@ -654,20 +654,6 @@ std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
// If there's only one anonymous version definition in a version
|
||||
// script file, the script does not actually define any symbol version,
|
||||
// but just specifies symbols visibilities.
|
||||
void SymbolTable::handleAnonymousVersion() {
|
||||
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
||||
assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
|
||||
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
||||
assignWildcardVersion(Ver, VER_NDX_GLOBAL);
|
||||
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
||||
assignExactVersion(Ver, VER_NDX_LOCAL, "local");
|
||||
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
||||
assignWildcardVersion(Ver, VER_NDX_LOCAL);
|
||||
}
|
||||
|
||||
// Handles -dynamic-list.
|
||||
void SymbolTable::handleDynamicList() {
|
||||
for (SymbolVersion &Ver : Config->DynamicList) {
|
||||
@ -731,23 +717,27 @@ void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
|
||||
|
||||
// This function processes version scripts by updating VersionId
|
||||
// member of symbols.
|
||||
// If there's only one anonymous version definition in a version
|
||||
// script file, the script does not actually define any symbol version,
|
||||
// but just specifies symbols visibilities.
|
||||
void SymbolTable::scanVersionScript() {
|
||||
// Handle edge cases first.
|
||||
handleAnonymousVersion();
|
||||
handleDynamicList();
|
||||
|
||||
// Now we have version definitions, so we need to set version ids to symbols.
|
||||
// Each version definition has a glob pattern, and all symbols that match
|
||||
// with the pattern get that version.
|
||||
|
||||
// First, we assign versions to exact matching symbols,
|
||||
// i.e. version definitions not containing any glob meta-characters.
|
||||
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
||||
assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
|
||||
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
||||
assignExactVersion(Ver, VER_NDX_LOCAL, "local");
|
||||
for (VersionDefinition &V : Config->VersionDefinitions)
|
||||
for (SymbolVersion &Ver : V.Globals)
|
||||
assignExactVersion(Ver, V.Id, V.Name);
|
||||
|
||||
// Next, we assign versions to fuzzy matching symbols,
|
||||
// i.e. version definitions containing glob meta-characters.
|
||||
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
||||
assignWildcardVersion(Ver, VER_NDX_GLOBAL);
|
||||
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
||||
assignWildcardVersion(Ver, VER_NDX_LOCAL);
|
||||
|
||||
// Note that because the last match takes precedence over previous matches,
|
||||
// we iterate over the definitions in the reverse order.
|
||||
for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
|
||||
@ -759,6 +749,12 @@ void SymbolTable::scanVersionScript() {
|
||||
// Let them parse and update their names to exclude version suffix.
|
||||
for (Symbol *Sym : SymVector)
|
||||
Sym->parseSymbolVersion();
|
||||
|
||||
// isPreemptible is false at this point. To correctly compute the binding of a
|
||||
// Defined (which is used by includeInDynsym()), we need to know if it is
|
||||
// VER_NDX_LOCAL or not. If defaultSymbolVersion is VER_NDX_LOCAL, we should
|
||||
// compute symbol versions before handling --dynamic-list.
|
||||
handleDynamicList();
|
||||
}
|
||||
|
||||
template void SymbolTable::addFile<ELF32LE>(InputFile *);
|
||||
|
@ -90,7 +90,6 @@ class SymbolTable {
|
||||
std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
|
||||
|
||||
llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
|
||||
void handleAnonymousVersion();
|
||||
void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
|
||||
StringRef VersionName);
|
||||
void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
|
||||
|
Loading…
Reference in New Issue
Block a user