<div dir="ltr">Shankar,<div><br></div><div>Noticed that Mac's ld supports the same feature as -u option, and so does Windows link.exe as /include. Should we add this feature to TargetInfo so that we can use that from all the TargetInfo's?</div>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 18, 2013 at 5:31 PM, Shankar Easwaran <span dir="ltr"><<a href="mailto:shankare@codeaurora.org" target="_blank">shankare@codeaurora.org</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: shankare<br>
Date: Tue Jun 18 19:31:09 2013<br>
New Revision: 184266<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=184266&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=184266&view=rev</a><br>
Log:<br>
[ELF] add -u/--undefined option, to define undefined symbols<br>
<br>
Added:<br>
    lld/trunk/test/elf/X86_64/Inputs/libfn.a<br>
    lld/trunk/test/elf/X86_64/undef.test<br>
Modified:<br>
    lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h<br>
    lld/trunk/lib/Driver/GnuLdDriver.cpp<br>
    lld/trunk/lib/Driver/LDOptions.td<br>
    lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h<br>
    lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h<br>
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h<br>
<br>
Modified: lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h?rev=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h (original)<br>
+++ lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h Tue Jun 18 19:31:09 2013<br>
@@ -12,6 +12,7 @@<br>
<br>
 #include "lld/Core/PassManager.h"<br>
 #include "lld/Core/Pass.h"<br>
+#include "lld/Core/range.h"<br>
 #include "lld/Core/TargetInfo.h"<br>
 #include "lld/ReaderWriter/Reader.h"<br>
 #include "lld/ReaderWriter/Writer.h"<br>
@@ -154,6 +155,22 @@ public:<br>
   /// Searches directories then calls appendInputFile()<br>
   bool appendLibrary(StringRef libName);<br>
<br>
+  /// adds undefined symbols that are specified in the command line<br>
+  void addUndefinedSymbol(StringRef symbolName) {<br>
+    _undefinedSymbols.push_back(symbolName);<br>
+  }<br>
+<br>
+  /// Iterators for symbols that appear on the command line<br>
+  typedef std::vector<StringRef> StringRefVector;<br>
+  typedef StringRefVector::iterator StringRefVectorIter;<br>
+  typedef StringRefVector::const_iterator StringRefVectorConstIter;<br>
+<br>
+  /// Return the list of undefined symbols that are specified in the<br>
+  /// linker command line, using the -u option.<br>
+  range<const StringRef *> undefinedSymbols() const {<br>
+    return _undefinedSymbols;<br>
+  }<br>
+<br>
 private:<br>
   ELFTargetInfo() LLVM_DELETED_FUNCTION;<br>
 protected:<br>
@@ -174,12 +191,13 @@ protected:<br>
   bool                               _dynamicLinkerArg;<br>
   bool                               _noAllowDynamicLibraries;<br>
   OutputMagic                        _outputMagic;<br>
-  std::vector<StringRef>             _inputSearchPaths;<br>
+  StringRefVector                    _inputSearchPaths;<br>
   llvm::BumpPtrAllocator             _extraStrings;<br>
   std::unique_ptr<Reader>            _elfReader;<br>
   std::unique_ptr<Writer>            _writer;<br>
   std::unique_ptr<Reader>            _linkerScriptReader;<br>
   StringRef                          _dynamicLinkerPath;<br>
+  StringRefVector                    _undefinedSymbols;<br>
 };<br>
 } // end namespace lld<br>
<br>
<br>
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)<br>
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Jun 18 19:31:09 2013<br>
@@ -217,6 +217,13 @@ GnuLdDriver::parse(int argc, const char<br>
   if (!options->allowLinkWithDynamicLibraries())<br>
     options->setIsStaticExecutable(true);<br>
<br>
+  // Handle -u, --undefined option<br>
+  for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_u),<br>
+                               ie = parsedArgs->filtered_end();<br>
+       it != ie; ++it) {<br>
+    options->addUndefinedSymbol((*it)->getValue());<br>
+  }<br>
+<br>
   // Handle -Lxxx<br>
   for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_L),<br>
                                ie = parsedArgs->filtered_end();<br>
<br>
Modified: lld/trunk/lib/Driver/LDOptions.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/LDOptions.td?rev=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/LDOptions.td?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/Driver/LDOptions.td (original)<br>
+++ lld/trunk/lib/Driver/LDOptions.td Tue Jun 18 19:31:09 2013<br>
@@ -72,6 +72,14 @@ def omagic_alias : Flag<["-"], "N">, Ali<br>
 def no_omagic : Flag<["--"], "no-omagic">,<br>
     HelpText<"This option negates most of the effects of the -N option. Disable linking with shared libraries">;<br>
