//===- lib/ReaderWriter/ReaderLinkerScript.cpp ----------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "lld/ReaderWriter/ReaderLinkerScript.h" #include "lld/Core/Error.h" #include "lld/Core/File.h" #include "lld/ReaderWriter/LinkerScript.h" using namespace lld; using namespace script; namespace { class LinkerScriptFile : public File { public: static ErrorOr > create(const TargetInfo &ti, std::unique_ptr mb) { std::unique_ptr file( new LinkerScriptFile(ti, std::move(mb))); file->_script = file->_parser.parse(); if (!file->_script) return linker_script_reader_error::parse_error; return std::move(file); } static inline bool classof(const File *f) { return f->kind() == kindLinkerScript; } virtual void setOrdinalAndIncrement(uint64_t &ordinal) const { _ordinal = ordinal++; } virtual const TargetInfo &getTargetInfo() const { return _targetInfo; } virtual const atom_collection &defined() const { return _definedAtoms; } virtual const atom_collection &undefined() const { return _undefinedAtoms; } virtual const atom_collection &sharedLibrary() const { return _sharedLibraryAtoms; } virtual const atom_collection &absolute() const { return _absoluteAtoms; } const LinkerScript *getScript() { return _script; } private: LinkerScriptFile(const TargetInfo &ti, std::unique_ptr mb) : File(mb->getBufferIdentifier(), kindLinkerScript), _targetInfo(ti), _lexer(std::move(mb)), _parser(_lexer), _script(nullptr) {} const TargetInfo &_targetInfo; atom_collection_vector _definedAtoms; atom_collection_vector _undefinedAtoms; atom_collection_vector _sharedLibraryAtoms; atom_collection_vector _absoluteAtoms; Lexer _lexer; Parser _parser; const LinkerScript *_script; }; } // end anon namespace namespace lld { error_code ReaderLinkerScript::parseFile(std::unique_ptr &mb, std::vector > &result) const { auto lsf = LinkerScriptFile::create(_targetInfo, std::move(mb)); if (!lsf) return lsf; const LinkerScript *ls = (*lsf)->getScript(); result.push_back(std::move(*lsf)); for (const auto &c : ls->_commands) { if (auto group = dyn_cast(c)) for (const auto &path : group->getPaths()) { if (error_code ec = _targetInfo.readFile(path._path, result)) return ec; } } return error_code::success(); } } // end namespace lld