[lld] r225330 - [ELF] Remove {ELF,}GNULinkerScript.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Jan 7 07:23:28 PST 2015


Nice!

On 6 January 2015 at 20:13, Rui Ueyama <ruiu at google.com> wrote:
> Author: ruiu
> Date: Tue Jan  6 19:13:08 2015
> New Revision: 225330
>
> URL: http://llvm.org/viewvc/llvm-project?rev=225330&view=rev
> Log:
> [ELF] Remove {ELF,}GNULinkerScript.
>
> Instead of representing a linker script file as an "InputElement",
> parse and evaluate scripts in the driver as we see them.
>
> Linker scripts are not regular input files (regular file is one of
> object, archive, or shared library file). They are more like
> extended command line options. Linker script handling was needlessly
> complicated because of that inappropriate abstraction (besides
> excessive class hierarchy -- there is no such thing like ELF linker
> script but we had two classes there for some reason.)
>
> LinkerScript was one of a few remaining InputElement subclasses
> that can be expanded to multiple files. With this patch, we are one
> step closer to retire InputElement.
>
> http://reviews.llvm.org/D6648
>
> Modified:
>     lld/trunk/include/lld/Driver/GnuLdInputGraph.h
>     lld/trunk/lib/Driver/GnuLdDriver.cpp
>     lld/trunk/lib/Driver/GnuLdInputGraph.cpp
>
> Modified: lld/trunk/include/lld/Driver/GnuLdInputGraph.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/GnuLdInputGraph.h?rev=225330&r1=225329&r2=225330&view=diff
> ==============================================================================
> --- lld/trunk/include/lld/Driver/GnuLdInputGraph.h (original)
> +++ lld/trunk/include/lld/Driver/GnuLdInputGraph.h Tue Jan  6 19:13:08 2015
> @@ -21,7 +21,6 @@
>  #include "lld/Core/InputGraph.h"
>  #include "lld/Core/Resolver.h"
>  #include "lld/ReaderWriter/ELFLinkingContext.h"
> -#include "lld/ReaderWriter/LinkerScript.h"
>
>  namespace lld {
>
> @@ -81,41 +80,6 @@ private:
>    const Attributes _attributes;
>  };
>
> -/// \brief Parse GNU Linker scripts.
> -class GNULdScript : public FileNode {
> -public:
> -  GNULdScript(ELFLinkingContext &ctx, StringRef userPath)
> -      : FileNode(userPath), _elfLinkingContext(ctx), _linkerScript(nullptr) {}
> -
> -  /// \brief Parse the linker script.
> -  std::error_code parse(const LinkingContext &, raw_ostream &) override;
> -
> -protected:
> -  ELFLinkingContext &_elfLinkingContext;
> -  std::unique_ptr<script::Parser> _parser;
> -  std::unique_ptr<script::Lexer> _lexer;
> -  script::LinkerScript *_linkerScript;
> -};
> -
> -/// \brief Handle ELF style with GNU Linker scripts.
> -class ELFGNULdScript : public GNULdScript {
> -public:
> -  ELFGNULdScript(ELFLinkingContext &ctx, StringRef userPath)
> -      : GNULdScript(ctx, userPath) {}
> -
> -  std::error_code parse(const LinkingContext &ctx,
> -                        raw_ostream &diagnostics) override;
> -
> -  bool getReplacements(InputGraph::InputElementVectorT &result) override {
> -    for (std::unique_ptr<InputElement> &elt : _expandElements)
> -      result.push_back(std::move(elt));
> -    return true;
> -  }
> -
> -private:
> -  InputGraph::InputElementVectorT _expandElements;
> -};
> -
>  } // namespace lld
>
>  #endif
>
> Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=225330&r1=225329&r2=225330&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
> +++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Jan  6 19:13:08 2015
> @@ -15,6 +15,7 @@
>
>  #include "lld/Driver/Driver.h"
>  #include "lld/Driver/GnuLdInputGraph.h"
> +#include "lld/ReaderWriter/LinkerScript.h"
>  #include "llvm/ADT/ArrayRef.h"
>  #include "llvm/ADT/Optional.h"
>  #include "llvm/ADT/STLExtras.h"
> @@ -217,6 +218,54 @@ static bool isLinkerScript(StringRef pat
>    return magic == llvm::sys::fs::file_magic::unknown;
>  }
>
> +static bool isPathUnderSysroot(StringRef sysroot, StringRef path) {
> +  if (sysroot.empty())
> +    return false;
> +  while (!path.empty() && !llvm::sys::fs::equivalent(sysroot, path))
> +    path = llvm::sys::path::parent_path(path);
> +  return !path.empty();
> +}
> +
> +static std::error_code
> +evaluateLinkerScript(ELFLinkingContext &ctx, InputGraph *inputGraph,
> +                     StringRef path, raw_ostream &diag) {
> +  // Read the script file from disk and parse.
> +  ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
> +      MemoryBuffer::getFileOrSTDIN(path);
> +  if (std::error_code ec = mb.getError())
> +    return ec;
> +  if (ctx.logInputFiles())
> +    diag << path << "\n";
> +  auto lexer = llvm::make_unique<script::Lexer>(std::move(mb.get()));
> +  auto parser = llvm::make_unique<script::Parser>(*lexer);
> +  script::LinkerScript *script = parser->parse();
> +  if (!script)
> +    return LinkerScriptReaderError::parse_error;
> +
> +  // Evaluate script commands.
> +  // Currently we only recognize GROUP() command.
> +  bool sysroot = (!ctx.getSysroot().empty()
> +                  && isPathUnderSysroot(ctx.getSysroot(), path));
> +  for (const script::Command *c : script->_commands) {
> +    auto *group = dyn_cast<script::Group>(c);
> +    if (!group)
> +      continue;
> +    int numfiles = 0;
> +    for (const script::Path &path : group->getPaths()) {
> +      // TODO : Propagate Set WholeArchive/dashlPrefix
> +      ELFFileNode::Attributes attr;
> +      attr.setSysRooted(sysroot);
> +      attr.setAsNeeded(path._asNeeded);
> +      attr.setDashlPrefix(path._isDashlPrefix);
> +      ++numfiles;
> +      inputGraph->addInputElement(llvm::make_unique<ELFFileNode>(
> +                                      ctx, ctx.allocateString(path._path), attr));
> +    }
> +    inputGraph->addInputElement(llvm::make_unique<GroupEnd>(numfiles));
> +  }
> +  return std::error_code();
> +}
> +
>  bool GnuLdDriver::applyEmulation(llvm::Triple &triple,
>                                   llvm::opt::InputArgList &args,
>                                   raw_ostream &diagnostics) {
> @@ -529,19 +578,19 @@ bool GnuLdDriver::parse(int argc, const
>        }
>        bool isScript =
>            (!path.endswith(".objtxt") && isLinkerScript(realpath, diagnostics));
> -      FileNode *inputNode = nullptr;
>        if (isScript) {
> -        inputNode = new ELFGNULdScript(*ctx, realpath);
> -        if (inputNode->parse(*ctx, diagnostics)) {
> -          diagnostics << path << ": Error parsing linker script\n";
> +        std::error_code ec = evaluateLinkerScript(
> +            *ctx, inputGraph.get(), realpath, diagnostics);
> +        if (ec) {
> +          diagnostics << path << ": Error parsing linker script: "
> +                      << ec.message() << "\n";
>            return false;
>          }
> -      } else {
> -        inputNode = new ELFFileNode(*ctx, path, attributes);
> +        break;
>        }
> -      std::unique_ptr<InputElement> inputFile(inputNode);
>        ++numfiles;
> -      inputGraph->addInputElement(std::move(inputFile));
> +      inputGraph->addInputElement(
> +          llvm::make_unique<ELFFileNode>(*ctx, path, attributes));
>        break;
>      }
>
>
> Modified: lld/trunk/lib/Driver/GnuLdInputGraph.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdInputGraph.cpp?rev=225330&r1=225329&r2=225330&view=diff
> ==============================================================================
> --- lld/trunk/lib/Driver/GnuLdInputGraph.cpp (original)
> +++ lld/trunk/lib/Driver/GnuLdInputGraph.cpp Tue Jan  6 19:13:08 2015
> @@ -63,68 +63,3 @@ std::error_code ELFFileNode::parse(const
>    }
>    return ctx.registry().parseFile(std::move(mb.get()), _files);
>  }
> -
> -/// \brief Parse the GnuLD Script
> -std::error_code GNULdScript::parse(const LinkingContext &ctx,
> -                                   raw_ostream &diagnostics) {
> -  ErrorOr<StringRef> filePath = getPath(ctx);
> -  if (std::error_code ec = filePath.getError())
> -    return ec;
> -  ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
> -      MemoryBuffer::getFileOrSTDIN(*filePath);
> -  if (std::error_code ec = mb.getError())
> -    return ec;
> -
> -  if (ctx.logInputFiles())
> -    diagnostics << *filePath << "\n";
> -
> -  _lexer.reset(new script::Lexer(std::move(mb.get())));
> -  _parser.reset(new script::Parser(*_lexer.get()));
> -
> -  _linkerScript = _parser->parse();
> -
> -  if (!_linkerScript)
> -    return LinkerScriptReaderError::parse_error;
> -
> -  return std::error_code();
> -}
> -
> -static bool isPathUnderSysroot(StringRef sysroot, StringRef path) {
> -  if (sysroot.empty())
> -    return false;
> -
> -  while (!path.empty() && !llvm::sys::fs::equivalent(sysroot, path))
> -    path = llvm::sys::path::parent_path(path);
> -
> -  return !path.empty();
> -}
> -
> -/// \brief Handle GnuLD script for ELF.
> -std::error_code ELFGNULdScript::parse(const LinkingContext &ctx,
> -                                      raw_ostream &diagnostics) {
> -  ELFFileNode::Attributes attributes;
> -  if (std::error_code ec = GNULdScript::parse(ctx, diagnostics))
> -    return ec;
> -  StringRef sysRoot = _elfLinkingContext.getSysroot();
> -  if (!sysRoot.empty() && isPathUnderSysroot(sysRoot, *getPath(ctx)))
> -    attributes.setSysRooted(true);
> -  for (const script::Command *c : _linkerScript->_commands) {
> -    auto *group = dyn_cast<script::Group>(c);
> -    if (!group)
> -      continue;
> -    size_t numfiles = 0;
> -    for (const script::Path &path : group->getPaths()) {
> -      // TODO : Propagate Set WholeArchive/dashlPrefix
> -      attributes.setAsNeeded(path._asNeeded);
> -      attributes.setDashlPrefix(path._isDashlPrefix);
> -      auto inputNode = new ELFFileNode(
> -          _elfLinkingContext, _elfLinkingContext.allocateString(path._path),
> -          attributes);
> -      std::unique_ptr<InputElement> inputFile(inputNode);
> -      _expandElements.push_back(std::move(inputFile));
> -      ++numfiles;
> -    }
> -    _expandElements.push_back(llvm::make_unique<GroupEnd>(numfiles));
> -  }
> -  return std::error_code();
> -}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list