[lld] r218259 - [ELF] Fix linking when a regular object defines a symbol that is used in a DSO

Rui Ueyama ruiu at google.com
Mon Sep 22 10:52:51 PDT 2014


Author: ruiu
Date: Mon Sep 22 12:52:50 2014
New Revision: 218259

URL: http://llvm.org/viewvc/llvm-project?rev=218259&view=rev
Log:
[ELF] Fix linking when a regular object defines a symbol that is used in a DSO

Patch from Rafael Auler!

When a shared lib has an undefined symbol that is defined in a regular object
(the program), the final executable must export this symbol in the dynamic
symbol table. However, in the current logic, lld only puts the symbol in the
dynamic symbol table if the symbol is weak. This patch fixes lld to put the
symbol in the dynamic symbol table regardless if it is weak or not.

This caused a problem in FreeBSD10, whose programs link against a crt1.o
that defines the symbol __progname, which is, in turn, undefined in libc.so.7
and will only be resolved in runtime.

http://reviews.llvm.org/D5424

Added:
    lld/trunk/test/elf/undef-from-dso-to-main.test
Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=218259&r1=218258&r2=218259&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Mon Sep 22 12:52:50 2014
@@ -262,8 +262,8 @@ public:
 
   void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; }
 
-  bool hasCoalescedWeakPair(StringRef name) const {
-    return _weakCoalescedSymbols.count(name) != 0;
+  bool hasCoalescedSharedLibPair(StringRef name) const {
+    return _sharedLibCoalescedSymbols.count(name) != 0;
   }
 
 private:
@@ -300,7 +300,7 @@ protected:
   StringRefVector _rpathList;
   StringRefVector _rpathLinkList;
   std::map<std::string, uint64_t> _absoluteSymbols;
-  llvm::StringSet<> _weakCoalescedSymbols;
+  llvm::StringSet<> _sharedLibCoalescedSymbols;
 };
 } // end namespace lld
 

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=218259&r1=218258&r2=218259&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Mon Sep 22 12:52:50 2014
@@ -241,11 +241,6 @@ std::unique_ptr<File> ELFLinkingContext:
   return std::move(undefinedSymFile);
 }
 
-static bool isSharedWeakAtom(const UndefinedAtom *ua) {
-  return ua->canBeNull() != UndefinedAtom::canBeNullNever &&
-         isa<SharedLibraryFile>(ua->file());
-}
-
 void ELFLinkingContext::notifySymbolTableCoalesce(const Atom *existingAtom,
                                                   const Atom *newAtom,
                                                   bool &useNew) {
@@ -259,11 +254,12 @@ void ELFLinkingContext::notifySymbolTabl
     ua = dyn_cast<UndefinedAtom>(existingAtom);
   }
 
-  if (da && ua && da->scope() == Atom::scopeGlobal && isSharedWeakAtom(ua))
-    // If strong defined atom coalesces away weak atom declared
-    // in the shared object the strong atom needs to be dynamicaly exported.
+  if (da && ua && da->scope() == Atom::scopeGlobal &&
+      isa<SharedLibraryFile>(ua->file()))
+    // If strong defined atom coalesces away an atom declared
+    // in the shared object the strong atom needs to be dynamically exported.
     // Save its name.
-    _weakCoalescedSymbols.insert(ua->name());
+    _sharedLibCoalescedSymbols.insert(ua->name());
 }
 
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=218259&r1=218258&r2=218259&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Mon Sep 22 12:52:50 2014
@@ -183,7 +183,7 @@ void OutputELFWriter<ELFT>::buildDynamic
       for (const auto &atom : section->atoms()) {
         const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
         if (da && (da->dynamicExport() == DefinedAtom::dynamicExportAlways ||
-                   _context.hasCoalescedWeakPair(da->name())))
+                   _context.hasCoalescedSharedLibPair(da->name())))
           _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
                                          atom->_virtualAddr, atom);
       }

Added: lld/trunk/test/elf/undef-from-dso-to-main.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/undef-from-dso-to-main.test?rev=218259&view=auto
==============================================================================
--- lld/trunk/test/elf/undef-from-dso-to-main.test (added)
+++ lld/trunk/test/elf/undef-from-dso-to-main.test Mon Sep 22 12:52:50 2014
@@ -0,0 +1,7 @@
+# Tests that a reference from a DSO to a regular object
+# forces the final executable to export the symbol.
+
+RUN: lld -flavor gnu  -target x86_64 %p/Inputs/defobj.o -L%p/Inputs -lundef2 -o %t1
+RUN: llvm-readobj -dyn-symbols %t1 | FileCheck -check-prefix CHECKSYMS %s
+
+CHECKSYMS: myexportedsymbol





More information about the llvm-commits mailing list