blob: 588576a0d1a1d353e210d531e89d83f17aedf239 [file] [log] [blame] [edit]
//===- lib/Driver/GnuLdInputGraph.cpp -------------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/Driver/GnuLdInputGraph.h"
#include "lld/ReaderWriter/LinkerScript.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
using namespace lld;
llvm::ErrorOr<StringRef> ELFFileNode::getPath(const LinkingContext &) const {
if (_attributes._isDashlPrefix)
return _elfLinkingContext.searchLibrary(_path);
return _elfLinkingContext.searchFile(_path, _attributes._isSysRooted);
}
std::string ELFFileNode::errStr(std::error_code errc) {
if (errc == llvm::errc::no_such_file_or_directory) {
if (_attributes._isDashlPrefix)
return (Twine("Unable to find library -l") + _path).str();
return (Twine("Unable to find file ") + _path).str();
}
return FileNode::errStr(errc);
}
/// \brief Parse the input file to lld::File.
std::error_code ELFFileNode::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";
if (_attributes._isWholeArchive) {
std::vector<std::unique_ptr<File>> parsedFiles;
if (std::error_code ec = ctx.registry().parseFile(
std::move(mb.get()), parsedFiles))
return ec;
assert(parsedFiles.size() == 1);
std::unique_ptr<File> f(parsedFiles[0].release());
if (const auto *archive = dyn_cast<ArchiveLibraryFile>(f.get())) {
// Have this node own the FileArchive object.
_archiveFile.reset(archive);
f.release();
// Add all members to _files vector
return archive->parseAllMembers(_files);
}
// if --whole-archive is around non-archive, just use it as normal.
_files.push_back(std::move(f));
return std::error_code();
}
return ctx.registry().parseFile(std::move(mb.get()), _files);
}