aboutsummaryrefslogtreecommitdiff
path: root/java/src/main/java/io/trygvis/ld/LdLoader.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/main/java/io/trygvis/ld/LdLoader.java')
-rw-r--r--java/src/main/java/io/trygvis/ld/LdLoader.java121
1 files changed, 121 insertions, 0 deletions
diff --git a/java/src/main/java/io/trygvis/ld/LdLoader.java b/java/src/main/java/io/trygvis/ld/LdLoader.java
new file mode 100644
index 0000000..0b71720
--- /dev/null
+++ b/java/src/main/java/io/trygvis/ld/LdLoader.java
@@ -0,0 +1,121 @@
+package io.trygvis.ld;
+
+import io.trygvis.ld.antlr.GnuLdLexer;
+import io.trygvis.ld.antlr.GnuLdParser;
+import org.antlr.v4.runtime.ANTLRFileStream;
+import org.antlr.v4.runtime.BufferedTokenStream;
+import org.antlr.v4.runtime.ConsoleErrorListener;
+
+import java.io.File;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Set;
+
+public class LdLoader {
+
+ public final List<MemoryArea> memoryAreas;
+
+ public LdLoader(List<MemoryArea> memoryAreas) {
+ this.memoryAreas = memoryAreas;
+ }
+
+ public enum MemoryAttribute {
+ R, W, X, A, I,
+ }
+
+ public static class MemoryArea {
+ private final BigInteger MEGA = BigInteger.valueOf(1024 * 1024);
+ private final BigInteger KILO = BigInteger.valueOf(1024);
+
+ String name;
+ BigInteger origin;
+ BigInteger length;
+ Set<MemoryAttribute> attributes;
+
+ @Override
+ public String toString() {
+ return "MemoryArea{" +
+ "name='" + name + '\'' +
+ ", origin=" + origin +
+ ", length=" + length +
+ ", attributes='" + attributes + '\'' +
+ '}';
+ }
+
+ public String prettyOrigin() {
+ if (origin == null) {
+ return "";
+ }
+ String hex = origin.toString(16);
+
+ return "0x" + ("00000000").substring(0, 8 - hex.length()) + hex;
+ }
+
+ public String prettyLength() {
+ if (length == null) {
+ return "";
+ }
+
+ if (length.compareTo(MEGA) >= 0 && length.mod(MEGA).equals(BigInteger.ZERO)) {
+ return length.divide(MEGA) + "M";
+ }
+
+ if (length.compareTo(KILO) >= 0 && length.mod(KILO).equals(BigInteger.ZERO)) {
+ return length.divide(KILO) + "k";
+ }
+
+ return String.valueOf(length);
+ }
+
+ public String prettyAttributes() {
+ String s = "";
+ for (MemoryAttribute attribute : attributes) {
+ s += attribute.name().toLowerCase();
+ }
+ return s;
+ }
+ }
+
+ public static LdLoader load(File path) throws Exception {
+ GnuLdLexer lexer = new GnuLdLexer(new ANTLRFileStream(path.getAbsolutePath()));
+ BufferedTokenStream tokens = new BufferedTokenStream(lexer);
+ GnuLdParser parser = new GnuLdParser(tokens);
+ parser.setBuildParseTree(true);
+ parser.removeErrorListeners();
+ ConsoleErrorListener errorListener = new ConsoleErrorListener();
+ parser.addErrorListener(errorListener);
+ CollectingErrorListener collectingErrorListener = new CollectingErrorListener();
+ parser.addErrorListener(collectingErrorListener);
+
+ ElfinfoGnuLdListener listener = new ElfinfoGnuLdListener();
+ parser.addParseListener(listener);
+
+ GnuLdParser.FileContext file = parser.file();
+
+ if (parser.getNumberOfSyntaxErrors() > 0) {
+ throw new ParseErrorException(lexer, tokens, parser, collectingErrorListener.errors
+ );
+ }
+
+// ElfinfoGnuLdVisitor visitor = new ElfinfoGnuLdVisitor();
+// visitor.visit(file);
+
+// return new LdLoader(visitor.memoryAreas);
+ return new LdLoader(listener.memoryAreas);
+ }
+
+ public static class ParseErrorException extends Exception {
+ public final GnuLdLexer lexer;
+ public final BufferedTokenStream tokens;
+ public final GnuLdParser parser;
+ public final List<String> errors;
+
+ public ParseErrorException(GnuLdLexer lexer, BufferedTokenStream tokens, GnuLdParser parser, List<String> errors) {
+ this.lexer = lexer;
+ this.tokens = tokens;
+ this.parser = parser;
+ this.errors = errors;
+ }
+ }
+
+}