[lld] r273423 - [ELF] - Implemented version script hierarchies.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 22 07:40:46 PDT 2016


Author: grimar
Date: Wed Jun 22 09:40:45 2016
New Revision: 273423

URL: http://llvm.org/viewvc/llvm-project?rev=273423&view=rev
Log:
[ELF] - Implemented version script hierarchies.

Patch implements hierarchies for version scripts. 
This allows to handle script files with dependencies, like next one has:

LIBSAMPLE_1.0{
  global:
  a;
};

LIBSAMPLE_2.0
{
  global:
  b;
}LIBSAMPLE_1.0;

Differential revision: http://reviews.llvm.org/D21556

Added:
    lld/trunk/test/ELF/verdef-dependency.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/SymbolListFile.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=273423&r1=273422&r2=273423&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Jun 22 09:40:45 2016
@@ -37,6 +37,7 @@ enum class BuildIdKind { None, Fnv1, Md5
 struct Version {
   Version(llvm::StringRef Name) : Name(Name) {}
   llvm::StringRef Name;
+  llvm::StringRef Parent;
   std::vector<llvm::StringRef> Globals;
   size_t NameOff; // Offset in string table.
 };

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=273423&r1=273422&r2=273423&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Jun 22 09:40:45 2016
@@ -1462,6 +1462,10 @@ template <class ELFT> void VersionDefini
 
   this->Header.sh_size =
       (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();
+  for (Version &V : Config->SymbolVersions)
+    if (!V.Parent.empty())
+      this->Header.sh_size += sizeof(Elf_Verdaux);
+
   this->Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
   this->Header.sh_addralign = sizeof(uint32_t);
 
@@ -1471,12 +1475,22 @@ template <class ELFT> void VersionDefini
   this->Header.sh_info = getVerDefNum();
 }
 
+static size_t getVersionNameStrTabOffset(StringRef Name) {
+  for (Version &V : Config->SymbolVersions)
+    if (V.Name == Name)
+      return V.NameOff;
+  error("unknown version name " + Name + " used as a dependency");
+  return 0;
+}
+
 template <class Elf_Verdef, class Elf_Verdaux>
 static void writeDefinition(Elf_Verdef *&Verdef, Elf_Verdaux *&Verdaux,
                             uint32_t Flags, uint32_t Index, StringRef Name,
-                            size_t StrTabOffset) {
+                            size_t StrTabOffset, StringRef ParentName) {
+  bool HasParent = !ParentName.empty();
+
   Verdef->vd_version = 1;
-  Verdef->vd_cnt = 1;
+  Verdef->vd_cnt = HasParent ? 2 : 1;
   Verdef->vd_aux =
       reinterpret_cast<char *>(Verdaux) - reinterpret_cast<char *>(Verdef);
   Verdef->vd_next = sizeof(Elf_Verdef);
@@ -1487,6 +1501,12 @@ static void writeDefinition(Elf_Verdef *
   ++Verdef;
 
   Verdaux->vda_name = StrTabOffset;
+  if (HasParent) {
+    Verdaux->vda_next = sizeof(Elf_Verdaux);
+    ++Verdaux;
+    Verdaux->vda_name = getVersionNameStrTabOffset(ParentName);
+  }
+
   Verdaux->vda_next = 0;
   ++Verdaux;
 }
@@ -1498,11 +1518,12 @@ void VersionDefinitionSection<ELFT>::wri
       reinterpret_cast<Elf_Verdaux *>(Verdef + getVerDefNum());
 
   writeDefinition(Verdef, Verdaux, VER_FLG_BASE, 1, getFileDefName(),
-                  FileDefNameOff);
+                  FileDefNameOff, "" /* Parent */);
 
   uint32_t I = 2;
   for (Version &V : Config->SymbolVersions)
-    writeDefinition(Verdef, Verdaux, 0 /* Flags */, I++, V.Name, V.NameOff);
+    writeDefinition(Verdef, Verdaux, 0 /* Flags */, I++, V.Name, V.NameOff,
+                    V.Parent);
 
   Verdef[-1].vd_next = 0;
 }

Modified: lld/trunk/ELF/SymbolListFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolListFile.cpp?rev=273423&r1=273422&r2=273423&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolListFile.cpp (original)
+++ lld/trunk/ELF/SymbolListFile.cpp Wed Jun 22 09:40:45 2016
@@ -94,6 +94,8 @@ void VersionScriptParser::parseVersion(S
     parseVersionSymbols(Version);
 
   expect("}");
+  if (!Version.empty() && peek() != ";")
+    Config->SymbolVersions.back().Parent = next();
   expect(";");
 }
 

Added: lld/trunk/test/ELF/verdef-dependency.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/verdef-dependency.s?rev=273423&view=auto
==============================================================================
--- lld/trunk/test/ELF/verdef-dependency.s (added)
+++ lld/trunk/test/ELF/verdef-dependency.s Wed Jun 22 09:40:45 2016
@@ -0,0 +1,56 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "LIBSAMPLE_1.0{               \
+# RUN:          global: a;                \
+# RUN:          local: *; };              \
+# RUN:       LIBSAMPLE_2.0{               \
+# RUN:          global: b;                \
+# RUN:          local: *; }LIBSAMPLE_1.0; \
+# RUN:       LIBSAMPLE_3.0{               \
+# RUN:          global: c;                \
+# RUN:          local: *; }LIBSAMPLE_2.0;" > %t.script
+# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
+# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# DSO:      SHT_GNU_verdef {
+# DSO-NEXT:   Definition {
+# DSO-NEXT:     Version: 1
+# DSO-NEXT:     Flags: Base
+# DSO-NEXT:     Index: 1
+# DSO-NEXT:     Hash: 127830196
+# DSO-NEXT:     Name: shared
+# DSO-NEXT:   }
+# DSO-NEXT:   Definition {
+# DSO-NEXT:     Version: 1
+# DSO-NEXT:     Flags: 0x0
+# DSO-NEXT:     Index: 2
+# DSO-NEXT:     Hash: 98457184
+# DSO-NEXT:     Name: LIBSAMPLE_1.0
+# DSO-NEXT:   }
+# DSO-NEXT:   Definition {
+# DSO-NEXT:     Version: 1
+# DSO-NEXT:     Flags: 0x0
+# DSO-NEXT:     Index: 3
+# DSO-NEXT:     Hash: 98456416
+# DSO-NEXT:     Name: LIBSAMPLE_2.0
+# DSO-NEXT:     Predecessor: LIBSAMPLE_1.0
+# DSO-NEXT:   }
+# DSO-NEXT:   Definition {
+# DSO-NEXT:     Version: 1
+# DSO-NEXT:     Flags: 0x0
+# DSO-NEXT:     Index: 4
+# DSO-NEXT:     Hash: 98456672
+# DSO-NEXT:     Name: LIBSAMPLE_3.0
+# DSO-NEXT:     Predecessor: LIBSAMPLE_2.0
+# DSO-NEXT:   }
+# DSO-NEXT: }
+
+# RUN: echo "LIBSAMPLE_1.0{               \
+# RUN:          global: a;                \
+# RUN:          local: *; };              \
+# RUN:       LIBSAMPLE_2.0{               \
+# RUN:          global: b;                \
+# RUN:          local: *; }LIBSAMPLE_X.X; " > %t.script
+# RUN: not ld.lld --version-script %t.script -shared %t.o -o %t.so 2>&1 \
+# RUN:   | FileCheck -check-prefix=ERR %s
+# ERR: unknown version name LIBSAMPLE_X.X used as a dependency




More information about the llvm-commits mailing list