[lld] r184266 - [ELF] add -u/--undefined option, to define undefined symbols

Shankar Easwaran shankare at codeaurora.org
Wed Jun 19 12:53:19 PDT 2013


Yes, it should be moved to TargetInfo, thanks for noticing that.

On 6/19/2013 1:01 PM, Rui Ueyama wrote:
> Shankar,
>
> 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?
>
>
> On Tue, Jun 18, 2013 at 5:31 PM, Shankar Easwaran
> <shankare at codeaurora.org>wrote:
>
>> Author: shankare
>> Date: Tue Jun 18 19:31:09 2013
>> New Revision: 184266
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=184266&view=rev
>> Log:
>> [ELF] add -u/--undefined option, to define undefined symbols
>>
>> Added:
>>      lld/trunk/test/elf/X86_64/Inputs/libfn.a
>>      lld/trunk/test/elf/X86_64/undef.test
>> Modified:
>>      lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h
>>      lld/trunk/lib/Driver/GnuLdDriver.cpp
>>      lld/trunk/lib/Driver/LDOptions.td
>>      lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
>>      lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
>>      lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
>>
>> Modified: lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h (original)
>> +++ lld/trunk/include/lld/ReaderWriter/ELFTargetInfo.h Tue Jun 18 19:31:09
>> 2013
>> @@ -12,6 +12,7 @@
>>
>>   #include "lld/Core/PassManager.h"
>>   #include "lld/Core/Pass.h"
>> +#include "lld/Core/range.h"
>>   #include "lld/Core/TargetInfo.h"
>>   #include "lld/ReaderWriter/Reader.h"
>>   #include "lld/ReaderWriter/Writer.h"
>> @@ -154,6 +155,22 @@ public:
>>     /// Searches directories then calls appendInputFile()
>>     bool appendLibrary(StringRef libName);
>>
>> +  /// adds undefined symbols that are specified in the command line
>> +  void addUndefinedSymbol(StringRef symbolName) {
>> +    _undefinedSymbols.push_back(symbolName);
>> +  }
>> +
>> +  /// Iterators for symbols that appear on the command line
>> +  typedef std::vector<StringRef> StringRefVector;
>> +  typedef StringRefVector::iterator StringRefVectorIter;
>> +  typedef StringRefVector::const_iterator StringRefVectorConstIter;
>> +
>> +  /// Return the list of undefined symbols that are specified in the
>> +  /// linker command line, using the -u option.
>> +  range<const StringRef *> undefinedSymbols() const {
>> +    return _undefinedSymbols;
>> +  }
>> +
>>   private:
>>     ELFTargetInfo() LLVM_DELETED_FUNCTION;
>>   protected:
>> @@ -174,12 +191,13 @@ protected:
>>     bool                               _dynamicLinkerArg;
>>     bool                               _noAllowDynamicLibraries;
>>     OutputMagic                        _outputMagic;
>> -  std::vector<StringRef>             _inputSearchPaths;
>> +  StringRefVector                    _inputSearchPaths;
>>     llvm::BumpPtrAllocator             _extraStrings;
>>     std::unique_ptr<Reader>            _elfReader;
>>     std::unique_ptr<Writer>            _writer;
>>     std::unique_ptr<Reader>            _linkerScriptReader;
>>     StringRef                          _dynamicLinkerPath;
>> +  StringRefVector                    _undefinedSymbols;
>>   };
>>   } // end namespace lld
>>
>>
>> Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
>> +++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Jun 18 19:31:09 2013
>> @@ -217,6 +217,13 @@ GnuLdDriver::parse(int argc, const char
>>     if (!options->allowLinkWithDynamicLibraries())
>>       options->setIsStaticExecutable(true);
>>
>> +  // Handle -u, --undefined option
>> +  for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_u),
>> +                               ie = parsedArgs->filtered_end();
>> +       it != ie; ++it) {
>> +    options->addUndefinedSymbol((*it)->getValue());
>> +  }
>> +
>>     // Handle -Lxxx
>>     for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_L),
>>                                  ie = parsedArgs->filtered_end();
>>
>> Modified: lld/trunk/lib/Driver/LDOptions.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/LDOptions.td?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/Driver/LDOptions.td (original)
>> +++ lld/trunk/lib/Driver/LDOptions.td Tue Jun 18 19:31:09 2013
>> @@ -72,6 +72,14 @@ def omagic_alias : Flag<["-"], "N">, Ali
>>   def no_omagic : Flag<["--"], "no-omagic">,
>>       HelpText<"This option negates most of the effects of the -N option.
>> Disable linking with shared libraries">;
>>
>> +// TODO: remove the options with the = sign, once the change in the
>> OptionParser
>> +// is done to recognize the allowed suffixes for an argument.
>> +def u : Separate<["-"], "u">,
>> +    HelpText<"Force symbol to be entered in the output file as an
>> undefined symbol">;
>> +def undefined : Separate<["--"], "undefined">, Alias<u>;
>> +def u_equal : Joined<["-"], "u=">, Alias<u>;
>> +def undefined_equal : Joined<["--"], "undefined=">, Alias<u>;
>> +
>>   // extensions
>>   def emit_yaml : Flag<["-"], "emit-yaml">,
>>       HelpText<"Write YAML instead of ELF">;
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Tue Jun 18
>> 19:31:09 2013
>> @@ -31,7 +31,6 @@ public:
>>   private:
>>     void buildDynamicSymbolTable(const File &file);
>>     void addDefaultAtoms();
>> -  void addFiles(InputFiles&);
>>     void finalizeDefaultAtomValues();
>>
>>     llvm::BumpPtrAllocator _alloc;
>> @@ -63,11 +62,6 @@ void DynamicLibraryWriter<ELFT>::buildDy
>>   template<class ELFT>
>>   void DynamicLibraryWriter<ELFT>::addDefaultAtoms() { }
>>
>> -template <class ELFT>
>> -void DynamicLibraryWriter<ELFT>::addFiles(InputFiles &inputFiles) {
>> -  this->_targetHandler.addFiles(inputFiles);
>> -}
>> -
>>   template<class ELFT>
>>   void DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
>>     this->_targetHandler.finalizeSymbolValues();
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Tue Jun 18 19:31:09
>> 2013
>> @@ -64,10 +64,13 @@ void ExecutableWriter<ELFT>::addDefaultA
>>   /// \brief Hook in lld to add CRuntime file
>>   template <class ELFT>
>>   void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
>> +  // Add the default atoms as defined by executables
>>     addDefaultAtoms();
>> +  // Add the runtime file
>>     inputFiles.prependFile(_runtimeFile);
>> -  // Give a chance for the target to add atoms
>> -  this->_targetHandler.addFiles(inputFiles);
>> +  // Add the Linker internal file for symbols that are defined by
>> +  // command line options
>> +  OutputELFWriter<ELFT>::addFiles(inputFiles);
>>   }
>>
>>   template <class ELFT> void
>> ExecutableWriter<ELFT>::createDefaultSections() {
>> @@ -120,11 +123,14 @@ template <class ELFT> void ExecutableWri
>>
>>     auto bssSection = this->_layout->findOutputSection(".bss");
>>
>> -  (*bssStartAtomIter)->_virtualAddr = bssSection->virtualAddr();
>> -  (*bssEndAtomIter)->_virtualAddr =
>> -      bssSection->virtualAddr() + bssSection->memSize();
>> -  (*underScoreEndAtomIter)->_virtualAddr =
>> (*bssEndAtomIter)->_virtualAddr;
>> -  (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
>> +  // If we dont find a bss section, then dont set these values
>> +  if (bssSection) {
>> +    (*bssStartAtomIter)->_virtualAddr = bssSection->virtualAddr();
>> +    (*bssEndAtomIter)->_virtualAddr =
>> +        bssSection->virtualAddr() + bssSection->memSize();
>> +    (*underScoreEndAtomIter)->_virtualAddr =
>> (*bssEndAtomIter)->_virtualAddr;
>> +    (*endAtomIter)->_virtualAddr = (*bssEndAtomIter)->_virtualAddr;
>> +  }
>>
>>     // Give a chance for the target to finalize its atom values
>>     this->_targetHandler.finalizeSymbolValues();
>>
>> Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=184266&r1=184265&r2=184266&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
>> +++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Tue Jun 18 19:31:09
>> 2013
>> @@ -28,6 +28,15 @@ using namespace llvm::object;
>>   template<class ELFT>
>>   class OutputELFWriter;
>>
>> +/// \brief This acts as a internal file that the linker uses to add
>> +/// undefined symbols that are defined by using the linker options such
>> +/// as -u, or --defsym option.
>> +template <class ELFT> class LinkerInternalFile : public
>> CRuntimeFile<ELFT> {
>> +public:
>> +  LinkerInternalFile(const ELFTargetInfo &ti)
>> +      : CRuntimeFile<ELFT>(ti, "Linker Internal File") {};
>> +};
>> +
>>
>>   //===----------------------------------------------------------------------===//
>>   //  OutputELFWriter Class
>>
>>   //===----------------------------------------------------------------------===//
>> @@ -78,7 +87,7 @@ protected:
>>     virtual void addDefaultAtoms() = 0;
>>
>>     // Add any runtime files and their atoms to the output
>> -  virtual void addFiles(InputFiles&) = 0;
>> +  virtual void addFiles(InputFiles &);
>>
>>     // Finalize the default atom values
>>     virtual void finalizeDefaultAtomValues() = 0;
>> @@ -114,6 +123,7 @@ protected:
>>     LLD_UNIQUE_BUMP_PTR(HashSection<ELFT>) _hashTable;
>>     llvm::StringSet<> _soNeeded;
>>     /// @}
>> +  LinkerInternalFile<ELFT> _linkerInternalFile;
>>   };
>>
>>
>>   //===----------------------------------------------------------------------===//
>> @@ -121,7 +131,8 @@ protected:
>>
>>   //===----------------------------------------------------------------------===//
>>   template <class ELFT>
>>   OutputELFWriter<ELFT>::OutputELFWriter(const ELFTargetInfo &ti)
>> -    : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()) {
>> +    : _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
>> +      _linkerInternalFile(ti) {
>>     _layout = &_targetHandler.targetLayout();
>>   }
>>
>> @@ -223,8 +234,19 @@ void OutputELFWriter<ELFT>::assignSectio
>>           _shdrtab->updateSection(section);
>>   }
>>
>> -template<class ELFT>
>> -void OutputELFWriter<ELFT>::createDefaultSections() {
>> +template <class ELFT>
>> +void OutputELFWriter<ELFT>::addFiles(InputFiles &inputFiles) {
>> +  // Add all input Files that are defined by the target
>> +  _targetHandler.addFiles(inputFiles);
>> +  // Add all symbols that are specified by the -u option
>> +  // as part of the command line argument to lld
>> +  for (auto ai : _targetInfo.undefinedSymbols())
>> +    _linkerInternalFile.addUndefinedAtom(ai);
>> +  // Make the linker internal file to be the first file
>> +  inputFiles.prependFile(_linkerInternalFile);
>> +}
>> +
>> +template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections()
>> {
>>     _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
>>     _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
>>     _layout->setHeader(_Header.get());
>>
>> Added: lld/trunk/test/elf/X86_64/Inputs/libfn.a
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/libfn.a?rev=184266&view=auto
>>
>> ==============================================================================
>> 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
>>
>> Added: lld/trunk/test/elf/X86_64/undef.test
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/undef.test?rev=184266&view=auto
>>
>> ==============================================================================
>> --- lld/trunk/test/elf/X86_64/undef.test (added)
>> +++ lld/trunk/test/elf/X86_64/undef.test Tue Jun 18 19:31:09 2013
>> @@ -0,0 +1,19 @@
>> +# This tests the functionality that an undefined symbol thats defined in
>> the
>> +# commmand line pulls in the required object file from the archive library
>> +# which is usually the usecase for it
>> +RUN: lld -flavor gnu -target x86_64 -u fn %p/Inputs/libfn.a -o %t
>> --noinhibit-exec
>> +RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=SYMFROMARCHIVE %s
>> +RUN: lld -flavor gnu -target x86_64 %p/Inputs/libfn.a -o %t
>> --noinhibit-exec
>> +RUN: llvm-readobj -symbols %t | FileCheck %s
>> +
>> +SYMFROMARCHIVE:  Symbol {
>> +SYMFROMARCHIVE:    Name: fn (16)
>> +SYMFROMARCHIVE:    Value: 0x4001A4
>> +SYMFROMARCHIVE:    Size: 11
>> +SYMFROMARCHIVE:    Binding: Global (0x1)
>> +SYMFROMARCHIVE:    Type: Function (0x2)
>> +SYMFROMARCHIVE:    Other: 0
>> +SYMFROMARCHIVE:    Section: .text (0x5)
>> +SYMFROMARCHIVE:  }
>> +
>> +CHECK-NOT: Name: fn
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation




More information about the llvm-commits mailing list