diff options
Diffstat (limited to 'lld/ELF/SymbolTable.cpp')
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index db8ee8f4d7b3..b9ef28f0436f 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -309,13 +309,43 @@ void SymbolTable::scanVersionScript() { // Then, assign versions to "*". In GNU linkers they have lower priority than // other wildcards. + bool globalAsteriskFound = false; + bool localAsteriskFound = false; + bool asteriskReported = false; + auto assignAsterisk = [&](SymbolVersion &pat, VersionDefinition *ver, + bool isLocal) { + // Avoid issuing a warning if both '--retain-symbol-file' and a version + // script with `global: *` are used. + // + // '--retain-symbol-file' adds a "*" pattern to + // 'config->versionDefinitions[VER_NDX_LOCAL].nonLocalPatterns', see + // 'readConfigs()' in 'Driver.cpp'. Note that it is not '.localPatterns', + // and may seem counterintuitive, but still works as expected. Here we can + // exploit that and skip analyzing the pattern added for this option. + if (!asteriskReported && (isLocal || ver->id > VER_NDX_LOCAL)) { + if ((isLocal && globalAsteriskFound) || + (!isLocal && localAsteriskFound)) { + warn("wildcard pattern '*' is used for both 'local' and 'global' " + "scopes in version script"); + asteriskReported = true; + } else if (!isLocal && globalAsteriskFound) { + warn("wildcard pattern '*' is used for multiple version definitions in " + "version script"); + asteriskReported = true; + } else { + localAsteriskFound = isLocal; + globalAsteriskFound = !isLocal; + } + } + assignWildcard(pat, isLocal ? VER_NDX_LOCAL : ver->id, ver->name); + }; for (VersionDefinition &v : llvm::reverse(ctx.arg.versionDefinitions)) { for (SymbolVersion &pat : v.nonLocalPatterns) if (pat.hasWildcard && pat.name == "*") - assignWildcard(pat, v.id, v.name); + assignAsterisk(pat, &v, false); for (SymbolVersion &pat : v.localPatterns) if (pat.hasWildcard && pat.name == "*") - assignWildcard(pat, VER_NDX_LOCAL, v.name); + assignAsterisk(pat, &v, true); } // Symbol themselves might know their versions because symbols |
