diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2016-07-17 16:03:47 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2016-07-17 16:03:47 +0200 |
commit | 0f57cc9750282ce0284fe69b06f161dea2bfc8cb (patch) | |
tree | 50afd51fec2d05752cc49441ae47c40aa831cf84 /Ld.cpp | |
parent | c5e53ec8da9b11e351893742096f76e2bceb5730 (diff) | |
download | elfinfo-0f57cc9750282ce0284fe69b06f161dea2bfc8cb.tar.gz elfinfo-0f57cc9750282ce0284fe69b06f161dea2bfc8cb.tar.bz2 elfinfo-0f57cc9750282ce0284fe69b06f161dea2bfc8cb.tar.xz elfinfo-0f57cc9750282ce0284fe69b06f161dea2bfc8cb.zip |
parser/lexer:
o Support special '/DISCARD/' as NAME.
o Add 'SORT' as a token. It is equivalent with SORT_BY_NAME. The new rule sort_by_name coverts both.
Ld:
o Don't die on unknown sections, they can be referenced before declared. Doesn't matter for this app anyway.
Diffstat (limited to 'Ld.cpp')
-rw-r--r-- | Ld.cpp | 49 |
1 files changed, 44 insertions, 5 deletions
@@ -39,14 +39,18 @@ public: } virtual V get(ParseTree *const node) { + return _annotations.at(node); + } + +// virtual V get(ParseTree *const node) { // try { // cout << "node = " << node->getText() << endl; - return _annotations.at(node); +// return _annotations.at(node); // } catch (std::out_of_range &e) { // cout << "out of range: " << node->getText() << endl; // throw e; // } - } +// } virtual void put(ParseTree *const node, V value) { // cout << "put(" << node << ", " << value << ")" << endl; @@ -88,7 +92,8 @@ public: return s; } } - throw out_of_range("No such section: " + name); + sections.emplace_back(Section{.name = name}); + return sections[sections.size() - 1]; } static uint64_t parseInt(const string &s) { @@ -218,8 +223,34 @@ public: LdScriptLoader::LdScriptLoader() : debug_(false) { } +class LdErrorListener : public BaseErrorListener { +public: + std::vector<std::string> messages; + + void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine, + const std::string &msg, std::exception_ptr e) override { + messages.push_back(msg); + } +}; + LdScript LdScriptLoader::load(std::string path) { - ANTLRFileStream input(path); + std::ifstream stream(path, std::ios::binary); + + if (!stream.good() || stream.eof()) { + return {}; + } + + string data; + while (!stream.eof()) { + char buf[1000]; + stream.read(buf, sizeof(buf)); + auto count = stream.gcount(); + for (int i = 0; i < count; i++) { + data.push_back((char) (buf[i] & 0x7f)); + } + } + + ANTLRInputStream input(data); GnuLdLexer lexer(&input); CommonTokenStream tokens(&lexer); tokens.fill(); @@ -233,9 +264,17 @@ LdScript LdScriptLoader::load(std::string path) { GnuLdParser parser(&tokens); ElfinfoGnuLdBaseListener listener; parser.addParseListener(&listener); + + LdErrorListener ldErrorListener; + parser.addErrorListener(&ldErrorListener); + auto file = parser.file(); - if (debug_) { + if (!ldErrorListener.messages.empty()) { + throw LdParseException(ldErrorListener.messages); + } + + if (debug_ && parser.getNumberOfSyntaxErrors() == 0) { std::cout << file->toStringTree(&parser) << std::endl << std::endl; } |