diff options
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rw-r--r-- | Ld.cpp | 60 | ||||
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | elfinfo.cpp | 2 | ||||
-rw-r--r-- | include-priv/trygvis/antlr.h | 67 | ||||
-rw-r--r-- | include/trygvis/elfinfo/Ld.h (renamed from includes/trygvis/elfinfo/Ld.h) | 1 |
6 files changed, 91 insertions, 59 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ddbe243..9c6b7f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,14 @@ find_package(Antlr4) antlr4_add_target(TARGET GnuLd STATIC LEXER GnuLdLexer.g4 PARSER GnuLdParser.g4) -add_executable(elfinfo elfinfo.cpp Ld.cpp includes/trygvis/elfinfo/Ld.h) +add_executable(elfinfo elfinfo.cpp Ld.cpp include/trygvis/elfinfo/Ld.h include-priv/trygvis/antlr.h) target_compile_options(elfinfo PUBLIC "--std=c++14") target_link_libraries(elfinfo elf GnuLd Antlr4::antlr4_shared) -target_include_directories(elfinfo PUBLIC includes/trygvis/elfinfo) +target_include_directories(elfinfo + PUBLIC include + PRIVATE include-priv) INSTALL(TARGETS elfinfo - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib -) + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) @@ -1,4 +1,5 @@ -#include "Ld.h" +#include "trygvis/elfinfo/Ld.h" +#include "trygvis/antlr.h" #include "GnuLdLexer.h" #include "GnuLdParser.h" #include "GnuLdParserBaseListener.h" @@ -9,6 +10,7 @@ namespace elfinfo { using antlr4::ANTLRFileStream; using antlr4::tree::ParseTree; using namespace std; +using namespace trygvis::antlr; static MemoryAttribute valueOf(char c) { switch (c) { @@ -22,7 +24,7 @@ static MemoryAttribute valueOf(char c) { case 'X': return MemoryAttribute::X; default: - throw std::domain_error("Invalid memory attribute: " + c); + throw domain_error("Invalid memory attribute: " + c); } } @@ -30,48 +32,6 @@ static bool endsWith(const string &a, const string &b) { return b.length() <= a.length() && a.compare(a.length() - b.length(), b.length(), b) == 0; } -template<typename V, bool debug = false> -class ParseTreeProperty { -public: - virtual V get(Ref<ParseTree> node) { - return get(node.get()); - } - - virtual V get(ParseTree *const node) { - if (!debug) { - return _annotations.at(node); - } - - try { -// cout << "node = " << node->getText() << endl; - return _annotations.at(node); - } catch (std::out_of_range &e) { - cout << "get(" << node << "), text=" << node->getText() << endl; - stringstream buf; - buf << "out of range: " << node << ", text=" << node->getText(); - auto msg = buf.str(); - cout << msg << endl; - throw LdInternalErrorException(msg); - } - } - - virtual void put(ParseTree *const node, V value) { - if (debug) { - cout << "put(" << node << ", " << value << "), text: " << node->getText() << endl; - } - _annotations[node] = value; - } - - virtual V removeFrom(ParseTree *const node) { - return _annotations.erase(node); - } - -protected: - std::map<ParseTree *, V> _annotations; - -private: -}; - class ElfinfoGnuLdBaseListener : public GnuLdParserBaseListener { private: public: @@ -260,16 +220,16 @@ LdScriptLoader::LdScriptLoader() : debug_(false) { class LdErrorListener : public BaseErrorListener { public: - std::vector<std::string> messages; + vector<string> messages; void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine, - const std::string &msg, std::exception_ptr e) override { + const string &msg, exception_ptr e) override { messages.push_back("line " + to_string(line) + ":" + to_string(charPositionInLine) + ": " + msg); } }; -LdScript LdScriptLoader::load(std::string path) { - std::ifstream stream(path, std::ios::binary); +LdScript LdScriptLoader::load(string path) { + ifstream stream(path, ios::binary); if (!stream.good() || stream.eof()) { return {}; @@ -292,7 +252,7 @@ LdScript LdScriptLoader::load(std::string path) { if (debug_) { for (auto token : tokens.getTokens()) { - std::cout << token->toString() << std::endl; + cout << token->toString() << endl; } } @@ -311,7 +271,7 @@ LdScript LdScriptLoader::load(std::string path) { } if (debug_ && parser.getNumberOfSyntaxErrors() == 0) { - std::cout << file->toStringTree(&parser) << std::endl << std::endl; + cout << file->toStringTree(&parser) << endl; } return { @@ -31,7 +31,7 @@ This code currently depend on experimental patches for Antlr4's C++ runtime whic more or less do it: git clone https://github.com/trygvis/antlr4 - cd antlr4 + cd antlr4/runtime/Cpp mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=$HOME/opt/antlr-cpp .. @@ -43,6 +43,9 @@ This will build and install Antlr4 into $HOME/opt/antlr-cpp. To build this code follow a similar approach: mkdir build - cmake .. -DAntlr4_DIR=$HOME/opt/antlr-cpp/lib/cmake/Antlr4 -DCMAKE_INSTALL_PREFIX=$HOME/opt/elfinfo + cmake -DAntlr4_DIR=$HOME/opt/antlr-cpp/lib/cmake/Antlr4 \ + -DCMAKE_INSTALL_PREFIX=$HOME/opt/elfinfo \ + -DCMAKE_SKIP_RPATH=ON \ + .. make make install diff --git a/elfinfo.cpp b/elfinfo.cpp index 08c6c5b..4f8848d 100644 --- a/elfinfo.cpp +++ b/elfinfo.cpp @@ -15,7 +15,7 @@ #include <map> #include <elf.h> -#include "Ld.h" +#include "trygvis/elfinfo/Ld.h" using namespace std; using namespace trygvis::elfinfo; diff --git a/include-priv/trygvis/antlr.h b/include-priv/trygvis/antlr.h new file mode 100644 index 0000000..f5656ea --- /dev/null +++ b/include-priv/trygvis/antlr.h @@ -0,0 +1,67 @@ +#pragma once + +#include "antlr4-runtime.h" + +namespace trygvis { +namespace antlr { + +// This namespace is shared copied code + +using ParseTree = antlr4::tree::ParseTree; + +class MissingParseTreeProperty : public std::out_of_range { +public: + explicit MissingParseTreeProperty(const std::string &what) : out_of_range(what) { } +}; + +template<typename V, bool debug = false> +class ParseTreeProperty { +public: + virtual V get(Ref<ParseTree> node) { + return get(node.get()); + } + + virtual V get(ParseTree *const node) { + if (!debug) { + return _annotations.at(node); + } + + try { +// cerr << "node = " << node->getText() << endl; + return _annotations.at(node); + } catch (std::out_of_range &e) { + std::cerr << "get(" << node << "), text=" << node->getText() << std::endl; + std::stringstream buf; + buf << "out of range: " << node << ", text=" << node->getText(); + auto msg = buf.str(); + std::cerr << msg << std::endl; + throw MissingParseTreeProperty(msg); + } + } + + virtual void put(ParseTree *const node, V value) { + if (debug) { + std::cerr << "put(" << node << ", " << value << "), text: " << node->getText() << std::endl; + } + _annotations[node] = value; + } + + virtual V removeFrom(ParseTree *const node) { + auto it = _annotations.find(node); + + if (it == _annotations.end()) { + throw MissingParseTreeProperty(node->getText()); + } + + return it->second; + } + +protected: + std::map<ParseTree *, V> _annotations; + +private: +}; + +} // namespace antlr + +} diff --git a/includes/trygvis/elfinfo/Ld.h b/include/trygvis/elfinfo/Ld.h index 03559a2..9bb81aa 100644 --- a/includes/trygvis/elfinfo/Ld.h +++ b/include/trygvis/elfinfo/Ld.h @@ -4,6 +4,7 @@ #include <set> #include <vector> #include <sstream> +#include <tree/ParseTree.h> namespace trygvis { namespace elfinfo { |