[lld] r291569 - Add support for anonymous local symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 10 08:37:24 PST 2017


Author: rafael
Date: Tue Jan 10 10:37:24 2017
New Revision: 291569

URL: http://llvm.org/viewvc/llvm-project?rev=291569&view=rev
Log:
Add support for anonymous local symbols.

This actually simplifies the code a bit as now all local symbols are
handled uniformly.

This should fix the build of www/webkit2-gtk3.

Added:
    lld/trunk/test/ELF/version-script-anonymous-local.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/SymbolTable.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=291569&r1=291568&r2=291569&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Jan 10 10:37:24 2017
@@ -1014,6 +1014,7 @@ private:
   void readAnonymousDeclaration();
   void readVersionDeclaration(StringRef VerStr);
   std::vector<SymbolVersion> readSymbols();
+  void readLocals();
 
   ScriptConfiguration &Opt = *ScriptConfig;
   bool IsUnderSysroot;
@@ -1861,17 +1862,22 @@ void ScriptParser::readAnonymousDeclarat
   if (consume("global:") || peek() != "local:")
     Config->VersionScriptGlobals = readSymbols();
 
-  // Next, read local symbols.
-  if (consume("local:")) {
-    if (consume("*")) {
+  readLocals();
+  expect("}");
+  expect(";");
+}
+
+void ScriptParser::readLocals() {
+  if (!consume("local:"))
+    return;
+  std::vector<SymbolVersion> Locals = readSymbols();
+  for (SymbolVersion V : Locals) {
+    if (V.Name == "*") {
       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
-      expect(";");
-    } else {
-      setError("local symbol list for anonymous version is not supported");
+      continue;
     }
+    Config->VersionScriptLocals.push_back(V);
   }
-  expect("}");
-  expect(";");
 }
 
 // Reads a list of symbols, e.g. "VerStr { global: foo; bar; local: *; };".
@@ -1885,16 +1891,7 @@ void ScriptParser::readVersionDeclaratio
   if (consume("global:") || peek() != "local:")
     Config->VersionDefinitions.back().Globals = readSymbols();
 
-  // Read local symbols.
-  if (consume("local:")) {
-    if (consume("*")) {
-      Config->DefaultSymbolVersion = VER_NDX_LOCAL;
-      expect(";");
-    } else {
-      for (SymbolVersion V : readSymbols())
-        Config->VersionScriptLocals.push_back(V);
-    }
-  }
+  readLocals();
   expect("}");
 
   // Each version may have a parent version. For example, "Ver2"

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=291569&r1=291568&r2=291569&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Jan 10 10:37:24 2017
@@ -605,19 +605,16 @@ SymbolTable<ELFT>::findAllByVersion(Symb
 
 // 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. We assume that the script was
-// in the form of { global: foo; bar; local *; }. So, local is default.
-// In this function, we make specified symbols global.
+// but just specifies symbols visibilities.
 template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() {
-  for (SymbolVersion &Ver : Config->VersionScriptGlobals) {
-    if (Ver.HasWildcard) {
-      for (SymbolBody *B : findAllByVersion(Ver))
-        B->symbol()->VersionId = VER_NDX_GLOBAL;
-      continue;
-    }
-    for (SymbolBody *B : findByVersion(Ver))
-      B->symbol()->VersionId = VER_NDX_GLOBAL;
-  }
+  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);
 }
 
 // Set symbol versions to symbols. This function handles patterns
@@ -673,10 +670,7 @@ template <class ELFT> void SymbolTable<E
       Sym->body()->parseSymbolVersion();
 
   // Handle edge cases first.
-  if (!Config->VersionScriptGlobals.empty()) {
-    handleAnonymousVersion();
-    return;
-  }
+  handleAnonymousVersion();
 
   if (Config->VersionDefinitions.empty())
     return;
@@ -687,8 +681,6 @@ template <class ELFT> void SymbolTable<E
 
   // First, we assign versions to exact matching symbols,
   // i.e. version definitions not containing any glob meta-characters.
-  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);
@@ -697,8 +689,6 @@ template <class ELFT> void SymbolTable<E
   // i.e. version definitions containing glob meta-characters.
   // Note that because the last match takes precedence over previous matches,
   // we iterate over the definitions in the reverse order.
-  for (SymbolVersion &Ver : Config->VersionScriptLocals)
-    assignWildcardVersion(Ver, VER_NDX_LOCAL);
   for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
     for (SymbolVersion &Ver : V.Globals)
       assignWildcardVersion(Ver, V.Id);

Added: lld/trunk/test/ELF/version-script-anonymous-local.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script-anonymous-local.s?rev=291569&view=auto
==============================================================================
--- lld/trunk/test/ELF/version-script-anonymous-local.s (added)
+++ lld/trunk/test/ELF/version-script-anonymous-local.s Tue Jan 10 10:37:24 2017
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: echo "{ global: foo; local: bar; };" > %t.script
+# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# CHECK:       DynamicSymbols [
+# CHECK-NEXT:    Symbol {
+# CHECK-NEXT:     Name:
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding:
+# CHECK-NEXT:     Type:
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section:
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: foo
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Global
+# CHECK-NEXT:     Type:
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section:
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name: zed
+# CHECK-NEXT:     Value:
+# CHECK-NEXT:     Size:
+# CHECK-NEXT:     Binding: Global
+# CHECK-NEXT:     Type:
+# CHECK-NEXT:     Other:
+# CHECK-NEXT:     Section:
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+
+.global foo
+foo:
+.global bar
+bar:
+.global zed
+zed:




More information about the llvm-commits mailing list