aboutsummaryrefslogtreecommitdiff
path: root/Ld.cpp
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2016-07-17 16:03:47 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2016-07-17 16:03:47 +0200
commit0f57cc9750282ce0284fe69b06f161dea2bfc8cb (patch)
tree50afd51fec2d05752cc49441ae47c40aa831cf84 /Ld.cpp
parentc5e53ec8da9b11e351893742096f76e2bceb5730 (diff)
downloadelfinfo-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.cpp49
1 files changed, 44 insertions, 5 deletions
diff --git a/Ld.cpp b/Ld.cpp
index a60656c..8bacaea 100644
--- a/Ld.cpp
+++ b/Ld.cpp
@@ -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;
}