<div dir="ltr">As per Ed Maste's report, this change should be the last one which needs to link "hello world" on the FreeBSD platform.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 13, 2015 at 9:34 AM, Rui Ueyama via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ruiu<br>
Date: Tue Oct 13 11:34:14 2015<br>
New Revision: 250176<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=250176&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=250176&view=rev</a><br>
Log:<br>
ELF2: Fix BSD's __progname symbol issue.<br>
<br>
BSD's DSO files have undefined symbol "__progname" which is defined<br>
in crt1.o. On that system, both user programs and system shared<br>
libraries depend on each other.<br>
<br>
In general, we need to put symbols defined by user programs which are<br>
referenced by shared libraries to user program's .dynsym.<br>
<br>
<a href="http://reviews.llvm.org/D13637" rel="noreferrer" target="_blank">http://reviews.llvm.org/D13637</a><br>
<br>
Added:<br>
    lld/trunk/test/elf2/progname.s<br>
Modified:<br>
    lld/trunk/ELF/Driver.cpp<br>
    lld/trunk/ELF/InputFiles.cpp<br>
    lld/trunk/ELF/InputFiles.h<br>
    lld/trunk/ELF/SymbolTable.cpp<br>
    lld/trunk/ELF/SymbolTable.h<br>
<br>
Modified: lld/trunk/ELF/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=250176&r1=250175&r2=250176&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=250176&r1=250175&r2=250176&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Driver.cpp (original)<br>
+++ lld/trunk/ELF/Driver.cpp Tue Oct 13 11:34:14 2015<br>
@@ -227,5 +227,6 @@ template <class ELFT> void LinkerDriver:<br>
     Config->OutputFile = "a.out";<br>
<br>
   // Write the result to the file.<br>
+  Symtab.finalize();<br>
   writeResult<ELFT>(&Symtab);<br>
 }<br>
<br>
Modified: lld/trunk/ELF/InputFiles.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=250176&r1=250175&r2=250176&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=250176&r1=250175&r2=250176&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputFiles.cpp (original)<br>
+++ lld/trunk/ELF/InputFiles.cpp Tue Oct 13 11:34:14 2015<br>
@@ -301,14 +301,14 @@ template <class ELFT> void SharedFile<EL<br>
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());<br>
   SymbolBodies.reserve(NumSymbols);<br>
   for (const Elf_Sym &Sym : Syms) {<br>
-    if (Sym.isUndefined())<br>
-      continue;<br>
-<br>
     ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);<br>
     error(NameOrErr.getError());<br>
     StringRef Name = *NameOrErr;<br>
<br>
-    SymbolBodies.emplace_back(this, Name, Sym);<br>
+    if (Sym.isUndefined())<br>
+      Undefs.push_back(Name);<br>
+    else<br>
+      SymbolBodies.emplace_back(this, Name, Sym);<br>
   }<br>
 }<br>
<br>
<br>
Modified: lld/trunk/ELF/InputFiles.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=250176&r1=250175&r2=250176&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=250176&r1=250175&r2=250176&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputFiles.h (original)<br>
+++ lld/trunk/ELF/InputFiles.h Tue Oct 13 11:34:14 2015<br>
@@ -169,6 +169,7 @@ template <class ELFT> class SharedFile :<br>
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;<br>
<br>
   std::vector<SharedSymbol<ELFT>> SymbolBodies;<br>
+  std::vector<StringRef> Undefs;<br>
   StringRef SoName;<br>
<br>
 public:<br>
@@ -177,6 +178,8 @@ public:<br>
     return SymbolBodies;<br>
   }<br>
<br>
+  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }<br>
+<br>
   static bool classof(const InputFile *F) {<br>
     return F->kind() == Base::SharedKind;<br>
   }<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=250176&r1=250175&r2=250176&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=250176&r1=250175&r2=250176&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.cpp (original)<br>
