<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>