Change the parseFile argument from MemoryBuffer pointer to LinkerInput

reference. Move readFile logic into FileNode::createLinkerInput.

llvm-svn: 190253
This commit is contained in:
Joerg Sonnenberger 2013-09-07 17:55:28 +00:00
parent 002c2a8ece
commit 5e235de9d3
32 changed files with 115 additions and 161 deletions

View File

@ -45,40 +45,37 @@ class LinkerInput {
LinkerInput(const LinkerInput &) LLVM_DELETED_FUNCTION; LinkerInput(const LinkerInput &) LLVM_DELETED_FUNCTION;
public: public:
explicit LinkerInput(StringRef file) explicit LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer,
: _file(file), _isForceLoad(false), _asNeeded(false) {} StringRef userPath)
: _buffer(std::move(buffer)), _userPath(userPath), _isForceLoad(false),
_asNeeded(false) {}
explicit LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer) explicit LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer,
: _buffer(std::move(buffer)), _file(_buffer->getBufferIdentifier()), const LinkerInput &other)
_isForceLoad(false), _asNeeded(false) {} : _buffer(std::move(buffer)), _userPath(other.getUserPath()),
_isForceLoad(other.isForceLoad()), _asNeeded(other.asNeeded()) {}
LinkerInput(LinkerInput &&other) LinkerInput(LinkerInput &&other)
: _buffer(std::move(other._buffer)), _file(std::move(other._file)), : _buffer(std::move(other._buffer)), _userPath(std::move(other._userPath)),
_isForceLoad(other.isForceLoad()), _asNeeded(other.asNeeded()) {} _isForceLoad(other.isForceLoad()), _asNeeded(other.asNeeded()) {}
LinkerInput &operator=(LinkerInput &&rhs) { LinkerInput &operator=(LinkerInput &&rhs) {
_buffer = std::move(rhs._buffer); _buffer = std::move(rhs._buffer);
_file = std::move(rhs._file); _userPath = std::move(rhs._userPath);
_isForceLoad = rhs.isForceLoad();
_asNeeded = rhs.asNeeded();
return *this; return *this;
} }
ErrorOr<llvm::MemoryBuffer&> getBuffer() const { StringRef getUserPath() const { return _userPath; }
if (!_buffer) {
llvm::OwningPtr<llvm::MemoryBuffer> buf;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(_file, buf))
return ec;
_buffer.reset(buf.take());
}
llvm::MemoryBuffer &getBuffer() const {
assert(_buffer);
return *_buffer; return *_buffer;
} }
StringRef getPath() const {
return _file;
}
std::unique_ptr<llvm::MemoryBuffer> takeBuffer() { std::unique_ptr<llvm::MemoryBuffer> takeBuffer() {
getBuffer(); assert(_buffer);
return std::move(_buffer); return std::move(_buffer);
} }
@ -96,8 +93,8 @@ public:
bool asNeeded() const { return _asNeeded; } bool asNeeded() const { return _asNeeded; }
private: private:
mutable std::unique_ptr<llvm::MemoryBuffer> _buffer; std::unique_ptr<llvm::MemoryBuffer> _buffer;
std::string _file; std::string _userPath;
bool _isForceLoad; bool _isForceLoad;
bool _asNeeded; bool _asNeeded;
}; };

View File

@ -12,11 +12,11 @@
#include "lld/Core/Error.h" #include "lld/Core/Error.h"
#include "lld/Core/LLVM.h" #include "lld/Core/LLVM.h"
#include "lld/Core/LinkerInput.h"
#include "lld/Core/range.h" #include "lld/Core/range.h"
#include "lld/Core/Reference.h" #include "lld/Core/Reference.h"
#include "lld/Driver/InputGraph.h" #include "lld/Driver/InputGraph.h"
#include "lld/Driver/LinkerInput.h"
#include "lld/ReaderWriter/Reader.h" #include "lld/ReaderWriter/Reader.h"
#include "llvm/Support/ErrorOr.h" #include "llvm/Support/ErrorOr.h"
@ -276,18 +276,9 @@ public:
/// The \p result is a vector because some input files parse into more than /// The \p result is a vector because some input files parse into more than
/// one lld::File (e.g. YAML). /// one lld::File (e.g. YAML).
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &inputBuff, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File> > &result) const = 0; std::vector<std::unique_ptr<File> > &result) const = 0;
/// This is a wrapper around parseFile() where the input file is specified
/// by file system path. The default implementation reads the input file
/// into a memory buffer and calls parseFile().
///
/// \param path This is the file system path to the input file.
/// \param [out] result The instantiated lld::File object is returned here.
virtual error_code
readFile(StringRef path, std::vector<std::unique_ptr<File> > &result) const;
/// This method is called by core linking to give the Writer a chance /// This method is called by core linking to give the Writer a chance
/// to add file format specific "files" to set of files to be linked. This is /// to add file format specific "files" to set of files to be linked. This is
/// how file format specific atoms can be added to the link. /// how file format specific atoms can be added to the link.

