mirror of
https://github.com/opnsense/src.git
synced 2026-03-15 23:25:30 -04:00
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
2 changed files with 18 additions and 23 deletions
|
|
@ -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 @@ private:
|
|||
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 a new issue