Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 1 | //===- lib/ReaderWriter/ReaderLinkerScript.cpp ----------------------------===// |
| 2 | // |
| 3 | // The LLVM Linker |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "lld/ReaderWriter/ReaderLinkerScript.h" |
| 11 | |
| 12 | #include "lld/Core/Error.h" |
| 13 | #include "lld/Core/File.h" |
Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 14 | #include "lld/ReaderWriter/LinkerScript.h" |
| 15 | |
| 16 | using namespace lld; |
| 17 | using namespace script; |
| 18 | |
| 19 | namespace { |
| 20 | class LinkerScriptFile : public File { |
| 21 | public: |
| 22 | static ErrorOr<std::unique_ptr<LinkerScriptFile> > |
| 23 | create(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb) { |
| 24 | std::unique_ptr<LinkerScriptFile> file( |
| 25 | new LinkerScriptFile(ti, std::move(mb))); |
| 26 | file->_script = file->_parser.parse(); |
| 27 | if (!file->_script) |
| 28 | return linker_script_reader_error::parse_error; |
| 29 | return std::move(file); |
| 30 | } |
| 31 | |
Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 32 | static inline bool classof(const File *f) { |
| 33 | return f->kind() == kindLinkerScript; |
| 34 | } |
| 35 | |
| 36 | virtual void setOrdinalAndIncrement(uint64_t &ordinal) const { |
| 37 | _ordinal = ordinal++; |
| 38 | } |
| 39 | |
| 40 | virtual const TargetInfo &getTargetInfo() const { return _targetInfo; } |
| 41 | |
| 42 | virtual const atom_collection<DefinedAtom> &defined() const { |
| 43 | return _definedAtoms; |
| 44 | } |
| 45 | |
| 46 | virtual const atom_collection<UndefinedAtom> &undefined() const { |
| 47 | return _undefinedAtoms; |
| 48 | } |
| 49 | |
| 50 | virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const { |
| 51 | return _sharedLibraryAtoms; |
| 52 | } |
| 53 | |
| 54 | virtual const atom_collection<AbsoluteAtom> &absolute() const { |
| 55 | return _absoluteAtoms; |
| 56 | } |
| 57 | |
| 58 | const LinkerScript *getScript() { |
| 59 | return _script; |
| 60 | } |
| 61 | |
| 62 | private: |
| 63 | LinkerScriptFile(const TargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb) |
Michael J. Spencer | 0f3dd61 | 2013-03-20 18:57:27 +0000 | [diff] [blame] | 64 | : File(mb->getBufferIdentifier(), kindLinkerScript), |
Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 65 | _targetInfo(ti), |
| 66 | _lexer(std::move(mb)), |
| 67 | _parser(_lexer), |
| 68 | _script(nullptr) {} |
| 69 | |
| 70 | const TargetInfo &_targetInfo; |
| 71 | atom_collection_vector<DefinedAtom> _definedAtoms; |
| 72 | atom_collection_vector<UndefinedAtom> _undefinedAtoms; |
| 73 | atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms; |
| 74 | atom_collection_vector<AbsoluteAtom> _absoluteAtoms; |
| 75 | Lexer _lexer; |
| 76 | Parser _parser; |
| 77 | const LinkerScript *_script; |
| 78 | }; |
| 79 | } // end anon namespace |
| 80 | |
| 81 | namespace lld { |
Michael J. Spencer | ce1e53e | 2013-04-05 21:08:30 +0000 | [diff] [blame] | 82 | error_code ReaderLinkerScript::parseFile( |
| 83 | std::unique_ptr<llvm::MemoryBuffer> mb, |
| 84 | std::vector<std::unique_ptr<File>> &result) const { |
Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 85 | auto lsf = LinkerScriptFile::create(_targetInfo, std::move(mb)); |
| 86 | if (!lsf) |
| 87 | return lsf; |
| 88 | const LinkerScript *ls = (*lsf)->getScript(); |
| 89 | result.push_back(std::move(*lsf)); |
| 90 | for (const auto &c : ls->_commands) { |
| 91 | if (auto group = dyn_cast<Group>(c)) |
| 92 | for (const auto &path : group->getPaths()) { |
Nick Kledzik | c314b46 | 2013-04-04 18:59:24 +0000 | [diff] [blame] | 93 | if (error_code ec = _targetInfo.readFile(path._path, result)) |
Michael J. Spencer | a55e37f | 2013-03-01 00:03:36 +0000 | [diff] [blame] | 94 | return ec; |
| 95 | } |
| 96 | } |
| 97 | return error_code::success(); |
| 98 | } |
| 99 | } // end namespace lld |