summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp40
-rw-r--r--lld/ELF/SymbolTable.h1
-rw-r--r--lld/test/ELF/dynamic-list-preempt.s7
-rw-r--r--lld/test/ELF/version-script-reassign.s5
4 files changed, 29 insertions, 24 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();
}
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 26a5adac6e7..b64707f4ab0 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -64,7 +64,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);
diff --git a/lld/test/ELF/dynamic-list-preempt.s b/lld/test/ELF/dynamic-list-preempt.s
index c19acc891da..024f9302a00 100644
--- a/lld/test/ELF/dynamic-list-preempt.s
+++ b/lld/test/ELF/dynamic-list-preempt.s
@@ -7,9 +7,14 @@
# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s
# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=DYNSYMS %s
+# RUN: echo "V1 { global: foo; bar; local: *; };" > %t.vers
+# RUN: ld.lld --hash-style=sysv -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so
+# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s
+# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=DYNSYMS %s
+
# RELOCS: Relocations [
# RELOCS-NEXT: Section ({{.*}}) .rela.plt {
-# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo 0x0
+# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo{{.*}} 0x0
# RELOCS-NEXT: R_X86_64_JUMP_SLOT ext 0x0
# RELOCS-NEXT: }
# RELOCS-NEXT: ]
diff --git a/lld/test/ELF/version-script-reassign.s b/lld/test/ELF/version-script-reassign.s
index e2413295cc4..62b32cba82b 100644
--- a/lld/test/ELF/version-script-reassign.s
+++ b/lld/test/ELF/version-script-reassign.s
@@ -4,6 +4,7 @@
# RUN: echo '{ global: foo; local: *; };' > %tg.ver
# RUN: echo 'V1 { global: foo; };' > %t1.ver
# RUN: echo 'V2 { global: foo; };' > %t2.ver
+# RUN: echo 'V2 { global: notexist; local: f*; };' > %t2w.ver
## Note, ld.bfd errors on the two cases.
# RUN: ld.lld -shared %t.o --version-script %tl.ver --version-script %t1.ver \
@@ -18,6 +19,10 @@
# RUN: -o %t.so 2>&1 | FileCheck --check-prefix=V1-WARN %s
# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=V1-SYM %s
+# RUN: ld.lld -shared %t.o --version-script %t1.ver --version-script %t2w.ver \
+# RUN: -o %t.so --fatal-warnings
+# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=V1-SYM %s
+
# LOCAL: warning: attempt to reassign symbol 'foo' of VER_NDX_LOCAL to version 'V1'
# LOCAL-SYM-NOT: foo
OpenPOWER on IntegriCloud