<br>
+// TODO: remove the options with the = sign, once the change in the OptionParser<br>
+// is done to recognize the allowed suffixes for an argument.<br>
+def u : Separate<["-"], "u">,<br>
+    HelpText<"Force symbol to be entered in the output file as an undefined symbol">;<br>
+def undefined : Separate<["--"], "undefined">, Alias<u>;<br>
+def u_equal : Joined<["-"], "u=">, Alias<u>;<br>
+def undefined_equal : Joined<["--"], "undefined=">, Alias<u>;<br>
+<br>
 // extensions<br>
 def emit_yaml : Flag<["-"], "emit-yaml">,<br>
     HelpText<"Write YAML instead of ELF">;<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Tue Jun 18 19:31:09 2013<br>
@@ -31,7 +31,6 @@ public:<br>
 private:<br>
   void buildDynamicSymbolTable(const File &file);<br>
   void addDefaultAtoms();<br>
-  void addFiles(InputFiles&);<br>
   void finalizeDefaultAtomValues();<br>
<br>
   llvm::BumpPtrAllocator _alloc;<br>
@@ -63,11 +62,6 @@ void DynamicLibraryWriter<ELFT>::buildDy<br>
 template<class ELFT><br>
 void DynamicLibraryWriter<ELFT>::addDefaultAtoms() { }<br>