View File

@ -34,9 +34,6 @@ public:
return a->kind() == InputElement::Kind::File; return a->kind() == InputElement::Kind::File;
} }
virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
createLinkerInput(const lld::LinkingContext &);
/// \brief validates the Input Element /// \brief validates the Input Element
virtual bool validate() { virtual bool validate() {
(void)_ctx; (void)_ctx;

View File

@ -35,9 +35,6 @@ public:
return a->kind() == InputElement::Kind::File; return a->kind() == InputElement::Kind::File;
} }
virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
createLinkerInput(const lld::LinkingContext &);
/// \brief validates the Input Element /// \brief validates the Input Element
virtual bool validate() { virtual bool validate() {
(void)_ctx; (void)_ctx;

View File

@ -18,7 +18,7 @@
#include "lld/Core/File.h" #include "lld/Core/File.h"
#include "lld/Core/LLVM.h" #include "lld/Core/LLVM.h"
#include "lld/Driver/LinkerInput.h" #include "lld/Core/LinkerInput.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <memory> #include <memory>
@ -232,7 +232,7 @@ public:
/// \brief Create a lld::File node from the FileNode /// \brief Create a lld::File node from the FileNode
virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> > virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
createLinkerInput(const LinkingContext &targetInfo) = 0; createLinkerInput(const LinkingContext &targetInfo);
protected: protected:
StringRef _path; StringRef _path;

View File

@ -37,9 +37,6 @@ public:
virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const; virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
createLinkerInput(const lld::LinkingContext &);
/// \brief validates the Input Element /// \brief validates the Input Element
virtual bool validate() { return true; } virtual bool validate() { return true; }
@ -62,9 +59,6 @@ public:
virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const; virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
createLinkerInput(const lld::LinkingContext &);
/// \brief validates the Input Element /// \brief validates the Input Element
virtual bool validate() { return true; } virtual bool validate() { return true; }

View File

@ -28,7 +28,7 @@ public:
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const; virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File> > &result) const; std::vector<std::unique_ptr<File> > &result) const;
void addPassNamed(StringRef name) { _passNames.push_back(name); } void addPassNamed(StringRef name) { _passNames.push_back(name); }

View File

@ -87,7 +87,7 @@ public:
} }
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File> > &result) const; std::vector<std::unique_ptr<File> > &result) const;
static std::unique_ptr<ELFLinkingContext> create(llvm::Triple); static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);

View File

@ -33,7 +33,7 @@ public:
virtual bool validateImpl(raw_ostream &diagnostics); virtual bool validateImpl(raw_ostream &diagnostics);
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File> > &result) const; std::vector<std::unique_ptr<File> > &result) const;
uint32_t getCPUType() const; uint32_t getCPUType() const;

View File

@ -49,7 +49,7 @@ public:
}; };
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File> > &result) const; std::vector<std::unique_ptr<File> > &result) const;
virtual Writer &writer() const; virtual Writer &writer() const;

View File

@ -32,15 +32,11 @@ class Reader {
public: public:
virtual ~Reader(); virtual ~Reader();
/// \brief Parse a file given its file system path and create a File object.
virtual error_code readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const;
/// \brief Parse a supplied buffer (already filled with the contents of a /// \brief Parse a supplied buffer (already filled with the contents of a
/// file) and create a File object. /// file) and create a File object.
/// ///
/// On success, the resulting File object takes ownership of the MemoryBuffer. /// On success, the resulting File object takes ownership of the MemoryBuffer.
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> &mb, virtual error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const = 0; std::vector<std::unique_ptr<File>> &result) const = 0;
protected: protected:

View File

