diff --git a/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/WildSleighAssemblerBuilder.java b/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/WildSleighAssemblerBuilder.java index a9dc79b88e..5fae3eb2cd 100644 --- a/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/WildSleighAssemblerBuilder.java +++ b/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/WildSleighAssemblerBuilder.java @@ -24,7 +24,6 @@ import ghidra.app.plugin.assembler.sleigh.grammars.AssemblyGrammar; import ghidra.app.plugin.assembler.sleigh.grammars.AssemblySentential; import ghidra.app.plugin.assembler.sleigh.sem.*; import ghidra.app.plugin.assembler.sleigh.symbol.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; import ghidra.app.plugin.languages.sleigh.InputContextScraper; import ghidra.app.plugin.processors.sleigh.*; import ghidra.app.plugin.processors.sleigh.pattern.DisjointPattern; @@ -72,10 +71,8 @@ public class WildSleighAssemblerBuilder } protected void buildInputContexts() { - try (DbgCtx dc = dbg.start("Building input contexts")) { - InputContextScraper scraper = new InputContextScraper(lang); - this.inputContexts = scraper.scrapeInputContexts(); - } + InputContextScraper scraper = new InputContextScraper(lang); + this.inputContexts = scraper.scrapeInputContexts(); } @Override diff --git a/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/sem/WildAssemblyNopStateGenerator.java b/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/sem/WildAssemblyNopStateGenerator.java index e5101e39a8..84b70d0416 100644 --- a/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/sem/WildAssemblyNopStateGenerator.java +++ b/Ghidra/Features/WildcardAssembler/src/main/java/ghidra/asm/wild/sem/WildAssemblyNopStateGenerator.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -39,7 +39,6 @@ public class WildAssemblyNopStateGenerator public Stream generate(GeneratorContext gc) { // TODO: Do we want to restrict the values? // TODO: Is this the right place to generate "interesting values"? - gc.dbg("Generating WILD NOP for " + opSym); return Stream.of(new AssemblyGeneratedPrototype( new WildAssemblyNopState(resolver, gc.path, gc.shift, opSym, wildcard), fromLeft)); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/AbstractSleighAssembler.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/AbstractSleighAssembler.java index 8045d7a9e6..3aaede7120 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/AbstractSleighAssembler.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/AbstractSleighAssembler.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,7 +27,6 @@ import ghidra.app.plugin.assembler.sleigh.parse.*; import ghidra.app.plugin.assembler.sleigh.sem.*; import ghidra.app.plugin.assembler.sleigh.symbol.AssemblyNumericSymbols; import ghidra.app.plugin.assembler.sleigh.tree.AssemblyParseBranch; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.framework.model.DomainObjectChangedEvent; import ghidra.framework.model.DomainObjectListener; @@ -43,7 +42,6 @@ import ghidra.util.task.TaskMonitor; public abstract class AbstractSleighAssembler implements GenericAssembler { - protected static final DbgTimer dbg = DbgTimer.INACTIVE; protected class ListenerForSymbolsRefresh implements DomainObjectListener { @Override @@ -150,7 +148,6 @@ public abstract class AbstractSleighAssembler> implements GenericAssemblerBuilder { - protected static final DbgTimer dbg = - SystemUtilities.isInTestingBatchMode() ? DbgTimer.INACTIVE : DbgTimer.ACTIVE; protected final SleighLanguage lang; protected final AbstractAssemblyResolutionFactory factory; @@ -319,41 +314,39 @@ public abstract class AbstractSleighAssemblerBuilder< // * Build the full grammar for the language */ protected void buildGrammar() { - try (DbgCtx dc = dbg.start("Building grammar")) { - grammar = new AssemblyGrammar(factory); - for (Symbol sym : lang.getSymbolTable().getSymbolList()) { - if (sym instanceof SubtableSymbol) { - SubtableSymbol subtable = (SubtableSymbol) sym; - grammar.combine(buildSubGrammar(subtable)); - } - else if (sym instanceof VarnodeSymbol) { - // Ignore. This just becomes a string terminal - } - else if (sym instanceof StartSymbol) { - // Ignore. We handle inst_start in semantic processing - } - else if (sym instanceof EndSymbol) { - // Ignore. We handle inst_next in semantic processing - } - - else if (sym instanceof Next2Symbol) { - // Ignore. We handle inst_next2 in semantic processing - } - else if (sym instanceof UseropSymbol) { - // Ignore. We don't do pcode. - } - else if (sym instanceof OperandSymbol) { - // Ignore. These are terminals, or will be produced by their defining symbols - } - else if (sym instanceof ValueSymbol) { - // Ignore. These are now terminals - } - else { - throw new RuntimeException("Unexpected type: " + sym.getClass()); - } + grammar = new AssemblyGrammar(factory); + for (Symbol sym : lang.getSymbolTable().getSymbolList()) { + if (sym instanceof SubtableSymbol) { + SubtableSymbol subtable = (SubtableSymbol) sym; + grammar.combine(buildSubGrammar(subtable)); + } + else if (sym instanceof VarnodeSymbol) { + // Ignore. This just becomes a string terminal + } + else if (sym instanceof StartSymbol) { + // Ignore. We handle inst_start in semantic processing + } + else if (sym instanceof EndSymbol) { + // Ignore. We handle inst_next in semantic processing + } + + else if (sym instanceof Next2Symbol) { + // Ignore. We handle inst_next2 in semantic processing + } + else if (sym instanceof UseropSymbol) { + // Ignore. We don't do pcode. + } + else if (sym instanceof OperandSymbol) { + // Ignore. These are terminals, or will be produced by their defining symbols + } + else if (sym instanceof ValueSymbol) { + // Ignore. These are now terminals + } + else { + throw new RuntimeException("Unexpected type: " + sym.getClass()); } - grammar.setStartName("instruction"); } + grammar.setStartName("instruction"); } /** @@ -367,18 +360,14 @@ public abstract class AbstractSleighAssemblerBuilder< // * Build the context transition graph for the language */ protected void buildContextGraph() { - try (DbgCtx dc = dbg.start("Building context graph")) { - ctxGraph = new AssemblyContextGraph(factory, lang, grammar); - } + ctxGraph = new AssemblyContextGraph(factory, lang, grammar); } /** * Build the parser for the language */ protected void buildParser() { - try (DbgCtx dc = dbg.start("Building parser")) { - parser = new AssemblyParser(grammar); - } + parser = new AssemblyParser(grammar); } /** diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractBinaryExpressionSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractBinaryExpressionSolver.java index 18a9efc1b3..69f43bb7e7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractBinaryExpressionSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractBinaryExpressionSolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -42,15 +42,9 @@ public abstract class AbstractBinaryExpressionSolver MaskedLong rval = solver.getValue(exp.getRight(), vals, cur); if (lval != null && !lval.isFullyDefined()) { - if (!lval.isFullyUndefined()) { - dbg.println("Partially-defined left value for binary solver: " + lval); - } lval = null; } if (rval != null && !rval.isFullyDefined()) { - if (!rval.isFullyUndefined()) { - dbg.println("Partially-defined right value for binary solver: " + rval); - } rval = null; } @@ -80,7 +74,6 @@ public abstract class AbstractBinaryExpressionSolver return factory.newErrorBuilder().error(e.getMessage()).description(description).build(); } catch (AssertionError e) { - dbg.println("While solving: " + exp + " (" + description + ")"); throw e; } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractExpressionSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractExpressionSolver.java index a5cde4aab2..3e5f59cc94 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractExpressionSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractExpressionSolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,6 @@ import java.util.Map; import java.util.Set; import ghidra.app.plugin.assembler.sleigh.sem.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.expression.PatternExpression; /** @@ -31,8 +30,6 @@ public abstract class AbstractExpressionSolver { private Class tcls; protected RecursiveDescentSolver solver; - protected final DbgTimer dbg = DbgTimer.INACTIVE; - /** * Construct a solver that can solve expression of the given type * diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractUnaryExpressionSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractUnaryExpressionSolver.java index 20c2879771..18ab34d4b0 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractUnaryExpressionSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractUnaryExpressionSolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -53,7 +53,6 @@ public abstract class AbstractUnaryExpressionSolver * AssemblyResolvedConstructor.error(e.getMessage(), description, null); } */ catch (AssertionError e) { - dbg.println("While solving: " + exp + " (" + description + ")"); throw e; } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java index 3832a08eb9..72e4940185 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,6 @@ import java.util.*; import ghidra.app.plugin.assembler.sleigh.expr.match.ExpressionMatcher; import ghidra.app.plugin.assembler.sleigh.sem.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; import ghidra.app.plugin.processors.sleigh.expression.*; import ghidra.util.Msg; @@ -70,31 +69,26 @@ public class OrExpressionSolver extends AbstractBinaryExpressionSolver ent : fields.entrySet()) { + long hi = ent.getKey(); + if (hi == 0) { fieldExp = ent.getValue(); + continue; } + + MaskedLong part = goal.shiftLeft(64 - hi).shiftRightPositional(64 - hi + lo); + AssemblyResolution sol = solver.solve(factory, fieldExp, part, vals, cur, hints, + description + " with shift " + lo); + if (sol.isError()) { + return sol; + } + result = result.combine((AssemblyResolvedPatterns) sol); + if (result == null) { + throw new SolverException("Solutions to individual fields produced conflict"); + } + + lo = hi; + fieldExp = ent.getValue(); } return result; } @@ -166,8 +160,6 @@ public class OrExpressionSolver extends AbstractBinaryExpressionSolver, PatternExpression> match = MATCHERS.neqConst.match(exp); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/RecursiveDescentSolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/RecursiveDescentSolver.java index 8182686c5f..cf376d184c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/RecursiveDescentSolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/RecursiveDescentSolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,7 +18,6 @@ package ghidra.app.plugin.assembler.sleigh.expr; import java.util.*; import ghidra.app.plugin.assembler.sleigh.sem.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.expression.PatternExpression; /** @@ -39,7 +38,6 @@ import ghidra.app.plugin.processors.sleigh.expression.PatternExpression; * {@link PatternExpression}. */ public class RecursiveDescentSolver { - protected static final DbgTimer DBG = DbgTimer.INACTIVE; private static final RecursiveDescentSolver INSTANCE = new RecursiveDescentSolver(); // A mapping from each subclass of PatternExpression to the appropriate solver @@ -118,14 +116,8 @@ public class RecursiveDescentSolver { PatternExpression exp, MaskedLong goal, Map vals, AssemblyResolvedPatterns cur, Set hints, String description) throws NeedsBackfillException { - try { - return getRegistered(exp.getClass()).solve(factory, exp, goal, vals, cur, hints, - description); - } - catch (UnsupportedOperationException e) { - DBG.println("Error solving " + exp + " = " + goal); - throw e; - } + return getRegistered(exp.getClass()).solve(factory, exp, goal, vals, cur, hints, + description); } /** @@ -170,7 +162,6 @@ public class RecursiveDescentSolver { protected MaskedLong getValue(T exp, Map vals, AssemblyResolvedPatterns cur) throws NeedsBackfillException { MaskedLong value = getRegistered(exp.getClass()).getValue(exp, vals, cur); - DBG.println("Expression: " + value + " =: " + exp); return value; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParseMachine.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParseMachine.java index d342b03402..5cdd1a3ee7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParseMachine.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParseMachine.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,8 +25,6 @@ import ghidra.app.plugin.assembler.sleigh.parse.AssemblyParseActionGotoTable.*; import ghidra.app.plugin.assembler.sleigh.symbol.*; import ghidra.app.plugin.assembler.sleigh.tree.*; import ghidra.app.plugin.assembler.sleigh.util.AsmUtil; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; /** * A class that implements the LALR(1) parsing algorithm @@ -75,8 +73,6 @@ public class AssemblyParseMachine implements Comparable { static int nextMachineId = 0; - static final DbgTimer DBG = DbgTimer.INACTIVE; - /** * Construct a new parse state * @@ -206,7 +202,6 @@ public class AssemblyParseMachine implements Comparable { c.accepted = accepted; c.error = error; - DBG.println("Copied " + id + " to " + c.id); return c; } @@ -224,41 +219,37 @@ public class AssemblyParseMachine implements Comparable { */ protected void doAction(Action a, AssemblyParseToken tok, Set results, Deque visited) { - try (DbgCtx dc = DBG.start("Action: " + a)) { - if (a instanceof ShiftAction) { - AssemblyParseMachine m = copy(); - m.stack.push(((ShiftAction) a).newStateNum); - m.treeStack.push(tok); - m.lastTok = tok; - m.pos += tok.getString().length(); - m.exhaust(results, visited); + if (a instanceof ShiftAction) { + AssemblyParseMachine m = copy(); + m.stack.push(((ShiftAction) a).newStateNum); + m.treeStack.push(tok); + m.lastTok = tok; + m.pos += tok.getString().length(); + m.exhaust(results, visited); + } + else if (a instanceof ReduceAction) { + AssemblyProduction prod = ((ReduceAction) a).prod; + AssemblyParseBranch branch = new AssemblyParseBranch(parser.grammar, prod); + AssemblyParseMachine m = copy(); + m.output.add(prod.getIndex()); + for (@SuppressWarnings("unused") + AssemblySymbol sym : prod.getRHS()) { + m.stack.pop(); + branch.addChild(m.treeStack.pop()); } - else if (a instanceof ReduceAction) { - AssemblyProduction prod = ((ReduceAction) a).prod; - AssemblyParseBranch branch = new AssemblyParseBranch(parser.grammar, prod); - AssemblyParseMachine m = copy(); - m.output.add(prod.getIndex()); - DBG.println("Prod: " + prod); - for (@SuppressWarnings("unused") - AssemblySymbol sym : prod.getRHS()) { - m.stack.pop(); - branch.addChild(m.treeStack.pop()); - } - for (Action aa : m.parser.actions.get(m.stack.peek(), prod.getLHS())) { - GotoAction ga = (GotoAction) aa; - DBG.println("Goto: " + ga); - AssemblyParseMachine n = m.copy(); - n.stack.push(ga.newStateNum); - n.treeStack.push(branch); - n.exhaust(results, visited); - } - } - else if (a instanceof AcceptAction) { - AssemblyParseMachine m = copy(); - m.accepted = true; - results.add(m); + for (Action aa : m.parser.actions.get(m.stack.peek(), prod.getLHS())) { + GotoAction ga = (GotoAction) aa; + AssemblyParseMachine n = m.copy(); + n.stack.push(ga.newStateNum); + n.treeStack.push(branch); + n.exhaust(results, visited); } } + else if (a instanceof AcceptAction) { + AssemblyParseMachine m = copy(); + m.accepted = true; + results.add(m); + } } /** @@ -271,13 +262,10 @@ public class AssemblyParseMachine implements Comparable { */ protected void consume(AssemblyTerminal t, AssemblyParseToken tok, Set results, Deque visited) { - try (DbgCtx dc = DBG.start("Matched " + t + " " + tok)) { - Collection as = parser.actions.get(stack.peek(), t); - assert !as.isEmpty(); - DBG.println("Actions: " + as); - for (Action a : as) { - doAction(a, tok, results, visited); - } + Collection as = parser.actions.get(stack.peek(), t); + assert !as.isEmpty(); + for (Action a : as) { + doAction(a, tok, results, visited); } } @@ -320,54 +308,47 @@ public class AssemblyParseMachine implements Comparable { * @param visited a collection of machine states already visited */ protected void exhaust(Set results, Deque visited) { - try (DbgCtx dc = DBG.start("Exhausting machine " + id)) { - DBG.println("Machine: " + this); - AssemblyParseMachine loop = findLoop(this, visited); - if (loop != null) { - DBG.println("Pruned. Loop of " + loop.id); - return; + AssemblyParseMachine loop = findLoop(this, visited); + if (loop != null) { + return; + } + try (DequePush push = DequePush.push(visited, this)) { + if (error != ERROR_NONE) { + throw new AssertionError("INTERNAL: Tried to step a machine with errors"); } - try (DequePush push = DequePush.push(visited, this)) { - if (error != ERROR_NONE) { - throw new AssertionError("INTERNAL: Tried to step a machine with errors"); + if (accepted) { + // Gratuitous inputs should be detected by getTree + throw new AssertionError("INTERNAL: Tried to step an accepted machine"); + } + Collection terms = parser.actions.getExpected(stack.peek()); + if (terms.isEmpty()) { + throw new RuntimeException("Encountered a state with no actions"); + } + Set unmatched = new TreeSet<>(terms); + for (AssemblyTerminal t : terms) { + for (AssemblyParseToken tok : t.match(buffer, pos, parser.grammar, symbols)) { + unmatched.remove(t); + assert buffer.regionMatches(pos, tok.getString(), 0, + tok.getString().length()); + consume(t, tok, results, visited); } - if (accepted) { - // Gratuitous inputs should be detected by getTree - throw new AssertionError("INTERNAL: Tried to step an accepted machine"); + } + if (!unmatched.isEmpty()) { + AssemblyParseMachine m = copy(); + final Collection newExpected; + if (m.lastTok == null || + !(m.lastTok instanceof TruncatedWhiteSpaceParseToken)) { + newExpected = unmatched; } - Collection terms = parser.actions.getExpected(stack.peek()); - if (terms.isEmpty()) { - throw new RuntimeException("Encountered a state with no actions"); - } - Set unmatched = new TreeSet<>(terms); - for (AssemblyTerminal t : terms) { - for (AssemblyParseToken tok : t.match(buffer, pos, parser.grammar, symbols)) { - unmatched.remove(t); - assert buffer.regionMatches(pos, tok.getString(), 0, - tok.getString().length()); - consume(t, tok, results, visited); - } - } - if (!unmatched.isEmpty()) { - AssemblyParseMachine m = copy(); - final Collection newExpected; - if (m.lastTok == null || - !(m.lastTok instanceof TruncatedWhiteSpaceParseToken)) { - newExpected = unmatched; - } - else { - newExpected = new TreeSet<>(); - newExpected.add(AssemblySentential.WHITE_SPACE); - } - DBG.println("Syntax Error: "); - DBG.println(" Expected: " + newExpected); - DBG.println(" Got: " + buffer.substring(pos)); - m.error = ERROR_SYNTAX; - m.got = buffer.substring(pos); - m.expected = newExpected; - results.add(m); - return; + else { + newExpected = new TreeSet<>(); + newExpected.add(AssemblySentential.WHITE_SPACE); } + m.error = ERROR_SYNTAX; + m.got = buffer.substring(pos); + m.expected = newExpected; + results.add(m); + return; } } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParser.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParser.java index c0a65ad26e..4c5f7610c7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParser.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/parse/AssemblyParser.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,8 +24,6 @@ import org.apache.commons.lang3.StringUtils; import ghidra.app.plugin.assembler.sleigh.grammars.*; import ghidra.app.plugin.assembler.sleigh.symbol.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; import ghidra.app.plugin.assembler.sleigh.util.TableEntry; /** @@ -65,12 +63,6 @@ public class AssemblyParser { // the LALR(1) Action/Goto table protected AssemblyParseActionGotoTable actions; - /** - * Change this to {@link DbgTimer#ACTIVE} for verbose diagnostics - */ - protected static final DbgTimer DBG = DbgTimer.INACTIVE; - protected static final boolean DBG_DETAIL = false; - /** * Construct a LALR(1) parser from the given grammar * @@ -90,41 +82,11 @@ public class AssemblyParser { grammar.addProduction(start, new AssemblySentential<>(grammar.getStart(), AssemblyEOI.EOI)); grammar.setStart(start); - try (DbgCtx dc = DBG.start("Computing First/Follow for General Grammar")) { - this.ff = new AssemblyFirstFollow(grammar); - if (DBG_DETAIL) { - printGeneralFF(DBG); - } - } - - try (DbgCtx dc = DBG.start("Computing LR0 States and Transition Table")) { - buildLR0Machine(); - if (DBG_DETAIL) { - printLR0States(DBG); - printLR0TransitionTable(DBG); - } - } - - try (DbgCtx dc = DBG.start("Computing Extended Grammar")) { - buildExtendedGrammar(); - if (DBG_DETAIL) { - printExtendedGrammar(DBG); - } - } - - try (DbgCtx dc = DBG.start("Computing First/Follow for Extended Grammar")) { - this.extff = new AssemblyFirstFollow(extendedGrammar); - if (DBG_DETAIL) { - printExtendedFF(DBG); - } - } - - try (DbgCtx dc = DBG.start("Computing Parse Table")) { - buildActionGotoTable(); - if (DBG_DETAIL) { - printParseTable(DBG); - } - } + this.ff = new AssemblyFirstFollow(grammar); + buildLR0Machine(); + buildExtendedGrammar(); + this.extff = new AssemblyFirstFollow(extendedGrammar); + buildActionGotoTable(); } protected void buildLR0Machine() { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyState.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyState.java index 896e55cd72..45607c1208 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyState.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyState.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,13 +19,10 @@ import java.util.Collection; import java.util.List; import java.util.stream.Stream; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; - /** * Base for a node in an assembly prototype */ public abstract class AbstractAssemblyState { - protected static final DbgTimer DBG = AbstractAssemblyTreeResolver.DBG; protected final AbstractAssemblyTreeResolver resolver; protected final AbstractAssemblyResolutionFactory factory; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyStateGenerator.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyStateGenerator.java index 740fec4655..f492fc0b6c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyStateGenerator.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyStateGenerator.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,7 +21,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import ghidra.app.plugin.assembler.sleigh.tree.AssemblyParseTreeNode; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; /** * Base class for generating prototype nodes ("states") from a parse tree node @@ -29,7 +28,6 @@ import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; * @param the type of parse tree node to process */ public abstract class AbstractAssemblyStateGenerator { - protected static final DbgTimer DBG = AbstractAssemblyTreeResolver.DBG; /** * Context to pass along as states are generated @@ -73,15 +71,6 @@ public abstract class AbstractAssemblyStateGenerator resolver; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyTreeResolver.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyTreeResolver.java index 9893ff4aa1..0d5dc3697c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyTreeResolver.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AbstractAssemblyTreeResolver.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,8 +27,6 @@ import ghidra.app.plugin.assembler.sleigh.sem.AbstractAssemblyStateGenerator.Gen import ghidra.app.plugin.assembler.sleigh.sem.AssemblyResolutionResults.Applicator; import ghidra.app.plugin.assembler.sleigh.symbol.AssemblyNonTerminal; import ghidra.app.plugin.assembler.sleigh.tree.*; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; import ghidra.app.plugin.processors.sleigh.*; import ghidra.app.plugin.processors.sleigh.symbol.*; import ghidra.program.model.address.Address; @@ -45,11 +43,11 @@ import ghidra.program.model.mem.MemBuffer; * attempts to determine possible encodings using the semantics associated with each branch of the * given parse tree. Details of this process are described in {@link SleighAssemblerBuilder}. * + * @param the type for resolved assembly patterns * @see SleighAssemblerBuilder */ public abstract class AbstractAssemblyTreeResolver { protected static final RecursiveDescentSolver SOLVER = RecursiveDescentSolver.getSolver(); - protected static final DbgTimer DBG = DbgTimer.INACTIVE; public static final String INST_START = "inst_start"; public static final String INST_NEXT = "inst_next"; @@ -67,7 +65,8 @@ public abstract class AbstractAssemblyTreeResolver getFactory() { return factory; } @@ -104,15 +106,6 @@ public abstract class AbstractAssemblyTreeResolver protStream = rootGen.generate(new GeneratorContext(List.of(), 0)); - if (DBG == DbgTimer.ACTIVE) { - try (DbgCtx dc = DBG.start("Prototypes:")) { - protStream = protStream.map(prot -> { - DBG.println(prot); - return prot; - }).collect(Collectors.toList()).stream(); - } - } - Stream patStream = protStream.map(p -> p.state).distinct().flatMap(s -> s.resolve(empty, errors)); @@ -159,33 +152,28 @@ public abstract class AbstractAssemblyTreeResolver> paths = - ctxGraph.computeOptimalApplications(src, table, dst, table); - DBG.println("Found " + paths.size()); - for (Deque path : paths) { - DBG.println(" " + path); - result.absorb(applyRecursionPath(path, tree, rootRec, ar)); - } + for (AssemblyResolution ar : temp) { + if (ar.isError()) { + result.add(ar); + continue; } + @SuppressWarnings("unchecked") + RP rp = (RP) ar; + AssemblyPatternBlock dst = rp.getContext(); + // TODO: The desired context may need to be passed in. For now, just take start. + AssemblyPatternBlock src = context; // NOTE: This is only correct for "instruction" + String table = "instruction"; - return result; + Collection> paths = + ctxGraph.computeOptimalApplications(src, table, dst, table); + for (Deque path : paths) { + result.absorb(applyRecursionPath(path, tree, rootRec, ar)); + } } + + return result; } /** @@ -206,9 +194,7 @@ public abstract class AbstractAssemblyTreeResolver { if (rp.hasBackfills()) { @@ -364,11 +350,8 @@ public abstract class AbstractAssemblyTreeResolver { - DBG.println("Current: " + rp.lineToString()); AssemblyResolution backctx = sem.solveContextChanges(rp, vals); - DBG.println("Mutated: " + backctx.lineToString()); return backctx; }).apply(factory, rp -> { return rp.solveContextChangesForForbids(sem, vals); @@ -381,7 +364,6 @@ public abstract class AbstractAssemblyTreeResolver patterns = sem.getPatterns() .stream() diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructState.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructState.java index a91fbedc71..0c3f498979 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructState.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructState.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -142,8 +142,6 @@ public class AssemblyConstructState extends AbstractAssemblyState { return sem.getPatterns() .stream() .map(pat -> { - DBG.println(path + ": Constructor pattern: " + pat.lineToString()); - DBG.println(path + ": Current pattern: " + fromMutations.lineToString()); AssemblyResolvedPatterns combined = fromMutations.combine(pat.shift(shift)); //DBG.println("Combined pattern: " + combined); return combined; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructStateGenerator.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructStateGenerator.java index 7dca302e57..228603009c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructStateGenerator.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructStateGenerator.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -100,8 +100,6 @@ public class AssemblyConstructStateGenerator Stream applied = sem.applyPatternsForward(gc.shift, fromLeft) .filter(pat -> { if (pat == null) { - gc.dbg("Conflicting pattern. fromLeft=" + fromLeft + ",sem=" + - sem.getLocation()); return false; } return true; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructorSemantic.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructorSemantic.java index 5be9e3d122..e320fae8fe 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructorSemantic.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyConstructorSemantic.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,7 +20,6 @@ import java.util.stream.Stream; import ghidra.app.plugin.assembler.sleigh.expr.MaskedLong; import ghidra.app.plugin.assembler.sleigh.expr.RecursiveDescentSolver; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.languages.sleigh.SleighLanguages; import ghidra.app.plugin.languages.sleigh.SubtableEntryVisitor; import ghidra.app.plugin.processors.sleigh.*; @@ -36,7 +35,6 @@ import ghidra.app.plugin.processors.sleigh.symbol.SubtableSymbol; */ public class AssemblyConstructorSemantic implements Comparable { protected static final RecursiveDescentSolver SOLVER = RecursiveDescentSolver.getSolver(); - protected static final DbgTimer DBG = AbstractAssemblyTreeResolver.DBG; protected final Set patterns = new HashSet<>(); protected final AbstractAssemblyResolutionFactory factory; @@ -304,28 +302,22 @@ public class AssemblyConstructorSemantic implements Comparable vals) { for (ContextChange chg : reversedChanges) { if (chg instanceof ContextOp) { - DBG.println("Current: " + res.lineToString()); // This seems backwards. That's because we're going backwards. // This is the "write" location for disassembly. ContextOp cop = (ContextOp) chg; - DBG.println("Handling context change: " + cop); // TODO: Is this res or subres? MaskedLong reqval = res.readContextOp(cop); if (reqval.equals(MaskedLong.UNKS)) { - DBG.println("Doesn't affect a current requirement"); continue; // this context change does not satisfy any requirement } - DBG.println("'read' " + reqval); // Remove the requirement that we just read before trying to solve res = res.maskOut(cop); - DBG.println("Masked out: " + res.lineToString()); // Now, solve AssemblyResolution sol = factory.solveOrBackfill(cop.getPatternExpression(), reqval, vals, res, "Solution to " + cop); - DBG.println("Solution: " + sol.lineToString()); if (sol.isError()) { AssemblyResolvedError err = (AssemblyResolvedError) sol; return factory.error(err.getError(), res); @@ -344,7 +336,6 @@ public class AssemblyConstructorSemantic implements Comparable applyPatternsForward(int shift, AssemblyResolvedPatterns fromLeft) { - if (patterns.isEmpty()) { - DBG.println("No patterns for " + getLocation() + "?" + "(hash=" + - System.identityHashCode(this) + ")"); - } return patterns.stream().map(pat -> fromLeft.combine(pat.shift(shift))); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java index f7613850f8..4df14f07f8 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,7 +18,6 @@ package ghidra.app.plugin.assembler.sleigh.sem; import java.math.BigInteger; import java.util.List; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.program.model.address.Address; import ghidra.program.model.lang.*; @@ -38,8 +37,6 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr protected AssemblyPatternBlock curctx; // the pseudo context value protected AssemblyPatternBlock defctx; // the computed default - protected final static DbgTimer dbg = DbgTimer.INACTIVE; - /** * Compute the default context at most addresses for the given language * @@ -110,17 +107,14 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr @Override public void setValue(Register register, BigInteger value) throws ContextChangeException { - dbg.println("Set " + register + " to " + value); } @Override public void setRegisterValue(RegisterValue value) throws ContextChangeException { - dbg.println("Set " + value); } @Override public void clearRegister(Register register) throws ContextChangeException { - dbg.println("Clear " + register); } @Override @@ -165,12 +159,10 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr @Override public void setFutureRegisterValue(Address address, RegisterValue value) { - dbg.println("Set " + value + " at " + address); } @Override public void setFutureRegisterValue(Address fromAddr, Address toAddr, RegisterValue value) { - dbg.println("Set " + value + " for [" + fromAddr + ":" + toAddr + "]"); } @Override @@ -182,8 +174,6 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr return; } defctx = defctx.combine(AssemblyPatternBlock.fromRegisterValue(registerValue)); - dbg.println("Combining " + registerValue); - dbg.println(" " + defctx); } @Override diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyNopStateGenerator.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyNopStateGenerator.java index 57fd24bdc7..70afde55b4 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyNopStateGenerator.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyNopStateGenerator.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -47,7 +47,6 @@ public class AssemblyNopStateGenerator @Override public Stream generate(GeneratorContext gc) { - gc.dbg("Generating NOP for " + opSym); return Stream.of(new AssemblyGeneratedPrototype( new AssemblyNopState(resolver, gc.path, gc.shift, opSym), fromLeft)); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyOperandState.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyOperandState.java index 36e82087f1..c9e71c0af7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyOperandState.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyOperandState.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,7 +20,6 @@ import java.util.stream.Stream; import ghidra.app.plugin.assembler.sleigh.symbol.AssemblyNumericTerminal; import ghidra.app.plugin.assembler.sleigh.symbol.AssemblyTerminal; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; import ghidra.app.plugin.processors.sleigh.ConstructState; import ghidra.app.plugin.processors.sleigh.expression.PatternExpression; import ghidra.app.plugin.processors.sleigh.symbol.OperandSymbol; @@ -128,42 +127,37 @@ public class AssemblyOperandState extends AbstractAssemblyState { if (symExp == null) { symExp = opSym.getDefiningSymbol().getPatternExpression(); } - DBG.println("Equation: " + symExp + " = " + Long.toHexString(value)); String desc = "Solution to " + opSym + " in " + Long.toHexString(value) + " = " + symExp; AssemblyResolution sol = factory.solveOrBackfill(symExp, value, bitsize, resolver.vals, null, desc); - DBG.println("Solution: " + sol); AssemblyResolution shifted = sol.shift(shift); - DBG.println("Shifted: " + shifted); return shifted; } @Override protected Stream resolve(AssemblyResolvedPatterns fromRight, Collection errors) { - try (DbgCtx dc = DBG.start("Resolving " + terminal)) { - AssemblyResolution sol = solveNumeric(); - if (sol.isError()) { - errors.add((AssemblyResolvedError) sol); - return Stream.of(); - } - if (sol.isBackfill()) { - AssemblyResolvedPatterns combined = - fromRight.combine((AssemblyResolvedBackfill) sol); - return Stream.of(combined.withRight(fromRight)); - } - AssemblyResolution combined = fromRight.combine((AssemblyResolvedPatterns) sol); - if (combined == null) { - errors.add(factory.newErrorBuilder() - .error("Pattern/operand conflict") - .description("Resolving " + terminal) - .build()); - return Stream.of(); - } - AssemblyResolvedPatterns pats = (AssemblyResolvedPatterns) combined; - // Do not take constructor from right - return Stream.of(pats.withRight(fromRight).withConstructor(null)); + AssemblyResolution sol = solveNumeric(); + if (sol.isError()) { + errors.add((AssemblyResolvedError) sol); + return Stream.of(); } + if (sol.isBackfill()) { + AssemblyResolvedPatterns combined = + fromRight.combine((AssemblyResolvedBackfill) sol); + return Stream.of(combined.withRight(fromRight)); + } + AssemblyResolution combined = fromRight.combine((AssemblyResolvedPatterns) sol); + if (combined == null) { + errors.add(factory.newErrorBuilder() + .error("Pattern/operand conflict") + .description("Resolving " + terminal) + .build()); + return Stream.of(); + } + AssemblyResolvedPatterns pats = (AssemblyResolvedPatterns) combined; + // Do not take constructor from right + return Stream.of(pats.withRight(fromRight).withConstructor(null)); } public AssemblyTerminal getTerminal() { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyResolutionResults.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyResolutionResults.java index efb14d25fe..00d8e96753 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyResolutionResults.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyResolutionResults.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,8 +21,6 @@ import java.util.stream.Collectors; import org.apache.commons.collections4.set.AbstractSetDecorator; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; - /** * A set of possible assembly resolutions for a single SLEIGH constructor * @@ -34,7 +32,6 @@ import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; * encodings, including error records describing the pruned intermediate results. */ public class AssemblyResolutionResults extends AbstractSetDecorator { - protected static final DbgTimer DBG = AbstractAssemblyTreeResolver.DBG; public interface Applicator { Iterable getPatterns(AssemblyResolvedPatterns cur); @@ -142,11 +139,8 @@ public class AssemblyResolutionResults extends AbstractSetDecorator children, AssemblyResolution right, String error) { super(factory, description, children, right); - AbstractAssemblyTreeResolver.DBG.println(error); this.error = error; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/DefaultAssemblyResolvedPatterns.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/DefaultAssemblyResolvedPatterns.java index 2804c1c244..b6ab1f8bc7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/DefaultAssemblyResolvedPatterns.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/DefaultAssemblyResolvedPatterns.java @@ -758,11 +758,9 @@ public class DefaultAssemblyResolvedPatterns extends AbstractAssemblyResolution Set printed = Arrays.stream(cons.getOpsPrintOrder()).boxed().collect(Collectors.toSet()); if (!(opSym.getDefiningSymbol() instanceof SubtableSymbol)) { - AssemblyTreeResolver.DBG.println("Operand " + opSym + " is not a sub-table"); continue; } if (!printed.contains(opIdx)) { - AssemblyTreeResolver.DBG.println("Operand " + opSym + " is hidden"); continue; } AssemblyResolvedPatterns child = (AssemblyResolvedPatterns) children.get(opIdx); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/util/DbgTimer.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/util/DbgTimer.java deleted file mode 100644 index 5e497df6d1..0000000000 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/util/DbgTimer.java +++ /dev/null @@ -1,261 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.assembler.sleigh.util; - -import java.io.*; -import java.util.Stack; - -/** - * A debugging, timing, and diagnostic tool - * - *

- * TODO: I should probably remove this and rely on the Msg.trace() method, or at the very least, - * refactor this to use that. - */ -public class DbgTimer extends PrintStream { - // a stack of start times - Stack timeStack = new Stack<>(); - - /** - * Create a new debugging timer, wrapping the given output stream - * - * @param out the stream - */ - public DbgTimer(OutputStream out) { - super(new TabbingOutputStream(out)); - TabbingOutputStream tos = (TabbingOutputStream) this.out; - tos.setTimeStack(timeStack); - } - - /** - * Create a new debugging timer, wrapping standard out - */ - public DbgTimer() { - this(System.out); - } - - /** - * A (rather slow) output stream that indents every line of its output - */ - public static class TabbingOutputStream extends OutputStream { - protected static final int STATE_NOLINE = 0; - protected static final int STATE_LINE = 1; - - protected OutputStream out; - protected int state = STATE_NOLINE; - protected Stack timeStack; - - /** - * Create a new stream wrapping another - * - * @param out the stream to wrap - */ - private TabbingOutputStream(OutputStream out) { - this.out = out; - } - - /** - * Start a new (indented) line of output - * - * @throws IOException - */ - protected void startln() throws IOException { - for (@SuppressWarnings("unused") - Long l : timeStack) { - out.write(' '); - out.write(' '); - } - } - - /** - * Workaround: Set the time stack reference - * - * @param timeStack the stack - */ - protected void setTimeStack(Stack timeStack) { - this.timeStack = timeStack; - } - - /** - * {@inheritDoc} - * - * Parses each line and prepends the indentation as they are printed - */ - @Override - public void write(int b) throws IOException { - if (b == '\n' || b == '\r') { - out.write(b); - state = STATE_NOLINE; - } - else if (state == STATE_NOLINE) { - startln(); - out.write(b); - state = STATE_LINE; - } - else { - out.write(b); - } - } - - @Override - public void close() throws IOException { - if (out == System.out || out == System.err) { - out.flush(); // might as well - return; - } - try (OutputStream s = out) { - s.flush(); - } - } - - @Override - public void flush() throws IOException { - out.flush(); - } - } - - /** An instance that prints to standard out */ - public static final DbgTimer ACTIVE = new DbgTimer(); - /** An instance that prints to /dev/null */ - public static final DbgTimer INACTIVE = new DbgTimer(new OutputStream() { - @Override - public void write(int b) throws IOException { - // This prevents inefficient squelching of debug messages. It is much better to squelch - // at the original print call (many overridden below). If one was missed, please - // override it too. Also see the TODO in the class documentation above. - throw new AssertionError("INTERNAL: Should not be here."); - } - }) { - @Override - public void print(String msg) { - // Nothing - } - - @Override - public void println(String msg) { - // Nothing - } - - @Override - public void println() { - // Nothing - } - - @Override - public void print(Object msg) { - // Nothing - } - - @Override - public void println(Object msg) { - // Nothing - } - - @Override - public DbgCtx start(Object message) { - return null; - } - - @Override - public void stop() { - // Nothing - } - }; - - /** - * Start a new, possibly long-running, task - * - * This is meant to be used idiomatically, as in a try-with-resources block: - * - *

-	 * try (DbgCtx dc = dbg.start("Twiddling the frobs:")) {
-	 * 	// do some classy twiddling
-	 * } // this will automatically print done and the time elapsed within the try block
-	 * 
- * - * This idiom is preferred because the task will be stopped even if an error occurs, if the - * method returns from within the block, etc. - * - * @param message the message to print when the task begins - * @return a context to close when the task ends - * - */ - public DbgCtx start(Object message) { - println(message); - flush(); - timeStack.push(System.currentTimeMillis()); - return new DbgCtx(this); - } - - /** - * Stop the current task - * - *

- * This will print done and the elapsed time since the start of the task. The "current task" is - * determined from the stack. - */ - public void stop() { - long time = System.currentTimeMillis() - timeStack.pop(); - flush(); - println("Done after " + time + "ms"); - } - - /** - * Replace the wrapped output stream (usually temporarily) - * - * @see #resetOutputStream(TabbingOutputStream) - * @param s the replacement stream - * @return the original stream, wrapped in a tabbing stream - */ - public TabbingOutputStream setOutputStream(OutputStream s) { - flush(); - TabbingOutputStream old = (TabbingOutputStream) this.out; - TabbingOutputStream tos = new TabbingOutputStream(s); - tos.setTimeStack(timeStack); - this.out = tos; - return old; - } - - /** - * Put the original tabbing stream back - * - * @see #setOutputStream(OutputStream) - * @param s the original wrapped stream - * @return the replacement stream, wrapped in a tabbing stream - */ - public TabbingOutputStream resetOutputStream(TabbingOutputStream s) { - flush(); - TabbingOutputStream old = (TabbingOutputStream) this.out; - this.out = s; - return old; - } - - /** - * A context for idiomatic use of the {@link DbgTimer} in a try-with-resources block - */ - public static class DbgCtx implements AutoCloseable { - private DbgTimer dbg; - - private DbgCtx(DbgTimer dbg) { - this.dbg = dbg; - } - - @Override - public void close() { - dbg.stop(); - } - } -} diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AbstractAssemblyTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AbstractAssemblyTest.java index 5815c4913f..ad65cbc683 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AbstractAssemblyTest.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AbstractAssemblyTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.assembler.sleigh; -import static org.junit.Assert.*; +import static org.junit.Assert.fail; import java.util.*; @@ -25,10 +25,8 @@ import org.junit.Before; import generic.test.AbstractGenericTest; import ghidra.app.plugin.assembler.*; -import ghidra.app.plugin.assembler.sleigh.parse.*; +import ghidra.app.plugin.assembler.sleigh.parse.AssemblyParseResult; import ghidra.app.plugin.assembler.sleigh.sem.*; -import ghidra.app.plugin.assembler.sleigh.tree.AssemblyParseTreeNode; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.SleighInstructionPrototype; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.util.PseudoInstruction; @@ -39,7 +37,6 @@ import ghidra.program.model.lang.*; import ghidra.program.model.mem.*; import ghidra.program.util.DefaultLanguageService; import ghidra.util.Msg; -import ghidra.util.NumericUtilities; /** * A test for assembly of a particular SLEIGH language @@ -52,7 +49,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { // note: disable debug output in batch mode--over 15M of output to the test log - static final DbgTimer dbg = BATCH_MODE ? DbgTimer.INACTIVE : DbgTimer.ACTIVE; static String setupLangID = ""; /** @@ -89,32 +85,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { return (SleighLanguage) languageService.getLanguage(langID); } - /** - * Print a collection of parse trees to the debug printer - * - * @param trees the trees - */ - protected static void dbgPrintTrees(Collection trees) { - dbg.println("Got " + trees.size() + " tree(s)."); - Set suggestions = new TreeSet<>(); - for (AssemblyParseResult result : trees) { - if (!result.isError()) { - AssemblyParseAcceptResult acc = (AssemblyParseAcceptResult) result; - AssemblyParseTreeNode tree = acc.getTree(); - tree.print(dbg); - } - else { - AssemblyParseErrorResult err = (AssemblyParseErrorResult) result; - dbg.println(err); - if (err.getBuffer().equals("")) { - suggestions.addAll(err.getSuggestions()); - } - } - } - dbg.println("Proposals: " + suggestions); - - } - /** * Disassemble an instruction, presumably the result of assembly * @@ -168,7 +138,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { */ protected void checkOneCompat(String instr, AssemblyResolutionResults rr) { AssemblyPatternBlock ins = AssemblyPatternBlock.fromString(instr); - dbg.println("Checking against: " + ins); Set errs = new TreeSet<>(); // Display in order, I guess Set misses = new TreeSet<>(); for (AssemblyResolution ar : rr) { @@ -183,15 +152,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { } misses.add(rescon); } - - dbg.println("Errors:"); - for (AssemblyResolution ar : errs) { - dbg.println(ar.toString(" ")); - } - dbg.println("Mismatches:"); - for (AssemblyResolution ar : misses) { - dbg.println(ar.toString(" ")); - } fail("No result matched the desired instruction bytes"); } @@ -209,7 +169,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { Address address = lang.getDefaultSpace().getAddress(addr); final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address) : AssemblyPatternBlock.fromString(ctxstr)).fillMask(); - dbg.println("Checking each: " + disassembly + " ctx:" + ctx); boolean gotOne = false; boolean failedOne = false; Set errs = new TreeSet<>(); // Display in order, I guess. @@ -223,13 +182,10 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { } AssemblyResolvedPatterns rp = (AssemblyResolvedPatterns) ar; try { - dbg.println(" " + rp.lineToString()); for (byte[] ins : rp.possibleInsVals(ctx)) { - dbg.println(" " + NumericUtilities.convertBytesToString(ins)); PseudoInstruction pi = disassemble(addr, ins, ctx.getVals()); String cons = dumpConstructorTree(pi); String dis = pi.toString(); - dbg.println(" " + dis); if (!disassembly.contains(dis.trim())) { failedOne = true; misTxtToCons.put(dis, cons); @@ -243,24 +199,9 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { } } if (failedOne) { - dbg.println("Disassembly Mismatches:"); - for (String dis : misTxtToCons.keySet()) { - dbg.println(" " + dis); - for (String cons : misTxtToCons.get(dis)) { - for (AssemblyResolvedPatterns rc : misTxtConsToRes.get(dis + cons)) { - dbg.println(" d:" + cons); - dbg.println(" a:" + rc.dumpConstructorTree()); - dbg.println(rc.toString(" ")); - } - } - } fail("At least one result did not disassemble to the given text"); } if (!gotOne) { - dbg.println("Errors:"); - for (AssemblyResolution ar : errs) { - dbg.println(ar.toString(" ")); - } fail("Did not get any matches"); } } @@ -288,8 +229,6 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { if (ar.isError()) { continue; } - dbg.println("Got:"); - dbg.println(ar.toString(" ")); fail("All results were expected to be errors"); } } @@ -356,7 +295,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { @Override public Collection filterParse( Collection parse) throws AssemblySyntaxException { - dbgPrintTrees(parse); + AssemblyTestCase.dbgPrintTrees(parse); if (checkAllSyntaxErrs) { checkAllSyntaxErrs(parse); } @@ -458,7 +397,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { } /** - * Like {@link #assertOneCompatRestExact(String, String, String, long), except a context is + * Like {@link #assertOneCompatRestExact(String, String, long, String)}, except a context is * given * * @param assembly the input assembly @@ -493,7 +432,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest { } /** - * Like {@link # assertAllSemanticErrors(String), but a context is given + * Like {@link #assertAllSemanticErrors(String)}, but a context is given * * @param assembly the input assembly * @param ctxstr the context pattern for assembly diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AssemblyTestCase.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AssemblyTestCase.java index 0a3c5558db..c8912279fb 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AssemblyTestCase.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/AssemblyTestCase.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,6 +17,8 @@ package ghidra.app.plugin.assembler.sleigh; import static org.junit.Assert.fail; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.util.*; import org.apache.commons.collections4.MultiValuedMap; @@ -28,9 +30,7 @@ import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.assembler.sleigh.parse.*; import ghidra.app.plugin.assembler.sleigh.sem.*; import ghidra.app.plugin.assembler.sleigh.tree.AssemblyParseTreeNode; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.*; -import ghidra.app.plugin.processors.sleigh.SleighDebugLogger.SleighDebugMode; import ghidra.app.util.PseudoInstruction; import ghidra.generic.util.datastruct.TreeSetValuedTreeMap; import ghidra.program.model.address.Address; @@ -38,7 +38,6 @@ import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.lang.*; import ghidra.program.model.mem.*; import ghidra.util.Msg; -import ghidra.util.NumericUtilities; /** * A test for assembly of a particular SLEIGH language @@ -52,7 +51,6 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { // note: disable debug output in batch mode--over 15M of output to the test log - static final DbgTimer dbg = BATCH_MODE ? DbgTimer.INACTIVE : DbgTimer.ACTIVE; static String setupLangID = ""; /** @@ -91,24 +89,25 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { * @param trees the trees */ protected static void dbgPrintTrees(Collection trees) { - dbg.println("Got " + trees.size() + " tree(s)."); + Msg.trace(AssemblyTestCase.class, "Got " + trees.size() + " tree(s)."); Set suggestions = new TreeSet<>(); for (AssemblyParseResult result : trees) { if (!result.isError()) { AssemblyParseAcceptResult acc = (AssemblyParseAcceptResult) result; AssemblyParseTreeNode tree = acc.getTree(); - tree.print(dbg); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + tree.print(new PrintStream(baos)); + Msg.trace(AssemblyTestCase.class, baos.toByteArray()); } else { AssemblyParseErrorResult err = (AssemblyParseErrorResult) result; - dbg.println(err); + Msg.trace(AssemblyTestCase.class, err.toString()); if (err.getBuffer().equals("")) { suggestions.addAll(err.getSuggestions()); } } } - dbg.println("Proposals: " + suggestions); - + Msg.trace(AssemblyTestCase.class, "Proposals: " + suggestions); } /** @@ -129,12 +128,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { Address at = lang.getDefaultSpace().getAddress(addr); context.setContextRegister(ctx); MemBuffer buf = new ByteMemBufferImpl(at, ins, lang.isBigEndian()); - SleighDebugLogger logger = - new SleighDebugLogger(buf, context, lang, SleighDebugMode.VERBOSE); InstructionPrototype ip = lang.parse(buf, context, false); - if (VERBOSE_DIS) { - dbg.println("SleighLog:\n" + logger.toString()); - } return new PseudoInstruction(at, ip, buf, context); } @@ -169,7 +163,6 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { */ protected void checkOneCompat(String instr, AssemblyResolutionResults rr) { AssemblyPatternBlock ins = AssemblyPatternBlock.fromString(instr); - dbg.println("Checking against: " + ins); Set errs = new TreeSet<>(); // Display in order, I guess Set misses = new TreeSet<>(); for (AssemblyResolution ar : rr) { @@ -185,14 +178,6 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { misses.add(rescon); } - dbg.println("Errors:"); - for (AssemblyResolution ar : errs) { - dbg.println(ar.toString(" ")); - } - dbg.println("Mismatches:"); - for (AssemblyResolution ar : misses) { - dbg.println(ar.toString(" ")); - } fail("No result matched the desired instruction bytes"); } @@ -210,7 +195,6 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { Address address = lang.getDefaultSpace().getAddress(addr); final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address) : AssemblyPatternBlock.fromString(ctxstr)).fillMask(); - dbg.println("Checking each: " + disassembly + " ctx:" + ctx); boolean gotOne = false; boolean failedOne = false; Set errs = new TreeSet<>(); // Display in order, I guess. @@ -224,13 +208,10 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { } AssemblyResolvedPatterns rcon = (AssemblyResolvedPatterns) ar; try { - dbg.println(" " + rcon.lineToString()); for (byte[] ins : rcon.possibleInsVals(ctx)) { - dbg.println(" " + NumericUtilities.convertBytesToString(ins)); PseudoInstruction pi = disassemble(addr, ins, ctx.getVals()); String cons = dumpConstructorTree(pi); String dis = pi.toString(); - dbg.println(" " + dis); if (!disassembly.contains(dis.trim())) { failedOne = true; misTxtToCons.put(dis, cons); @@ -244,24 +225,9 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { } } if (failedOne) { - dbg.println("Disassembly Mismatches:"); - for (String dis : misTxtToCons.keySet()) { - dbg.println(" " + dis); - for (String cons : misTxtToCons.get(dis)) { - for (AssemblyResolvedPatterns rc : misTxtConsToRes.get(dis + cons)) { - dbg.println(" d:" + cons); - dbg.println(" a:" + rc.dumpConstructorTree()); - dbg.println(rc.toString(" ")); - } - } - } fail("At least one result did not disassemble to the given text"); } if (!gotOne) { - dbg.println("Errors:"); - for (AssemblyResolution ar : errs) { - dbg.println(ar.toString(" ")); - } fail("Did not get any matches"); } } @@ -289,8 +255,6 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { if (ar.isError()) { continue; } - dbg.println("Got:"); - dbg.println(ar.toString(" ")); fail("All results were expected to be errors"); } } @@ -459,7 +423,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { } /** - * Like {@link #assertOneCompatRestExact(String, String, String, long), except a context is + * Like {@link #assertOneCompatRestExact(String, String, long, String)}, except a context is * given * * @param assembly the input assembly @@ -494,7 +458,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest { } /** - * Like {@link # assertAllSemanticErrors(String), but a context is given + * Like {@link #assertAllSemanticErrors(String)}, but a context is given * * @param assembly the input assembly * @param ctxstr the context pattern for assembly diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/DbgTimerTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/DbgTimerTest.java deleted file mode 100644 index 259c6241d6..0000000000 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/assembler/sleigh/DbgTimerTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.assembler.sleigh; - -import org.junit.Test; - -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.DbgCtx; -import ghidra.app.plugin.assembler.sleigh.util.DbgTimer.TabbingOutputStream; - -public class DbgTimerTest { - @Test - public void testDbgTimer() { - try (DbgTimer dbg = new DbgTimer()) { - dbg.println("The first line"); - try (DbgCtx dc = dbg.start("First push")) { - dbg.println("An indented line"); - } - dbg.println("The last line"); - TabbingOutputStream old = dbg.setOutputStream(System.err); - dbg.println("The error line"); - try (DbgCtx dc = dbg.start("Error push")) { - dbg.println("An indented error line"); - } - dbg.println("The last error line"); - dbg.resetOutputStream(old); - } - } -}