[PATCH] D13960: [ELF2] Symbol Versioning: part 1, VERSION() directive parsing

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 21 15:02:54 PDT 2015


davide created this revision.
davide added reviewers: ruiu, rafael.
davide added a subscriber: llvm-commits.

So, this is a WIP. But it's enough that I can parse non-trivial trees, e.g.

VERSION {
   VERS_1.1 {
       global:
         x;
         *;
       local:
         zelda;
   };
  VERS_1.2 {
    local:
      z;
  };
  VERS_1.3 {
    global:
      y;
  } VERS_1.1;
  VERS_1.4 {
    x;
  } VERS_1.3;
}

There are a couple of issues with the current code:

1) It's not able to parse 'extern' :
     	 extern "C++" {
     		 ns::*;
     		 "f(int, double)";
     	 };
2) It currently thinks ':' is a token (which I'm not completely sure it's right). So, when parsing namespaces (see example above) it will fail.

Still, this is expressive enough to parse almost every single version script FreeBSD base system ships with (modulo bugs). I hope to collect feedback, implement semantic action, and only after that commit.

http://reviews.llvm.org/D13960

Files:
  ELF/LinkerScript.cpp

Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/StringSaver.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace lld;
@@ -50,6 +51,7 @@
   void readOutputArch();
   void readOutputFormat();
   void readSearchDir();
+  void readVersion();
 
   StringSaver Saver;
   std::vector<StringRef> Tokens;
@@ -78,6 +80,8 @@
       readOutputFormat();
     } else if (Tok == "SEARCH_DIR") {
       readSearchDir();
+    } else if (Tok == "VERSION") {
+      readVersion();
     } else {
       error("unknown directive: " + Tok);
     }
@@ -105,7 +109,7 @@
     // Unquoted token
     size_t Pos = S.find_first_not_of(
         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-        "0123456789_.$/\\~=+[]*?-:");
+        "0123456789_.$/\\~=+[]*?-");
     // A character that cannot start a word (which is usually a
     // punctuation) forms a single character token.
     if (Pos == 0)
@@ -255,6 +259,46 @@
   expect(")");
 }
 
+void LinkerScript::readVersion() {
+  StringRef Tok, TokNext;
+  expect("{");
+  for (;;) {
+    Tok = next();
+    if (Tok == "}")
+      break;
+    expect("{");
+    Tok = next();
+
+    // Neither global or local is specified.
+    // Just parse the list of the symbols.
+    if (Tok != "global" && Tok != "local") {
+      expect(";");
+      while ((Tok = next()) != "}")
+        TokNext = next();
+      TokNext = next();
+    } else {
+      TokNext = next();
+
+      // Parse global symbols.
+      if (Tok == "global" && TokNext == ":")
+        do {
+          Tok = next(); // Symbol name
+          TokNext = next();
+        } while (Tok != "}");
+
+      // Parse local symbols.
+      if (Tok == "local" && TokNext == ":")
+        do {
+          Tok = next(); // Symbol name
+          TokNext = next();
+        } while (Tok != "}");
+    }
+    if (TokNext != ";")
+      // Dependency on another version.
+      expect(";");
+  }
+}
+
 // Entry point. The other functions or classes are private to this file.
 void lld::elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) {
   LinkerScript(A, MB.getBuffer()).run();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13960.38054.patch
Type: text/x-patch
Size: 2323 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151021/9995c559/attachment.bin>


More information about the llvm-commits mailing list