[lld] r204291 - [ELF] Order DT_NEEDED entries by command line order.

Michael J. Spencer bigcheesegs at gmail.com
Wed Mar 19 18:28:23 PDT 2014


Author: mspencer
Date: Wed Mar 19 20:28:23 2014
New Revision: 204291

URL: http://llvm.org/viewvc/llvm-project?rev=204291&view=rev
Log:
[ELF] Order DT_NEEDED entries by command line order.

With this all test-suite tests pass with lld on x86-64 Linux.

Added:
    lld/trunk/test/elf/DT_NEEDED-order.test
    lld/trunk/test/elf/Inputs/use-shared2.x86-64
Modified:
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
    lld/trunk/test/elf/Inputs/use-shared.c

Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=204291&r1=204290&r2=204291&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Wed Mar 19 20:28:23 2014
@@ -18,7 +18,7 @@
 #include "lld/ReaderWriter/ELFLinkingContext.h"
 #include "lld/ReaderWriter/Writer.h"
 
-#include "llvm/ADT/StringSet.h"
+#include <unordered_set>
 
 namespace lld {
 namespace elf {
@@ -129,7 +129,6 @@ protected:
   LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) _dynamicSymbolTable;
   LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _dynamicStringTable;
   LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
-  llvm::StringSet<> _soNeeded;
   /// @}
 };
 
@@ -165,6 +164,12 @@ void OutputELFWriter<ELFT>::buildStaticS
     _symtab->addSymbol(a, ELF::SHN_UNDEF);
 }
 
+struct StringRefFilePairHash {
+  std::size_t operator()(const std::pair<StringRef, const File *> &v) const {
+    return llvm::hash_combine(v.first, v.second);
+  }
+};
+
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
@@ -176,14 +181,26 @@ void OutputELFWriter<ELFT>::buildDynamic
           _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
                                          atom->_virtualAddr, atom);
       }
+  std::unordered_set<std::pair<StringRef, const File *>, StringRefFilePairHash>
+    soNeeded;
   for (const auto sla : file.sharedLibrary()) {
     _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
-    _soNeeded.insert(sla->loadName());
+    soNeeded.insert(std::make_pair(sla->loadName(), &sla->file()));
   }
-  for (const auto &loadName : _soNeeded) {
+  // Sort needed entries by command line order. This is needed so the correct
+  // dynamic symbol is loaded in cases where multiple dynamic libraries define
+  // the same symbol.
+  std::vector<std::pair<StringRef, const File *>> sortedSoNeeded(
+      soNeeded.begin(), soNeeded.end());
+  std::sort(sortedSoNeeded.begin(), sortedSoNeeded.end(),
+            [](const std::pair<StringRef, const File *> &a,
+               const std::pair<StringRef, const File *> &b) {
+    return a.second->ordinal() < b.second->ordinal();
+  });
+  for (auto const &lib : sortedSoNeeded) {
     Elf_Dyn dyn;
     dyn.d_tag = DT_NEEDED;
-    dyn.d_un.d_val = _dynamicStringTable->addString(loadName.getKey());
+    dyn.d_un.d_val = _dynamicStringTable->addString(lib.first);
     _dynamicTable->addEntry(dyn);
   }
   const auto &rpathList = _context.getRpathList();

Added: lld/trunk/test/elf/DT_NEEDED-order.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/DT_NEEDED-order.test?rev=204291&view=auto
==============================================================================
--- lld/trunk/test/elf/DT_NEEDED-order.test (added)
+++ lld/trunk/test/elf/DT_NEEDED-order.test Wed Mar 19 20:28:23 2014
@@ -0,0 +1,14 @@
+RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared2.x86-64 \
+RUN:   %p/Inputs/shared.so-x86-64 %p/Inputs/libundef.so -o %t -e main \
+RUN:   --noinhibit-exec
+RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared2.x86-64 \
+RUN:   %p/Inputs/libundef.so %p/Inputs/shared.so-x86-64 -o %t2 -e main \
+RUN:   --noinhibit-exec
+RUN: llvm-readobj -dynamic-table %t | FileCheck --check-prefix=ORDER1 %s
+RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=ORDER2 %s
+
+ORDER1: NEEDED SharedLibrary (shared.so
+ORDER1: NEEDED SharedLibrary (libundef.so
+
+ORDER2: NEEDED SharedLibrary (libundef.so
+ORDER2: NEEDED SharedLibrary (shared.so

Modified: lld/trunk/test/elf/Inputs/use-shared.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared.c?rev=204291&r1=204290&r2=204291&view=diff
==============================================================================
--- lld/trunk/test/elf/Inputs/use-shared.c (original)
+++ lld/trunk/test/elf/Inputs/use-shared.c Wed Mar 19 20:28:23 2014
@@ -1,7 +1,8 @@
 extern int i;
+extern long long x __attribute__((weak));
 void foo();
 
 int main() {
   foo();
-  return i;
+  return i + x;
 }

Added: lld/trunk/test/elf/Inputs/use-shared2.x86-64
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared2.x86-64?rev=204291&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/use-shared2.x86-64 (added) and lld/trunk/test/elf/Inputs/use-shared2.x86-64 Wed Mar 19 20:28:23 2014 differ





More information about the llvm-commits mailing list