[lld] r280284 - Linker script: support VERSION command.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 31 13:03:54 PDT 2016


Author: ruiu
Date: Wed Aug 31 15:03:54 2016
New Revision: 280284

URL: http://llvm.org/viewvc/llvm-project?rev=280284&view=rev
Log:
Linker script: support VERSION command.

Summary:
VERSION commands define symbol versions. The grammar of the
commnad is as follows

  VERSION { version-script-commands }

where version-script-commands is

  [ name ] { version-definitions }.

Note that we already support version-script-commands because
it is being used for version script command.

This patch is based on George's patch https://reviews.llvm.org/D23609

Reviewers: grimar

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D24089

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/ELF/verdef.s
    lld/trunk/test/ELF/version-script.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=280284&r1=280283&r2=280284&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Aug 31 15:03:54 2016
@@ -653,6 +653,8 @@ private:
   void readPhdrs();
   void readSearchDir();
   void readSections();
+  void readVersion();
+  void readVersionScriptCommand();
 
   SymbolAssignment *readAssignment(StringRef Name);
   OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
@@ -676,7 +678,7 @@ private:
 
   // For parsing version script.
   void readExtern(std::vector<SymbolVersion> *Globals);
-  void readVersion(StringRef VerStr);
+  void readVersionDeclaration(StringRef VerStr);
   void readGlobal(StringRef VerStr);
   void readLocal();
 
@@ -698,29 +700,39 @@ const StringMap<elf::ScriptParser::Handl
     {"PHDRS", &ScriptParser::readPhdrs},
     {"SEARCH_DIR", &ScriptParser::readSearchDir},
     {"SECTIONS", &ScriptParser::readSections},
+    {"VERSION", &ScriptParser::readVersion},
     {";", &ScriptParser::readNothing}};
 
 void ScriptParser::readVersionScript() {
-  StringRef Msg = "anonymous version definition is used in "
-                  "combination with other version definitions";
+  readVersionScriptCommand();
+  if (!atEOF())
+    setError("EOF expected, but got " + next());
+}
+
+void ScriptParser::readVersionScriptCommand() {
   if (skip("{")) {
-    readVersion("");
-    if (!atEOF())
-      setError(Msg);
+    readVersionDeclaration("");
     return;
   }
 
-  while (!atEOF() && !Error) {
+  while (!atEOF() && !Error && peek() != "}") {
     StringRef VerStr = next();
     if (VerStr == "{") {
-      setError(Msg);
+      setError("anonymous version definition is used in "
+               "combination with other version definitions");
       return;
     }
     expect("{");
-    readVersion(VerStr);
+    readVersionDeclaration(VerStr);
   }
 }
 
+void ScriptParser::readVersion() {
+  expect("{");
+  readVersionScriptCommand();
+  expect("}");
+}
+
 void ScriptParser::readLinkerScript() {
   while (!atEOF()) {
     StringRef Tok = next();
@@ -1377,7 +1389,7 @@ unsigned ScriptParser::readPhdrType() {
   return Ret;
 }
 
-void ScriptParser::readVersion(StringRef VerStr) {
+void ScriptParser::readVersionDeclaration(StringRef VerStr) {
   // Identifiers start at 2 because 0 and 1 are reserved
   // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
   size_t VersionId = Config->VersionDefinitions.size() + 2;

Modified: lld/trunk/test/ELF/verdef.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/verdef.s?rev=280284&r1=280283&r2=280284&view=diff
==============================================================================
--- lld/trunk/test/ELF/verdef.s (original)
+++ lld/trunk/test/ELF/verdef.s Wed Aug 31 15:03:54 2016
@@ -101,6 +101,14 @@
 # MAIN-NEXT: SHT_GNU_verdef {
 # MAIN-NEXT: }
 
+# RUN: echo "VERSION { \
+# RUN:       LIBSAMPLE_1.0 { global: a; local: *; }; \
+# RUN:       LIBSAMPLE_2.0 { global: b; local: *; }; \
+# RUN:       LIBSAMPLE_3.0 { global: c; local: *; }; \
+# RUN:       }" > %t.script
+# RUN: ld.lld --script %t.script -shared -soname shared %t.o -o %t2.so
+# RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s
+
 .globl a
 .type  a, at function
 a:

Modified: lld/trunk/test/ELF/version-script.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/version-script.s?rev=280284&r1=280283&r2=280284&view=diff
==============================================================================
--- lld/trunk/test/ELF/version-script.s (original)
+++ lld/trunk/test/ELF/version-script.s Wed Aug 31 15:03:54 2016
@@ -35,8 +35,8 @@
 # RUN:          global: foo3; \
 # RUN:          local: *; }; " > %t5.script
 # RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
-# RUN:   FileCheck -check-prefix=ERR %s
-# ERR: anonymous version definition is used in combination with other version definitions
+# RUN:   FileCheck -check-prefix=ERR1 %s
+# ERR1: anonymous version definition is used in combination with other version definitions
 
 # RUN: echo    "{             \
 # RUN:          global: foo1; \
@@ -45,7 +45,8 @@
 # RUN:          global: foo3; \
 # RUN:          local: *; }; " > %t5.script
 # RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
-# RUN:   FileCheck -check-prefix=ERR %s
+# RUN:   FileCheck -check-prefix=ERR2 %s
+# ERR2: EOF expected, but got VERSION_2.0
 
 # RUN: echo "VERSION_1.0{     \
 # RUN:          global: foo1; \




More information about the llvm-commits mailing list