diff options
Diffstat (limited to 'lld/ELF/SymbolTable.cpp')
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 252e1201c0c..fde08064a60 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -153,20 +153,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) { @@ -241,23 +227,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)) @@ -269,4 +259,10 @@ 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(); } |