+++ lld/trunk/ELF/SymbolTable.cpp Tue Oct 13 11:34:14 2015<br>
@@ -181,6 +181,13 @@ template <class ELFT> Symbol *SymbolTabl<br>
   return Sym;<br>
 }<br>
<br>
+template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {<br>
+  auto It = Symtab.find(Name);<br>
+  if (It == Symtab.end())<br>
+    return nullptr;<br>
+  return It->second->Body;<br>
+}<br>
+<br>
 template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *New) {<br>
   Symbol *Sym = insert(New);<br>
   if (Sym->Body == New)<br>
@@ -230,6 +237,20 @@ template <class ELFT> void SymbolTable<E<br>
   addFile(std::move(File));<br>
 }<br>
<br>
+template <class ELFT> void SymbolTable<ELFT>::finalize() {<br>
+  // This code takes care of the case in which shared libraries depend on<br>
+  // the user program (not the other way, which is usual). Shared libraries<br>
+  // may have undefined symbols, expecting that the user program provides<br>
+  // the definitions for them. An example is BSD's __progname symbol.<br>
+  // We need to put such symbols to the main program's .dynsym so that<br>
+  // shared libraries can find them.<br>
+  for (std::unique_ptr<SharedFile<ELFT>> &File : SharedFiles)<br>
+    for (StringRef U : File->getUndefinedSymbols())<br>
+      if (SymbolBody *Sym = find(U))<br>
+        if (Sym->isDefined())<br>
+          Sym->setUsedInDynamicReloc();<br>
+}<br>
+<br>
 template class lld::elf2::SymbolTable<ELF32LE>;<br>
 template class lld::elf2::SymbolTable<ELF32BE>;<br>
 template class lld::elf2::SymbolTable<ELF64LE>;<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=250176&r1=250175&r2=250176&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=250176&r1=250175&r2=250176&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.h (original)<br>
+++ lld/trunk/ELF/SymbolTable.h Tue Oct 13 11:34:14 2015<br>
@@ -52,6 +52,7 @@ public:<br>
   void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,<br>
                        typename llvm::object::ELFFile<ELFT>::uintX_t Value);<br>
   void addIgnoredSym(StringRef Name);<br>
+  void finalize();<br>
<br>
 private:<br>
   Symbol *insert(SymbolBody *New);<br>
@@ -60,6 +61,7 @@ private:<br>
   void addMemberFile(Lazy *Body);<br>
   void checkCompatibility(std::unique_ptr<InputFile> &File);<br>
   void resolve(SymbolBody *Body);<br>
+  SymbolBody *find(StringRef Name);<br>
   void reportConflict(const Twine &Message, const SymbolBody &Old,<br>
                       const SymbolBody &New, bool Warning);<br>
<br>
<br>
Added: lld/trunk/test/elf2/progname.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/progname.s?rev=250176&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/progname.s?rev=250176&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/elf2/progname.s (added)<br>
+++ lld/trunk/test/elf2/progname.s Tue Oct 13 11:34:14 2015<br>
@@ -0,0 +1,20 @@<br>
+// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o<br>
+// RUN: echo '.global __progname' > %t2.s<br>
+// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %t2.s -o %t2.o<br>
+// RUN: ld.lld2 -shared %t2.o -o %t2.so<br>
+// RUN: ld.lld2 -o %t %t.o %t2.so<br>
+// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s<br>
+<br>
+// CHECK:      Name:     __progname@<br>
+// CHECK-NEXT: Value:    0x11000<br>
+// CHECK-NEXT: Size:     0<br>
+// CHECK-NEXT: Binding:  Global (0x1)<br>
+// CHECK-NEXT: Type:     None (0x0)<br>
+// CHECK-NEXT: Other:    0<br>
+// CHECK-NEXT: Section:  .text<br>
+// CHECK-NEXT: }<br>
+<br>
+.global _start, __progname<br>
+_start:<br>
+__progname:<br>
+  nop<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>