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

Rui Ueyama ruiu at google.com
Wed Jun 19 11:01:02 PDT 2013


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130619/08c2ad1b/attachment.html>


More information about the llvm-commits mailing list