@ -34,7 +34,7 @@ public:
/// \brief Returns a vector of Files that are contained in the archive file /// \brief Returns a vector of Files that are contained in the archive file
/// pointed to by the Memorybuffer /// pointed to by the Memorybuffer
error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb, error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const; std::vector<std::unique_ptr<File>> &result) const;
private: private:

View File

@ -26,7 +26,7 @@ public:
/// \brief Returns a vector of Files that are contained in the archive file /// \brief Returns a vector of Files that are contained in the archive file
/// pointed to by the Memorybuffer /// pointed to by the Memorybuffer
error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb, error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const; std::vector<std::unique_ptr<File>> &result) const;
}; };

View File

@ -33,17 +33,6 @@ bool LinkingContext::validate(raw_ostream &diagnostics) {
return validateImpl(diagnostics); return validateImpl(diagnostics);
} }
error_code
LinkingContext::readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const {
OwningPtr<llvm::MemoryBuffer> opmb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb))
return ec;
std::unique_ptr<MemoryBuffer> mb(opmb.take());
return this->parseFile(mb, result);
}
error_code LinkingContext::writeFile(const File &linkedFile) const { error_code LinkingContext::writeFile(const File &linkedFile) const {
return this->writer().writeFile(linkedFile, _outputPath); return this->writer().writeFile(linkedFile, _outputPath);
} }

View File

