aboutsummaryrefslogtreecommitdiff
path: root/Ld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Ld.cpp')
-rw-r--r--Ld.cpp68
1 files changed, 52 insertions, 16 deletions
diff --git a/Ld.cpp b/Ld.cpp
index 8bacaea..16c40fa 100644
--- a/Ld.cpp
+++ b/Ld.cpp
@@ -7,10 +7,9 @@ namespace trygvis {
namespace elfinfo {
using antlr4::ANTLRFileStream;
+using antlr4::tree::ParseTree;
using namespace std;
-using ParseTree = antlr4::tree::ParseTree;
-
static MemoryAttribute valueOf(char c) {
switch (c) {
case 'r':
@@ -31,7 +30,7 @@ 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>
+template<typename V, bool debug = false>
class ParseTreeProperty {
public:
virtual V get(Ref<ParseTree> node) {
@@ -39,21 +38,27 @@ public:
}
virtual V get(ParseTree *const node) {
- return _annotations.at(node);
- }
+ if (!debug) {
+ return _annotations.at(node);
+ }
-// virtual V get(ParseTree *const node) {
-// try {
-// cout << "node = " << node->getText() << endl;
-// return _annotations.at(node);
-// } catch (std::out_of_range &e) {
-// cout << "out of range: " << node->getText() << endl;
-// throw e;
-// }
-// }
+ 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) {
- // cout << "put(" << node << ", " << value << ")" << endl;
+ if (debug) {
+ cout << "put(" << node << ", " << value << "), text: " << node->getText() << endl;
+ }
_annotations[node] = value;
}
@@ -131,6 +136,10 @@ public:
expr.put(ctx, 0);
}
+ virtual void exitExpDefined(GnuLdParser::ExpDefinedContext *ctx) override {
+ expr.put(ctx, 0);
+ }
+
void exitExpInt(GnuLdParser::ExpIntContext *ctx) override {
uint64_t i = parseInt(ctx->INT()->getText());
expr.put(ctx, i);
@@ -150,6 +159,20 @@ public:
expr.put(ctx, x);
}
+ void exitExpMul(GnuLdParser::ExpMulContext *ctx) override {
+ uint64_t a = expr.get(ctx->exp(0));
+ uint64_t b = expr.get(ctx->exp(1));
+ uint64_t x = a * b;
+ expr.put(ctx, x);
+ }
+
+ void exitExpDiv(GnuLdParser::ExpDivContext *ctx) override {
+ uint64_t a = expr.get(ctx->exp(0));
+ uint64_t b = expr.get(ctx->exp(1));
+ uint64_t x = b > 0 ? a / b : 0;
+ expr.put(ctx, x);
+ }
+
void exitExpName(GnuLdParser::ExpNameContext *ctx) override {
expr.put(ctx, 0);
}
@@ -176,11 +199,23 @@ public:
expr.put(ctx, expr.get(ctx->exp()));
}
+ void exitExpParen(GnuLdParser::ExpParenContext *ctx) override {
+ expr.put(ctx, expr.get(ctx->exp()));
+ }
+
void exitExpLoadaddr(GnuLdParser::ExpLoadaddrContext *ctx) override {
auto &section = getSection(ctx->NAME()->getText());
expr.put(ctx, 0);
}
+ void exitExpTernary(GnuLdParser::ExpTernaryContext *ctx) override {
+ uint64_t a = expr.get(ctx->exp(0));
+ uint64_t b = expr.get(ctx->exp(1));
+ uint64_t c = expr.get(ctx->exp(2));
+ uint64_t x = a ? b : c;
+ expr.put(ctx, x);
+ }
+
void exitExpConstant(GnuLdParser::ExpConstantContext *ctx) override {
expr.put(ctx, expr.get(ctx->NAME()));
}
@@ -229,7 +264,7 @@ public:
void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine,
const std::string &msg, std::exception_ptr e) override {
- messages.push_back(msg);
+ messages.push_back("line " + to_string(line) + ":" + to_string(charPositionInLine) + ": " + msg);
}
};
@@ -266,6 +301,7 @@ LdScript LdScriptLoader::load(std::string path) {
parser.addParseListener(&listener);
LdErrorListener ldErrorListener;
+ parser.removeErrorListeners();
parser.addErrorListener(&ldErrorListener);
auto file = parser.file();