diff --git a/include/lld/ReaderWriter/LinkerScript.h b/include/lld/ReaderWriter/LinkerScript.h index be22bf3..90753ff 100644 --- a/include/lld/ReaderWriter/LinkerScript.h +++ b/include/lld/ReaderWriter/LinkerScript.h @@ -74,6 +74,7 @@ public: kw_group, kw_hidden, kw_keep, + kw_memory, kw_provide, kw_provide_hidden, kw_only_if_ro, @@ -149,6 +150,7 @@ public: Entry, Group, InputSectionsCmd, + Memory, OutputArch, OutputFormat, OutputSectionDescription, @@ -279,6 +281,30 @@ private: StringRef _entryName; }; +struct MemoryEntry { + MemoryEntry() {} +}; + +/// Represents all the contents of the MEMORY {} construct. +class Memory: public Command { +public: + //explicit Memory() {} + + static bool classof(const Command *c) { + return c->getKind() == Kind::Memory; + } + + void dump(raw_ostream &os) const override { + os << "MEMORY" << "\n"; + } + + StringRef getMemory() const { return _memory; } + +private: + //std::vector ; + StringRef _memory; +}; + class SearchDir : public Command { public: explicit SearchDir(StringRef searchPath) @@ -861,6 +887,10 @@ private: Group *parseGroup(); bool parseAsNeeded(std::vector &paths); + /// Parse the MEMORY linker script command. + /// Example: XXXFIXME. + Memory *parseMemory(); + /// Parse the ENTRY linker script command. /// Example: /// diff --git a/lib/ReaderWriter/LinkerScript.cpp b/lib/ReaderWriter/LinkerScript.cpp index 3984408..f9ed244 100644 --- a/lib/ReaderWriter/LinkerScript.cpp +++ b/lib/ReaderWriter/LinkerScript.cpp @@ -64,6 +64,7 @@ void Token::dump(raw_ostream &os) const { CASE(kw_exclude_file) CASE(kw_group) CASE(kw_hidden) + CASE(kw_memory) CASE(kw_keep) CASE(kw_provide) CASE(kw_provide_hidden) @@ -512,6 +513,7 @@ void Lexer::lex(Token &tok) { .Case("EXCLUDE_FILE", Token::kw_exclude_file) .Case("GROUP", Token::kw_group) .Case("HIDDEN", Token::kw_hidden) + .Case("MEMORY", Token::kw_memory) .Case("KEEP", Token::kw_keep) .Case("ONLY_IF_RO", Token::kw_only_if_ro) .Case("ONLY_IF_RW", Token::kw_only_if_rw) @@ -1347,6 +1349,81 @@ Entry *Parser::parseEntry() { return new (_alloc) Entry(entryName); } +#ifdef notyet +static MemoryEntry parseMemoryEntry() { + // Parse name + + // Parse attributes. + // XXX: Are attributes always present? + consumeToken(); + if (!expectAndConsume(Token::l_parent, "expected (")) + return nullptr; + consumeToken(); + if (!expectAndConsume(Token::r_parent, "expected )")) + return nullptr; + + consumeToken(); + if (!expectAndConsume(Token::semicolon, "expected :")) + return nullptr; + + // Parse origin + consumeToken(); + if (!expectAndConsume(Token::origin, "expected ORIGIN/org/o")) + return nullptr; + consumeToken(); + if (!expectAndConsume(Token::equal, "expected =")) + return nullptr; + if (_tok.kind != Token::identifier) { + error(_tok, "expected identifier"); + return nullptr; + } + + consumeToken(); + if (!expectAndConsume(Token::comma, "expected ,")) + return nullptr; + + // Parse length + consumeToken(); + if (!expectAndConsume(Token::length, "expect LENGTH/len/l")) + return nullptr; + consumeToken(); + if (!expectAndConsume(Token::equal, "expect =")) + return nullptr; + if (_tok.kind != Token::identifier) { + error(_tok, "expected identifier"); + return nullptr; + } + // XXX: what should origin/length look like? StringRef maybe? + // Add return. +} +#endif + +// Parse MEMORY +Memory *Parser::parseMemory() { + assert(_tok._kind == Token::kw_memory && "Expected MEMORY!"); + consumeToken(); + if (!expectAndConsume(Token::l_brace, "expected {")) + return nullptr; + std::vector memoryEntries; + bool unrecognizedToken = false; + + // Parse one or more memory entires. + // XXX: There could be zero memory ? + while (!unrecognizedToken) { + switch (_tok._kind) { + case Token::identifier: + consumeToken(); + break; + default: + break; + } + } + + consumeToken(); + if (!expectAndConsume(Token::r_brace, "expected }")) + return nullptr; +} + // Parse SEARCH_DIR(ident) SearchDir *Parser::parseSearchDir() { assert(_tok._kind == Token::kw_search_dir && "Expected SEARCH_DIR!");