@ -66,11 +66,6 @@ public:
namespace lld { namespace lld {
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
COREFileNode::createLinkerInput(const LinkingContext &info) {
return std::unique_ptr<LinkerInput>(new LinkerInput(*path(info)));
}
bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) { bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
CoreLinkingContext info; CoreLinkingContext info;
if (parse(argc, argv, info)) if (parse(argc, argv, info))

View File

@ -70,11 +70,6 @@ public:
namespace lld { namespace lld {
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
MachOFileNode::createLinkerInput(const LinkingContext &ctx) {
return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
}
bool DarwinLdDriver::linkMachO(int argc, const char *argv[], bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
raw_ostream &diagnostics) { raw_ostream &diagnostics) {
MachOLinkingContext ctx; MachOLinkingContext ctx;

View File

@ -68,11 +68,11 @@ bool Driver::link(const LinkingContext &context, raw_ostream &diagnostics) {
} }
for (const auto &input : linkerInputs) { for (const auto &input : linkerInputs) {
if (context.logInputFiles()) if (context.logInputFiles())
llvm::outs() << input->getPath() << "\n"; llvm::outs() << input->getUserPath() << "\n";
tg.spawn([ &, index]{ tg.spawn([ &, index]{
if (error_code ec = context.readFile(input->getPath(), files[index])) { if (error_code ec = context.parseFile(*input, files[index])) {
diagnostics << "Failed to read file: " << input->getPath() << ": " diagnostics << "Failed to read file: " << input->getUserPath() << ": "
<< ec.message() << "\n"; << ec.message() << "\n";
fail = true; fail = true;
return; return;

View File

@ -71,13 +71,12 @@ public:
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> > llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
ELFFileNode::createLinkerInput(const LinkingContext &ctx) { ELFFileNode::createLinkerInput(const LinkingContext &ctx) {
auto filePath = path(ctx); auto inputFile(FileNode::createLinkerInput(ctx));
if (!filePath &&
error_code(filePath) == llvm::errc::no_such_file_or_directory) if (inputFile) {
return make_error_code(llvm::errc::no_such_file_or_directory); (*inputFile)->setAsNeeded(_asNeeded);
std::unique_ptr<LinkerInput> inputFile(new LinkerInput(*filePath)); (*inputFile)->setForceLoad(_isWholeArchive);
inputFile->setAsNeeded(_asNeeded); }
inputFile->setForceLoad(_isWholeArchive);
return std::move(inputFile); return std::move(inputFile);
} }

View File

@ -54,3 +54,18 @@ bool InputGraph::dump(raw_ostream &diagnostics) {
return false; return false;
return true; return true;
} }
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
FileNode::createLinkerInput(const LinkingContext &ctx) {
auto filePath = path(ctx);
if (!filePath &&
error_code(filePath) == llvm::errc::no_such_file_or_directory)
return make_error_code(llvm::errc::no_such_file_or_directory);
OwningPtr<llvm::MemoryBuffer> opmb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb))
return ec;
std::unique_ptr<MemoryBuffer> mb(opmb.take());
return std::unique_ptr<LinkerInput>(new LinkerInput(std::move(mb), *filePath));
}

View File

@ -212,16 +212,6 @@ parseArgs(int argc, const char *argv[], raw_ostream &diagnostics,
} // namespace } // namespace
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
PECOFFFileNode::createLinkerInput(const LinkingContext &ctx) {
return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
}
llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
PECOFFLibraryNode::createLinkerInput(const LinkingContext &ctx) {
return std::unique_ptr<LinkerInput>(new LinkerInput(*path(ctx)));
}
llvm::ErrorOr<StringRef> PECOFFFileNode::path(const LinkingContext &) const { llvm::ErrorOr<StringRef> PECOFFFileNode::path(const LinkingContext &) const {
if (_path.endswith(".lib")) if (_path.endswith(".lib"))
return _ctx.searchLibraryFile(_path); return _ctx.searchLibraryFile(_path);

View File

@ -288,12 +288,11 @@ void CoreLinkingContext::addPasses(PassManager &pm) const {
} }
} }
error_code CoreLinkingContext::parseFile( error_code CoreLinkingContext::parseFile(LinkerInput &input,
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
if (!_reader) if (!_reader)
_reader = createReaderYAML(*this); _reader = createReaderYAML(*this);
return _reader->parseFile(mb, result); return _reader->parseFile(input, result);
} }
Writer &CoreLinkingContext::writer() const { Writer &CoreLinkingContext::writer() const {

View File

@ -98,24 +98,23 @@ bool ELFLinkingContext::isRelativeReloc(const Reference &) const {
return false; return false;
} }
error_code ELFLinkingContext::parseFile( error_code ELFLinkingContext::parseFile(LinkerInput &input,
std::unique_ptr<MemoryBuffer> &mb,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
ScopedTask task(getDefaultDomain(), "parseFile"); ScopedTask task(getDefaultDomain(), "parseFile");
error_code ec = _elfReader->parseFile(mb, result); error_code ec = _elfReader->parseFile(input, result);
if (!ec) if (!ec)
return ec; return ec;
// Not an ELF file, check file extension to see if it might be yaml // Not an ELF file, check file extension to see if it might be yaml
StringRef path = mb->getBufferIdentifier(); StringRef path = input.getBuffer().getBufferIdentifier();
if (path.endswith(".objtxt")) { if (path.endswith(".objtxt")) {
ec = _yamlReader->parseFile(mb, result); ec = _yamlReader->parseFile(input, result);
if (!ec) if (!ec)
return ec; return ec;
} }
// Not a yaml file, assume it is a linkerscript // Not a yaml file, assume it is a linkerscript
return _linkerScriptReader->parseFile(mb, result); return _linkerScriptReader->parseFile(input, result);
} }
Writer &ELFLinkingContext::writer() const { return *_writer; } Writer &ELFLinkingContext::writer() const { return *_writer; }

View File

@ -81,21 +81,22 @@ public:
ELFReader(const ELFLinkingContext &ctx) ELFReader(const ELFLinkingContext &ctx)
: lld::Reader(ctx), _elfLinkingContext(ctx), _readerArchive(ctx, *this) {} : lld::Reader(ctx), _elfLinkingContext(ctx), _readerArchive(ctx, *this) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb, error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
using llvm::object::ELFType; using llvm::object::ELFType;
llvm::MemoryBuffer &mb(input.getBuffer());
llvm::sys::fs::file_magic FileType = llvm::sys::fs::file_magic FileType =
llvm::sys::fs::identify_magic(mb->getBuffer()); llvm::sys::fs::identify_magic(mb.getBuffer());
std::size_t MaxAlignment = std::size_t MaxAlignment =
1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart())); 1ULL << llvm::countTrailingZeros(uintptr_t(mb.getBufferStart()));
llvm::error_code ec; llvm::error_code ec;
switch (FileType) { switch (FileType) {
case llvm::sys::fs::file_magic::elf_relocatable: { case llvm::sys::fs::file_magic::elf_relocatable: {
std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>( std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, std::move(mb), getElfArchType(&mb), MaxAlignment, _elfLinkingContext,
ec)); std::move(input.takeBuffer()), ec));
if (ec) if (ec)
return ec; return ec;
result.push_back(std::move(f)); result.push_back(std::move(f));
@ -107,15 +108,15 @@ public:
if (!_elfLinkingContext.allowLinkWithDynamicLibraries()) if (!_elfLinkingContext.allowLinkWithDynamicLibraries())
return llvm::make_error_code(llvm::errc::executable_format_error); return llvm::make_error_code(llvm::errc::executable_format_error);
auto f = createELF<DynamicFileCreateELFTraits>( auto f = createELF<DynamicFileCreateELFTraits>(
getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, getElfArchType(&mb), MaxAlignment, _elfLinkingContext,
std::move(mb)); std::move(input.takeBuffer()));
if (!f) if (!f)
return f; return f;
result.push_back(std::move(*f)); result.push_back(std::move(*f));
break; break;
} }
case llvm::sys::fs::file_magic::archive: case llvm::sys::fs::file_magic::archive:
ec = _readerArchive.parseFile(mb, result); ec = _readerArchive.parseFile(input, result);
break; break;
default: default:
return llvm::make_error_code(llvm::errc::executable_format_error); return llvm::make_error_code(llvm::errc::executable_format_error);

View File

@ -234,13 +234,13 @@ void MachOLinkingContext::addPasses(PassManager &pm) const {
} }
error_code MachOLinkingContext::parseFile( error_code MachOLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb, LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
// if (!_machoReader) // if (!_machoReader)
// _machoReader = createReaderMachO(*this); // _machoReader = createReaderMachO(*this);
// error_code ec = _machoReader->parseFile(mb,result); // error_code ec = _machoReader->parseFile(input,result);
// if (ec) { // if (ec) {
return _yamlReader->parseFile(mb, result); return _yamlReader->parseFile(input, result);
// } // }
return error_code::success(); return error_code::success();

View File

@ -239,11 +239,11 @@ public:
/// Instantiates a File object from a native object file. Ownership /// Instantiates a File object from a native object file. Ownership
/// of the MemoryBuffer is transfered to the resulting File object. /// of the MemoryBuffer is transfered to the resulting File object.
static error_code make(const LinkingContext &context, static error_code make(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> &mb, LinkerInput &input,
StringRef path,
std::vector<std::unique_ptr<lld::File>> &result) { std::vector<std::unique_ptr<lld::File>> &result) {
const uint8_t *const base = const uint8_t *const base =
reinterpret_cast<const uint8_t *>(mb->getBufferStart()); reinterpret_cast<const uint8_t *>(input.getBuffer().getBufferStart());
StringRef path(input.getBuffer().getBufferIdentifier());
const NativeFileHeader* const header = const NativeFileHeader* const header =
reinterpret_cast<const NativeFileHeader*>(base); reinterpret_cast<const NativeFileHeader*>(base);
const NativeChunk *const chunks = const NativeChunk *const chunks =
@ -253,7 +253,7 @@ public:
return make_error_code(native_reader_error::unknown_file_format); return make_error_code(native_reader_error::unknown_file_format);
// make sure mapped file contains all needed data // make sure mapped file contains all needed data
const size_t fileSize = mb->getBufferSize(); const size_t fileSize = input.getBuffer().getBufferSize();
if ( header->fileSize > fileSize ) if ( header->fileSize > fileSize )
return make_error_code(native_reader_error::file_too_short); return make_error_code(native_reader_error::file_too_short);
@ -263,7 +263,8 @@ public:
<< header->chunkCount << "\n"); << header->chunkCount << "\n");
// instantiate NativeFile object and add values to it as found // instantiate NativeFile object and add values to it as found
std::unique_ptr<File> file(new File(context, std::move(mb), path)); std::unique_ptr<File> file(new File(context, std::move(input.takeBuffer()),
path));
// process each chunk // process each chunk
for (uint32_t i = 0; i < header->chunkCount; ++i) { for (uint32_t i = 0; i < header->chunkCount; ++i) {
@ -912,9 +913,9 @@ public:
Reader(const LinkingContext &context) : lld::Reader(context) {} Reader(const LinkingContext &context) : lld::Reader(context) {}
virtual error_code virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, parseFile(LinkerInput &input,
std::vector<std::unique_ptr<lld::File>> &result) const { std::vector<std::unique_ptr<lld::File>> &result) const {
return File::make(_context, mb, mb->getBufferIdentifier(), result); return File::make(_context, input, result);
} }
}; };
} // end namespace native } // end namespace native

View File

@ -28,9 +28,9 @@ namespace lld {
namespace {} // anonymous namespace namespace {} // anonymous namespace
error_code PECOFFLinkingContext::parseFile( error_code PECOFFLinkingContext::parseFile(
std::unique_ptr<MemoryBuffer> &mb, LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
return _reader->parseFile(mb, result); return _reader->parseFile(input, result);
} }
bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) { bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {

View File

@ -676,14 +676,15 @@ public:
: Reader(context), _readerArchive(context, *this), : Reader(context), _readerArchive(context, *this),
_PECOFFLinkingContext(context) {} _PECOFFLinkingContext(context) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb, error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
StringRef magic(mb->getBufferStart(), mb->getBufferSize()); StringRef magic(input.getBuffer().getBufferStart(), input.getBuffer().getBufferSize());
llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(magic); llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(magic);
if (fileType == llvm::sys::fs::file_magic::archive)
return _readerArchive.parseFile(input, result);
std::unique_ptr<MemoryBuffer> mb(input.takeBuffer());
if (fileType == llvm::sys::fs::file_magic::coff_object) if (fileType == llvm::sys::fs::file_magic::coff_object)
return parseCOFFFile(mb, result); return parseCOFFFile(mb, result);
if (fileType == llvm::sys::fs::file_magic::archive)
return _readerArchive.parseFile(mb, result);
return lld::coff::parseCOFFImportLibrary(_context, mb, result); return lld::coff::parseCOFFImportLibrary(_context, mb, result);
} }

View File

@ -17,14 +17,4 @@
namespace lld { namespace lld {
Reader::~Reader() { Reader::~Reader() {
} }
error_code Reader::readFile(StringRef path,
std::vector<std::unique_ptr<File>> &result) const {
OwningPtr<llvm::MemoryBuffer> opmb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb))
return ec;
std::unique_ptr<MemoryBuffer> mb(opmb.take());
return this->parseFile(mb, result);
}
} // end namespace lld } // end namespace lld

View File

@ -47,8 +47,8 @@ public:
return nullptr; return nullptr;
if (_context.logInputFiles()) if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n"; llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mb(buff.take()); LinkerInput newInput(std::unique_ptr<MemoryBuffer>(buff.take()), _input);
if (_context.parseFile(mb, result)) if (_context.parseFile(newInput, result))
return nullptr; return nullptr;
assert(result.size() == 1); assert(result.size() == 1);
@ -122,6 +122,7 @@ protected:
} }
private: private:
LinkerInput _input;
std::unique_ptr<llvm::object::Archive> _archive; std::unique_ptr<llvm::object::Archive> _archive;
atom_collection_vector<DefinedAtom> _definedAtoms; atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms; atom_collection_vector<UndefinedAtom> _undefinedAtoms;
@ -132,10 +133,11 @@ private:
public: public:
/// only subclasses of ArchiveLibraryFile can be instantiated /// only subclasses of ArchiveLibraryFile can be instantiated
FileArchive(const LinkingContext &context, FileArchive(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb, error_code &ec) LinkerInput &input, error_code &ec)
: ArchiveLibraryFile(context, mb->getBufferIdentifier()) { : ArchiveLibraryFile(context, input.getBuffer().getBufferIdentifier()),
_input(std::move(input)) {
std::unique_ptr<llvm::object::Archive> archive_obj( std::unique_ptr<llvm::object::Archive> archive_obj(
new llvm::object::Archive(mb.release(), ec)); new llvm::object::Archive(_input.takeBuffer().release(), ec));
if (ec) if (ec)
return; return;
_archive.swap(archive_obj); _archive.swap(archive_obj);
@ -159,12 +161,12 @@ public:
// Returns a vector of Files that are contained in the archive file // Returns a vector of Files that are contained in the archive file
// pointed to by the MemoryBuffer // pointed to by the MemoryBuffer
error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb, error_code ReaderArchive::parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
error_code ec; error_code ec;
if (_context.forceLoadAllArchives()) { if (_context.forceLoadAllArchives()) {
_archive.reset(new llvm::object::Archive(mb.release(), ec)); _archive.reset(new llvm::object::Archive(input.takeBuffer().release(), ec));
if (ec) if (ec)
return ec; return ec;
@ -176,12 +178,13 @@ error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
std::unique_ptr<MemoryBuffer> mbc(buff.take()); std::unique_ptr<MemoryBuffer> mbc(buff.take());
if (_context.logInputFiles()) if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n"; llvm::outs() << buff->getBufferIdentifier() << "\n";
if ((ec = _context.parseFile(mbc, result))) LinkerInput newInput(std::move(mbc), input);
if ((ec = _context.parseFile(newInput, result)))
return ec; return ec;
} }
} else { } else {
std::unique_ptr<File> f; std::unique_ptr<File> f;
f.reset(new FileArchive(_context, std::move(mb), ec)); f.reset(new FileArchive(_context, input, ec));
if (ec) if (ec)
return ec; return ec;

View File

@ -19,7 +19,7 @@ using namespace script;
namespace { namespace {
class LinkerScriptFile : public File { class LinkerScriptFile : public File {
public: public:
static ErrorOr<std::unique_ptr<LinkerScriptFile>> static ErrorOr<std::unique_ptr<LinkerScriptFile> >
create(const LinkingContext &context, create(const LinkingContext &context,
std::unique_ptr<llvm::MemoryBuffer> mb) { std::unique_ptr<llvm::MemoryBuffer> mb) {
std::unique_ptr<LinkerScriptFile> file( std::unique_ptr<LinkerScriptFile> file(
@ -56,9 +56,7 @@ public:
return _absoluteAtoms; return _absoluteAtoms;
} }
const LinkerScript *getScript() { const LinkerScript *getScript() { return _script; }
return _script;
}
private: private:
LinkerScriptFile(const LinkingContext &context, LinkerScriptFile(const LinkingContext &context,
@ -79,9 +77,8 @@ private:
namespace lld { namespace lld {
error_code ReaderLinkerScript::parseFile( error_code ReaderLinkerScript::parseFile(
std::unique_ptr<llvm::MemoryBuffer> &mb, LinkerInput &input, std::vector<std::unique_ptr<File> > &result) const {
std::vector<std::unique_ptr<File>> &result) const { auto lsf = LinkerScriptFile::create(_context, input.takeBuffer());
auto lsf = LinkerScriptFile::create(_context, std::move(mb));
if (!lsf) if (!lsf)
return lsf; return lsf;
const LinkerScript *ls = (*lsf)->getScript(); const LinkerScript *ls = (*lsf)->getScript();
@ -89,7 +86,15 @@ error_code ReaderLinkerScript::parseFile(
for (const auto &c : ls->_commands) { for (const auto &c : ls->_commands) {
if (auto group = dyn_cast<lld::script::Group>(c)) if (auto group = dyn_cast<lld::script::Group>(c))
for (const auto &path : group->getPaths()) { for (const auto &path : group->getPaths()) {
if (error_code ec = _context.readFile(path._path, result)) OwningPtr<llvm::MemoryBuffer> opmb;
if (error_code ec =
llvm::MemoryBuffer::getFileOrSTDIN(path._path, opmb))
return ec;
LinkerInput newInput(std::unique_ptr<llvm::MemoryBuffer>(opmb.take()),
input);
if (error_code ec = _context.parseFile(newInput, result))
return ec; return ec;
} }
} }

View File

@ -1350,7 +1350,7 @@ class ReaderYAML : public Reader {
public: public:
ReaderYAML(const LinkingContext &context) : Reader(context) {} ReaderYAML(const LinkingContext &context) : Reader(context) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> &mb, error_code parseFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result) const { std::vector<std::unique_ptr<File>> &result) const {
// Note: we do not take ownership of the MemoryBuffer. That is // Note: we do not take ownership of the MemoryBuffer. That is
// because yaml may produce multiple File objects, so there is no // because yaml may produce multiple File objects, so there is no
@ -1361,7 +1361,7 @@ public:
// Create YAML Input parser. // Create YAML Input parser.
ContextInfo context(_context); ContextInfo context(_context);
llvm::yaml::Input yin(mb->getBuffer(), &context); llvm::yaml::Input yin(input.getBuffer().getBuffer(), &context);
// Fill vector with File objects created by parsing yaml. // Fill vector with File objects created by parsing yaml.
std::vector<const lld::File*> createdFiles; std::vector<const lld::File*> createdFiles;

View File

@ -11,8 +11,8 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "lld/Core/LinkerInput.h"
#include "lld/Driver/Driver.h" #include "lld/Driver/Driver.h"
#include "lld/Driver/LinkerInput.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"