diff --git a/lld/include/lld/Driver/LinkerInput.h b/lld/include/lld/Core/LinkerInput.h similarity index 74% rename from lld/include/lld/Driver/LinkerInput.h rename to lld/include/lld/Core/LinkerInput.h index a14716d40d34..71836ccab0b0 100644 --- a/lld/include/lld/Driver/LinkerInput.h +++ b/lld/include/lld/Core/LinkerInput.h @@ -45,40 +45,37 @@ class LinkerInput { LinkerInput(const LinkerInput &) LLVM_DELETED_FUNCTION; public: - explicit LinkerInput(StringRef file) - : _file(file), _isForceLoad(false), _asNeeded(false) {} + explicit LinkerInput(std::unique_ptr buffer, + StringRef userPath) + : _buffer(std::move(buffer)), _userPath(userPath), _isForceLoad(false), + _asNeeded(false) {} - explicit LinkerInput(std::unique_ptr buffer) - : _buffer(std::move(buffer)), _file(_buffer->getBufferIdentifier()), - _isForceLoad(false), _asNeeded(false) {} + explicit LinkerInput(std::unique_ptr buffer, + const LinkerInput &other) + : _buffer(std::move(buffer)), _userPath(other.getUserPath()), + _isForceLoad(other.isForceLoad()), _asNeeded(other.asNeeded()) {} 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()) {} LinkerInput &operator=(LinkerInput &&rhs) { _buffer = std::move(rhs._buffer); - _file = std::move(rhs._file); + _userPath = std::move(rhs._userPath); + _isForceLoad = rhs.isForceLoad(); + _asNeeded = rhs.asNeeded(); return *this; } - ErrorOr getBuffer() const { - if (!_buffer) { - llvm::OwningPtr buf; - if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(_file, buf)) - return ec; - _buffer.reset(buf.take()); - } + StringRef getUserPath() const { return _userPath; } + llvm::MemoryBuffer &getBuffer() const { + assert(_buffer); return *_buffer; } - StringRef getPath() const { - return _file; - } - std::unique_ptr takeBuffer() { - getBuffer(); + assert(_buffer); return std::move(_buffer); } @@ -96,8 +93,8 @@ public: bool asNeeded() const { return _asNeeded; } private: - mutable std::unique_ptr _buffer; - std::string _file; + std::unique_ptr _buffer; + std::string _userPath; bool _isForceLoad; bool _asNeeded; }; diff --git a/lld/include/lld/Core/LinkingContext.h b/lld/include/lld/Core/LinkingContext.h index 0740fc55fc45..7c04eac8a536 100644 --- a/lld/include/lld/Core/LinkingContext.h +++ b/lld/include/lld/Core/LinkingContext.h @@ -12,11 +12,11 @@ #include "lld/Core/Error.h" #include "lld/Core/LLVM.h" +#include "lld/Core/LinkerInput.h" #include "lld/Core/range.h" #include "lld/Core/Reference.h" #include "lld/Driver/InputGraph.h" -#include "lld/Driver/LinkerInput.h" #include "lld/ReaderWriter/Reader.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 /// one lld::File (e.g. YAML). virtual error_code - parseFile(std::unique_ptr &inputBuff, + parseFile(LinkerInput &input, std::vector > &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 > &result) const; - /// 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 /// how file format specific atoms can be added to the link. diff --git a/lld/include/lld/Driver/CoreInputGraph.h b/lld/include/lld/Driver/CoreInputGraph.h index c42f5181cc14..8983e5f1a4c3 100644 --- a/lld/include/lld/Driver/CoreInputGraph.h +++ b/lld/include/lld/Driver/CoreInputGraph.h @@ -34,9 +34,6 @@ public: return a->kind() == InputElement::Kind::File; } - virtual llvm::ErrorOr > - createLinkerInput(const lld::LinkingContext &); - /// \brief validates the Input Element virtual bool validate() { (void)_ctx; diff --git a/lld/include/lld/Driver/DarwinInputGraph.h b/lld/include/lld/Driver/DarwinInputGraph.h index d443c9df3e9d..4f27a49a0f47 100644 --- a/lld/include/lld/Driver/DarwinInputGraph.h +++ b/lld/include/lld/Driver/DarwinInputGraph.h @@ -35,9 +35,6 @@ public: return a->kind() == InputElement::Kind::File; } - virtual llvm::ErrorOr > - createLinkerInput(const lld::LinkingContext &); - /// \brief validates the Input Element virtual bool validate() { (void)_ctx; diff --git a/lld/include/lld/Driver/InputGraph.h b/lld/include/lld/Driver/InputGraph.h index 56716f26823e..3ecd2322a1a4 100644 --- a/lld/include/lld/Driver/InputGraph.h +++ b/lld/include/lld/Driver/InputGraph.h @@ -18,7 +18,7 @@ #include "lld/Core/File.h" #include "lld/Core/LLVM.h" -#include "lld/Driver/LinkerInput.h" +#include "lld/Core/LinkerInput.h" #include "llvm/Support/raw_ostream.h" #include @@ -232,7 +232,7 @@ public: /// \brief Create a lld::File node from the FileNode virtual llvm::ErrorOr > - createLinkerInput(const LinkingContext &targetInfo) = 0; + createLinkerInput(const LinkingContext &targetInfo); protected: StringRef _path; diff --git a/lld/include/lld/Driver/WinLinkInputGraph.h b/lld/include/lld/Driver/WinLinkInputGraph.h index 7803b121960f..cb2216df51b9 100644 --- a/lld/include/lld/Driver/WinLinkInputGraph.h +++ b/lld/include/lld/Driver/WinLinkInputGraph.h @@ -37,9 +37,6 @@ public: virtual llvm::ErrorOr path(const LinkingContext &ctx) const; - virtual llvm::ErrorOr > - createLinkerInput(const lld::LinkingContext &); - /// \brief validates the Input Element virtual bool validate() { return true; } @@ -62,9 +59,6 @@ public: virtual llvm::ErrorOr path(const LinkingContext &ctx) const; - virtual llvm::ErrorOr > - createLinkerInput(const lld::LinkingContext &); - /// \brief validates the Input Element virtual bool validate() { return true; } diff --git a/lld/include/lld/ReaderWriter/CoreLinkingContext.h b/lld/include/lld/ReaderWriter/CoreLinkingContext.h index 2871ffb02568..5920ff9cda71 100644 --- a/lld/include/lld/ReaderWriter/CoreLinkingContext.h +++ b/lld/include/lld/ReaderWriter/CoreLinkingContext.h @@ -28,7 +28,7 @@ public: virtual ErrorOr stringFromRelocKind(Reference::Kind kind) const; virtual error_code - parseFile(std::unique_ptr &mb, + parseFile(LinkerInput &input, std::vector > &result) const; void addPassNamed(StringRef name) { _passNames.push_back(name); } diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index b9f057802d73..9f7bf3689ad3 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -87,7 +87,7 @@ public: } virtual error_code - parseFile(std::unique_ptr &mb, + parseFile(LinkerInput &input, std::vector > &result) const; static std::unique_ptr create(llvm::Triple); diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h index 1d3a6fb8dbdc..0cb3f15612cf 100644 --- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h +++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h @@ -33,7 +33,7 @@ public: virtual bool validateImpl(raw_ostream &diagnostics); virtual error_code - parseFile(std::unique_ptr &mb, + parseFile(LinkerInput &input, std::vector > &result) const; uint32_t getCPUType() const; diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h index 9acf547f1faa..c9f2cb8b4332 100644 --- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -49,7 +49,7 @@ public: }; virtual error_code - parseFile(std::unique_ptr &mb, + parseFile(LinkerInput &input, std::vector > &result) const; virtual Writer &writer() const; diff --git a/lld/include/lld/ReaderWriter/Reader.h b/lld/include/lld/ReaderWriter/Reader.h index 0fabdf529a4e..fe690e8fc689 100644 --- a/lld/include/lld/ReaderWriter/Reader.h +++ b/lld/include/lld/ReaderWriter/Reader.h @@ -32,15 +32,11 @@ class Reader { public: virtual ~Reader(); - /// \brief Parse a file given its file system path and create a File object. - virtual error_code readFile(StringRef path, - std::vector> &result) const; - /// \brief Parse a supplied buffer (already filled with the contents of a /// file) and create a File object. /// /// On success, the resulting File object takes ownership of the MemoryBuffer. - virtual error_code parseFile(std::unique_ptr &mb, + virtual error_code parseFile(LinkerInput &input, std::vector> &result) const = 0; protected: diff --git a/lld/include/lld/ReaderWriter/ReaderArchive.h b/lld/include/lld/ReaderWriter/ReaderArchive.h index 4c2504f18f49..c120ce5d6ea3 100644 --- a/lld/include/lld/ReaderWriter/ReaderArchive.h +++ b/lld/include/lld/ReaderWriter/ReaderArchive.h @@ -34,7 +34,7 @@ public: /// \brief Returns a vector of Files that are contained in the archive file /// pointed to by the Memorybuffer - error_code parseFile(std::unique_ptr &mb, + error_code parseFile(LinkerInput &input, std::vector> &result) const; private: diff --git a/lld/include/lld/ReaderWriter/ReaderLinkerScript.h b/lld/include/lld/ReaderWriter/ReaderLinkerScript.h index 7a9f608ee2fb..09594e9dc5cf 100644 --- a/lld/include/lld/ReaderWriter/ReaderLinkerScript.h +++ b/lld/include/lld/ReaderWriter/ReaderLinkerScript.h @@ -26,7 +26,7 @@ public: /// \brief Returns a vector of Files that are contained in the archive file /// pointed to by the Memorybuffer - error_code parseFile(std::unique_ptr &mb, + error_code parseFile(LinkerInput &input, std::vector> &result) const; }; diff --git a/lld/lib/Core/LinkingContext.cpp b/lld/lib/Core/LinkingContext.cpp index e341a886eac9..82b79bf23ee2 100644 --- a/lld/lib/Core/LinkingContext.cpp +++ b/lld/lib/Core/LinkingContext.cpp @@ -33,17 +33,6 @@ bool LinkingContext::validate(raw_ostream &diagnostics) { return validateImpl(diagnostics); } -error_code -LinkingContext::readFile(StringRef path, - std::vector> &result) const { - OwningPtr opmb; - if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb)) - return ec; - - std::unique_ptr mb(opmb.take()); - return this->parseFile(mb, result); -} - error_code LinkingContext::writeFile(const File &linkedFile) const { return this->writer().writeFile(linkedFile, _outputPath); } diff --git a/lld/lib/Driver/CoreDriver.cpp b/lld/lib/Driver/CoreDriver.cpp index 6d5e8a0a106e..7a949b709936 100644 --- a/lld/lib/Driver/CoreDriver.cpp +++ b/lld/lib/Driver/CoreDriver.cpp @@ -66,11 +66,6 @@ public: namespace lld { -llvm::ErrorOr > -COREFileNode::createLinkerInput(const LinkingContext &info) { - return std::unique_ptr(new LinkerInput(*path(info))); -} - bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) { CoreLinkingContext info; if (parse(argc, argv, info)) diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index 422adb979a49..db6977c59121 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -70,11 +70,6 @@ public: namespace lld { -llvm::ErrorOr > -MachOFileNode::createLinkerInput(const LinkingContext &ctx) { - return std::unique_ptr(new LinkerInput(*path(ctx))); -} - bool DarwinLdDriver::linkMachO(int argc, const char *argv[], raw_ostream &diagnostics) { MachOLinkingContext ctx; diff --git a/lld/lib/Driver/Driver.cpp b/lld/lib/Driver/Driver.cpp index 0936524d9c86..33917f3b7376 100644 --- a/lld/lib/Driver/Driver.cpp +++ b/lld/lib/Driver/Driver.cpp @@ -68,11 +68,11 @@ bool Driver::link(const LinkingContext &context, raw_ostream &diagnostics) { } for (const auto &input : linkerInputs) { if (context.logInputFiles()) - llvm::outs() << input->getPath() << "\n"; + llvm::outs() << input->getUserPath() << "\n"; tg.spawn([ &, index]{ - if (error_code ec = context.readFile(input->getPath(), files[index])) { - diagnostics << "Failed to read file: " << input->getPath() << ": " + if (error_code ec = context.parseFile(*input, files[index])) { + diagnostics << "Failed to read file: " << input->getUserPath() << ": " << ec.message() << "\n"; fail = true; return; diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 211f3affdaa8..8375b5970861 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -71,13 +71,12 @@ public: llvm::ErrorOr > ELFFileNode::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); - std::unique_ptr inputFile(new LinkerInput(*filePath)); - inputFile->setAsNeeded(_asNeeded); - inputFile->setForceLoad(_isWholeArchive); + auto inputFile(FileNode::createLinkerInput(ctx)); + + if (inputFile) { + (*inputFile)->setAsNeeded(_asNeeded); + (*inputFile)->setForceLoad(_isWholeArchive); + } return std::move(inputFile); } diff --git a/lld/lib/Driver/InputGraph.cpp b/lld/lib/Driver/InputGraph.cpp index 001cfed4e271..6157c90848db 100644 --- a/lld/lib/Driver/InputGraph.cpp +++ b/lld/lib/Driver/InputGraph.cpp @@ -54,3 +54,18 @@ bool InputGraph::dump(raw_ostream &diagnostics) { return false; return true; } + +llvm::ErrorOr > +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 opmb; + if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb)) + return ec; + + std::unique_ptr mb(opmb.take()); + + return std::unique_ptr(new LinkerInput(std::move(mb), *filePath)); +} diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index ff0cb3b00e49..ec01df43e851 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -212,16 +212,6 @@ parseArgs(int argc, const char *argv[], raw_ostream &diagnostics, } // namespace -llvm::ErrorOr > -PECOFFFileNode::createLinkerInput(const LinkingContext &ctx) { - return std::unique_ptr(new LinkerInput(*path(ctx))); -} - -llvm::ErrorOr > -PECOFFLibraryNode::createLinkerInput(const LinkingContext &ctx) { - return std::unique_ptr(new LinkerInput(*path(ctx))); -} - llvm::ErrorOr PECOFFFileNode::path(const LinkingContext &) const { if (_path.endswith(".lib")) return _ctx.searchLibraryFile(_path); diff --git a/lld/lib/ReaderWriter/CoreLinkingContext.cpp b/lld/lib/ReaderWriter/CoreLinkingContext.cpp index f82105e81f99..8f89f1d4a6a8 100644 --- a/lld/lib/ReaderWriter/CoreLinkingContext.cpp +++ b/lld/lib/ReaderWriter/CoreLinkingContext.cpp @@ -288,12 +288,11 @@ void CoreLinkingContext::addPasses(PassManager &pm) const { } } -error_code CoreLinkingContext::parseFile( - std::unique_ptr &mb, +error_code CoreLinkingContext::parseFile(LinkerInput &input, std::vector> &result) const { if (!_reader) _reader = createReaderYAML(*this); - return _reader->parseFile(mb, result); + return _reader->parseFile(input, result); } Writer &CoreLinkingContext::writer() const { diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index bd838c73f4e4..0ec4a8aa6fdb 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -98,24 +98,23 @@ bool ELFLinkingContext::isRelativeReloc(const Reference &) const { return false; } -error_code ELFLinkingContext::parseFile( - std::unique_ptr &mb, +error_code ELFLinkingContext::parseFile(LinkerInput &input, std::vector> &result) const { ScopedTask task(getDefaultDomain(), "parseFile"); - error_code ec = _elfReader->parseFile(mb, result); + error_code ec = _elfReader->parseFile(input, result); if (!ec) return ec; // 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")) { - ec = _yamlReader->parseFile(mb, result); + ec = _yamlReader->parseFile(input, result); if (!ec) return ec; } // 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; } diff --git a/lld/lib/ReaderWriter/ELF/Reader.cpp b/lld/lib/ReaderWriter/ELF/Reader.cpp index 0cbb86ebd4b3..ab1a8421f3ad 100644 --- a/lld/lib/ReaderWriter/ELF/Reader.cpp +++ b/lld/lib/ReaderWriter/ELF/Reader.cpp @@ -81,21 +81,22 @@ public: ELFReader(const ELFLinkingContext &ctx) : lld::Reader(ctx), _elfLinkingContext(ctx), _readerArchive(ctx, *this) {} - error_code parseFile(std::unique_ptr &mb, + error_code parseFile(LinkerInput &input, std::vector> &result) const { using llvm::object::ELFType; + llvm::MemoryBuffer &mb(input.getBuffer()); llvm::sys::fs::file_magic FileType = - llvm::sys::fs::identify_magic(mb->getBuffer()); + llvm::sys::fs::identify_magic(mb.getBuffer()); std::size_t MaxAlignment = - 1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart())); + 1ULL << llvm::countTrailingZeros(uintptr_t(mb.getBufferStart())); llvm::error_code ec; switch (FileType) { case llvm::sys::fs::file_magic::elf_relocatable: { std::unique_ptr f(createELF( - getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, std::move(mb), - ec)); + getElfArchType(&mb), MaxAlignment, _elfLinkingContext, + std::move(input.takeBuffer()), ec)); if (ec) return ec; result.push_back(std::move(f)); @@ -107,15 +108,15 @@ public: if (!_elfLinkingContext.allowLinkWithDynamicLibraries()) return llvm::make_error_code(llvm::errc::executable_format_error); auto f = createELF( - getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, - std::move(mb)); + getElfArchType(&mb), MaxAlignment, _elfLinkingContext, + std::move(input.takeBuffer())); if (!f) return f; result.push_back(std::move(*f)); break; } case llvm::sys::fs::file_magic::archive: - ec = _readerArchive.parseFile(mb, result); + ec = _readerArchive.parseFile(input, result); break; default: return llvm::make_error_code(llvm::errc::executable_format_error); diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index 7c80ffe8e2cc..456f8bd482e2 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -234,13 +234,13 @@ void MachOLinkingContext::addPasses(PassManager &pm) const { } error_code MachOLinkingContext::parseFile( - std::unique_ptr &mb, + LinkerInput &input, std::vector> &result) const { // if (!_machoReader) // _machoReader = createReaderMachO(*this); - // error_code ec = _machoReader->parseFile(mb,result); + // error_code ec = _machoReader->parseFile(input,result); // if (ec) { - return _yamlReader->parseFile(mb, result); + return _yamlReader->parseFile(input, result); // } return error_code::success(); diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp index ddb623481787..31024a06fab4 100644 --- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp +++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp @@ -239,11 +239,11 @@ public: /// Instantiates a File object from a native object file. Ownership /// of the MemoryBuffer is transfered to the resulting File object. static error_code make(const LinkingContext &context, - std::unique_ptr &mb, - StringRef path, + LinkerInput &input, std::vector> &result) { const uint8_t *const base = - reinterpret_cast(mb->getBufferStart()); + reinterpret_cast(input.getBuffer().getBufferStart()); + StringRef path(input.getBuffer().getBufferIdentifier()); const NativeFileHeader* const header = reinterpret_cast(base); const NativeChunk *const chunks = @@ -253,7 +253,7 @@ public: return make_error_code(native_reader_error::unknown_file_format); // 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 ) return make_error_code(native_reader_error::file_too_short); @@ -263,7 +263,8 @@ public: << header->chunkCount << "\n"); // instantiate NativeFile object and add values to it as found - std::unique_ptr file(new File(context, std::move(mb), path)); + std::unique_ptr file(new File(context, std::move(input.takeBuffer()), + path)); // process each chunk for (uint32_t i = 0; i < header->chunkCount; ++i) { @@ -912,9 +913,9 @@ public: Reader(const LinkingContext &context) : lld::Reader(context) {} virtual error_code - parseFile(std::unique_ptr &mb, + parseFile(LinkerInput &input, std::vector> &result) const { - return File::make(_context, mb, mb->getBufferIdentifier(), result); + return File::make(_context, input, result); } }; } // end namespace native diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp index f41c87b6943c..48ee6cb4ec74 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -28,9 +28,9 @@ namespace lld { namespace {} // anonymous namespace error_code PECOFFLinkingContext::parseFile( - std::unique_ptr &mb, + LinkerInput &input, std::vector> &result) const { - return _reader->parseFile(mb, result); + return _reader->parseFile(input, result); } bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) { diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index c8d546c6fc6c..8c18e4ee25a1 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -676,14 +676,15 @@ public: : Reader(context), _readerArchive(context, *this), _PECOFFLinkingContext(context) {} - error_code parseFile(std::unique_ptr &mb, + error_code parseFile(LinkerInput &input, std::vector> &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); + if (fileType == llvm::sys::fs::file_magic::archive) + return _readerArchive.parseFile(input, result); + std::unique_ptr mb(input.takeBuffer()); if (fileType == llvm::sys::fs::file_magic::coff_object) return parseCOFFFile(mb, result); - if (fileType == llvm::sys::fs::file_magic::archive) - return _readerArchive.parseFile(mb, result); return lld::coff::parseCOFFImportLibrary(_context, mb, result); } diff --git a/lld/lib/ReaderWriter/Reader.cpp b/lld/lib/ReaderWriter/Reader.cpp index 9f08ed274367..a3c939f40ab5 100644 --- a/lld/lib/ReaderWriter/Reader.cpp +++ b/lld/lib/ReaderWriter/Reader.cpp @@ -17,14 +17,4 @@ namespace lld { Reader::~Reader() { } - -error_code Reader::readFile(StringRef path, - std::vector> &result) const { - OwningPtr opmb; - if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb)) - return ec; - - std::unique_ptr mb(opmb.take()); - return this->parseFile(mb, result); -} } // end namespace lld diff --git a/lld/lib/ReaderWriter/ReaderArchive.cpp b/lld/lib/ReaderWriter/ReaderArchive.cpp index fead9c58441f..494e0d7c3bad 100644 --- a/lld/lib/ReaderWriter/ReaderArchive.cpp +++ b/lld/lib/ReaderWriter/ReaderArchive.cpp @@ -47,8 +47,8 @@ public: return nullptr; if (_context.logInputFiles()) llvm::outs() << buff->getBufferIdentifier() << "\n"; - std::unique_ptr mb(buff.take()); - if (_context.parseFile(mb, result)) + LinkerInput newInput(std::unique_ptr(buff.take()), _input); + if (_context.parseFile(newInput, result)) return nullptr; assert(result.size() == 1); @@ -122,6 +122,7 @@ protected: } private: + LinkerInput _input; std::unique_ptr _archive; atom_collection_vector _definedAtoms; atom_collection_vector _undefinedAtoms; @@ -132,10 +133,11 @@ private: public: /// only subclasses of ArchiveLibraryFile can be instantiated FileArchive(const LinkingContext &context, - std::unique_ptr mb, error_code &ec) - : ArchiveLibraryFile(context, mb->getBufferIdentifier()) { + LinkerInput &input, error_code &ec) + : ArchiveLibraryFile(context, input.getBuffer().getBufferIdentifier()), + _input(std::move(input)) { std::unique_ptr archive_obj( - new llvm::object::Archive(mb.release(), ec)); + new llvm::object::Archive(_input.takeBuffer().release(), ec)); if (ec) return; _archive.swap(archive_obj); @@ -159,12 +161,12 @@ public: // Returns a vector of Files that are contained in the archive file // pointed to by the MemoryBuffer -error_code ReaderArchive::parseFile(std::unique_ptr &mb, +error_code ReaderArchive::parseFile(LinkerInput &input, std::vector> &result) const { error_code ec; if (_context.forceLoadAllArchives()) { - _archive.reset(new llvm::object::Archive(mb.release(), ec)); + _archive.reset(new llvm::object::Archive(input.takeBuffer().release(), ec)); if (ec) return ec; @@ -176,12 +178,13 @@ error_code ReaderArchive::parseFile(std::unique_ptr &mb, std::unique_ptr mbc(buff.take()); if (_context.logInputFiles()) 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; } } else { std::unique_ptr f; - f.reset(new FileArchive(_context, std::move(mb), ec)); + f.reset(new FileArchive(_context, input, ec)); if (ec) return ec; diff --git a/lld/lib/ReaderWriter/ReaderLinkerScript.cpp b/lld/lib/ReaderWriter/ReaderLinkerScript.cpp index e7f1ad98fdf8..bcfb7c94b3b6 100644 --- a/lld/lib/ReaderWriter/ReaderLinkerScript.cpp +++ b/lld/lib/ReaderWriter/ReaderLinkerScript.cpp @@ -19,7 +19,7 @@ using namespace script; namespace { class LinkerScriptFile : public File { public: - static ErrorOr> + static ErrorOr > create(const LinkingContext &context, std::unique_ptr mb) { std::unique_ptr file( @@ -56,9 +56,7 @@ public: return _absoluteAtoms; } - const LinkerScript *getScript() { - return _script; - } + const LinkerScript *getScript() { return _script; } private: LinkerScriptFile(const LinkingContext &context, @@ -79,9 +77,8 @@ private: namespace lld { error_code ReaderLinkerScript::parseFile( - std::unique_ptr &mb, - std::vector> &result) const { - auto lsf = LinkerScriptFile::create(_context, std::move(mb)); + LinkerInput &input, std::vector > &result) const { + auto lsf = LinkerScriptFile::create(_context, input.takeBuffer()); if (!lsf) return lsf; const LinkerScript *ls = (*lsf)->getScript(); @@ -89,7 +86,15 @@ error_code ReaderLinkerScript::parseFile( for (const auto &c : ls->_commands) { if (auto group = dyn_cast(c)) for (const auto &path : group->getPaths()) { - if (error_code ec = _context.readFile(path._path, result)) + OwningPtr opmb; + if (error_code ec = + llvm::MemoryBuffer::getFileOrSTDIN(path._path, opmb)) + return ec; + + LinkerInput newInput(std::unique_ptr(opmb.take()), + input); + + if (error_code ec = _context.parseFile(newInput, result)) return ec; } } diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp index 028756557428..72c0a1dadcd9 100644 --- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -1350,7 +1350,7 @@ class ReaderYAML : public Reader { public: ReaderYAML(const LinkingContext &context) : Reader(context) {} - error_code parseFile(std::unique_ptr &mb, + error_code parseFile(LinkerInput &input, std::vector> &result) const { // Note: we do not take ownership of the MemoryBuffer. That is // because yaml may produce multiple File objects, so there is no @@ -1361,7 +1361,7 @@ public: // Create YAML Input parser. 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. std::vector createdFiles; diff --git a/lld/unittests/DriverTests/DriverTest.h b/lld/unittests/DriverTests/DriverTest.h index 527a1105b397..6472a4a6c430 100644 --- a/lld/unittests/DriverTests/DriverTest.h +++ b/lld/unittests/DriverTests/DriverTest.h @@ -11,8 +11,8 @@ #include "gtest/gtest.h" +#include "lld/Core/LinkerInput.h" #include "lld/Driver/Driver.h" -#include "lld/Driver/LinkerInput.h" #include "llvm/Support/raw_ostream.h"