<div dir="ltr"><div>Michael,</div><div><br></div><div>I'll revert this change for now as it broke buildbots. I could repro it on my local machine too.</div><div><br></div><a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/13755/steps/test/logs/stdio">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/13755/steps/test/logs/stdio</a></div>

<div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Mar 19, 2014 at 6:28 PM, Michael J. Spencer <span dir="ltr"><<a href="mailto:bigcheesegs@gmail.com" target="_blank">bigcheesegs@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mspencer<br>
Date: Wed Mar 19 20:28:23 2014<br>
New Revision: 204291<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=204291&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=204291&view=rev</a><br>
Log:<br>
[ELF] Order DT_NEEDED entries by command line order.<br>
<br>
With this all test-suite tests pass with lld on x86-64 Linux.<br>
<br>
Added:<br>
    lld/trunk/test/elf/DT_NEEDED-order.test<br>
    lld/trunk/test/elf/Inputs/use-shared2.x86-64<br>
Modified:<br>
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h<br>
    lld/trunk/test/elf/Inputs/use-shared.c<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=204291&r1=204290&r2=204291&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=204291&r1=204290&r2=204291&view=diff</a><br>


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


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


==============================================================================<br>
--- lld/trunk/test/elf/Inputs/use-shared.c (original)<br>
+++ lld/trunk/test/elf/Inputs/use-shared.c Wed Mar 19 20:28:23 2014<br>
@@ -1,7 +1,8 @@<br>
 extern int i;<br>
+extern long long x __attribute__((weak));<br>
 void foo();<br>
<br>
 int main() {<br>
   foo();<br>
-  return i;<br>
+  return i + x;<br>
 }<br>
<br>
Added: lld/trunk/test/elf/Inputs/use-shared2.x86-64<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared2.x86-64?rev=204291&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared2.x86-64?rev=204291&view=auto</a><br>


==============================================================================<br>
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<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>