<br>
-template <class ELFT><br>
-void DynamicLibraryWriter<ELFT>::addFiles(InputFiles &inputFiles) {<br>
-  this->_targetHandler.addFiles(inputFiles);<br>
-}<br>
-<br>
 template<class ELFT><br>
 void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {<br>
   this->_targetHandler.finalizeSymbolValues();<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Tue Jun 18 19:31:09 2013<br>
@@ -64,10 +64,13 @@ void ExecutableWriter<ELFT>::addDefaultA<br>
 /// \brief Hook in lld to add CRuntime file<br>
 template <class ELFT><br>
 void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {<br>
+  // Add the default atoms as defined by executables<br>
   addDefaultAtoms();<br>
+  // Add the runtime file<br>
   inputFiles.prependFile(_runtimeFile);<br>
-  // Give a chance for the target to add atoms<br>
-  this->_targetHandler.addFiles(inputFiles);<br>
+  // Add the Linker internal file for symbols that are defined by<br>
+  // command line options<br>
+  OutputELFWriter<ELFT>::addFiles(inputFiles);<br>
 }<br>
<br>
 template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() {<br>
@@ -120,11 +123,14 @@ template <class ELFT> void ExecutableWri<br>
<br>
   auto bssSection = this->_layout->findOutputSection(".bss");<br>
<br>
-  (*bssStartAtomIter)->_virtualAddr = bssSection->virtualAddr();<br>
-  (*bssEndAtomIter)->_virtualAddr =<br>
-      bssSection->virtualAddr() + bssSection->memSize();<br>
-  (*underScoreEndAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;<br>
-  (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;<br>
+  // If we dont find a bss section, then dont set these values<br>
+  if (bssSection) {<br>
+    (*bssStartAtomIter)->_virtualAddr = bssSection->virtualAddr();<br>
+    (*bssEndAtomIter)->_virtualAddr =<br>
+        bssSection->virtualAddr() + bssSection->memSize();<br>
+    (*underScoreEndAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;<br>
+    (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;<br>
+  }<br>
<br>
   // Give a chance for the target to finalize its atom values<br>
   this->_targetHandler.finalizeSymbolValues();<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=184266&r1=184265&r2=184266&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=184266&r1=184265&r2=184266&view=diff</a><br>


==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Tue Jun 18 19:31:09 2013<br>
@@ -28,6 +28,15 @@ using namespace llvm::object;<br>
 template<class ELFT><br>
 class OutputELFWriter;<br>
<br>
+/// \brief This acts as a internal file that the linker uses to add<br>
+/// undefined symbols that are defined by using the linker options such<br>
+/// as -u, or --defsym option.<br>
+template <class ELFT> class LinkerInternalFile : public CRuntimeFile<ELFT> {<br>
+public:<br>
+  LinkerInternalFile(const ELFTargetInfo &ti)<br>
+      : CRuntimeFile<ELFT>(ti, "Linker Internal File") {};<br>
+};<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 //  OutputELFWriter Class<br>
 //===----------------------------------------------------------------------===//<br>
@@ -78,7 +87,7 @@ protected:<br>
   virtual void addDefaultAtoms() = 0;<br>
<br>
   // Add any runtime files and their atoms to the output<br>
-  virtual void addFiles(InputFiles&) = 0;<br>
+  virtual void addFiles(InputFiles &);<br>
<br>
   // Finalize the default atom values<br>
   virtual void finalizeDefaultAtomValues() = 0;<br>
@@ -114,6 +123,7 @@ protected:<br>
   LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;<br>
   llvm::StringSet<> _soNeeded;<br>
   /// @}<br>
+  LinkerInternalFile<ELFT> _linkerInternalFile;<br>
 };<br>
<br>
 //===----------------------------------------------------------------------===//<br>
@@ -121,7 +131,8 @@ protected:<br>
 //===----------------------------------------------------------------------===//<br>
 template <class ELFT><br>
 OutputELFWriter<ELFT>::OutputELFWriter(const ELFTargetInfo &ti)<br>
-    : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()) {<br>
+    : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),<br>
+      _linkerInternalFile(ti) {<br>
   _layout = &_targetHandler.targetLayout();<br>
 }<br>
<br>
@@ -223,8 +234,19 @@ void OutputELFWriter<ELFT>::assignSectio<br>
         _shdrtab->updateSection(section);<br>
 }<br>
<br>
-template<class ELFT><br>
-void OutputELFWriter<ELFT>::createDefaultSections() {<br>
+template <class ELFT><br>
+void OutputELFWriter<ELFT>::addFiles(InputFiles &inputFiles) {<br>
+  // Add all input Files that are defined by the target<br>
+  _targetHandler.addFiles(inputFiles);<br>
+  // Add all symbols that are specified by the -u option<br>
+  // as part of the command line argument to lld<br>
+  for (auto ai : _targetInfo.undefinedSymbols())<br>
+    _linkerInternalFile.addUndefinedAtom(ai);<br>
+  // Make the linker internal file to be the first file<br>
+  inputFiles.prependFile(_linkerInternalFile);<br>
+}<br>
+<br>
+template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {<br>
   _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));<br>
   _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));<br>
   _layout->setHeader(_Header.get());<br>
<br>
Added: lld/trunk/test/elf/X86_64/Inputs/libfn.a<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/libfn.a?rev=184266&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/libfn.a?rev=184266&view=auto</a><br>


==============================================================================<br>
Binary files lld/trunk/test/elf/X86_64/Inputs/libfn.a (added) and lld/trunk/test/elf/X86_64/Inputs/libfn.a Tue Jun 18 19:31:09 2013 differ<br>
<br>
Added: lld/trunk/test/elf/X86_64/undef.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/undef.test?rev=184266&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/undef.test?rev=184266&view=auto</a><br>


==============================================================================<br>
--- lld/trunk/test/elf/X86_64/undef.test (added)<br>
+++ lld/trunk/test/elf/X86_64/undef.test Tue Jun 18 19:31:09 2013<br>
@@ -0,0 +1,19 @@<br>
+# This tests the functionality that an undefined symbol thats defined in the<br>
+# commmand line pulls in the required object file from the archive library<br>
+# which is usually the usecase for it<br>
+RUN: lld -flavor gnu -target x86_64 -u fn %p/Inputs/libfn.a -o %t --noinhibit-exec<br>
+RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=SYMFROMARCHIVE %s<br>
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/libfn.a -o %t --noinhibit-exec<br>
+RUN: llvm-readobj -symbols %t | FileCheck %s<br>
+<br>
+SYMFROMARCHIVE:  Symbol {<br>
+SYMFROMARCHIVE:    Name: fn (16)<br>
+SYMFROMARCHIVE:    Value: 0x4001A4<br>
+SYMFROMARCHIVE:    Size: 11<br>
+SYMFROMARCHIVE:    Binding: Global (0x1)<br>
+SYMFROMARCHIVE:    Type: Function (0x2)<br>
+SYMFROMARCHIVE:    Other: 0<br>
+SYMFROMARCHIVE:    Section: .text (0x5)<br>
+SYMFROMARCHIVE:  }<br>
+<br>
+CHECK-NOT: Name: fn<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>