diff options
Diffstat (limited to 'java/src/main/java/io/trygvis/ld/LdLoader.java')
-rw-r--r-- | java/src/main/java/io/trygvis/ld/LdLoader.java | 121 |
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; + } + } + +} |