Refactor buildXrefs, parallel versions of ConsistencyCheck

This commit is contained in:
caheckman 2019-09-20 09:07:56 -04:00
parent 0ed1540e3a
commit efb6148b6c
9 changed files with 79 additions and 118 deletions

View file

@ -1,3 +1,18 @@
/* ###
* 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.pcode.utils;
import ghidra.sleigh.grammar.Location;

View file

@ -16,9 +16,9 @@
package ghidra.pcodeCPort.sleighbase;
import java.io.PrintStream;
import java.util.ArrayList;
import generic.stl.*;
import ghidra.pcode.utils.MessageFormattingUtils;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.slghpatexpress.ContextField;
@ -27,8 +27,6 @@ import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.space.spacetype;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location;
import ghidra.util.Msg;
public abstract class SleighBase extends Translate implements NamedSymbolProvider {
@ -69,39 +67,17 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
return (root != null);
}
public void reportError(Location location, String msg) {
Msg.error(this, MessageFormattingUtils.format(location, msg));
}
public void reportError(Location location, String msg, Throwable t) {
Msg.error(this, MessageFormattingUtils.format(location, msg), t);
}
public void reportWarning(Location location, String msg) {
Msg.warn(this, MessageFormattingUtils.format(location, msg));
}
protected void buildXrefs() {
protected void buildXrefs(ArrayList<SleighSymbol> errorPairs) {
SymbolScope glb = symtab.getGlobalScope();
int errors = 0;
glb.begin();
IteratorSTL<SleighSymbol> iter;
StringBuffer buffer = new StringBuffer();
for (iter = glb.begin(); !iter.isEnd(); iter.increment()) {
SleighSymbol sym = iter.get();
if (sym.getType() == symbol_type.varnode_symbol) {
Pair<IteratorSTL<VarnodeSymbol>, Boolean> res = varnode_xref.insert((VarnodeSymbol) sym);
if (!res.second) {
String msg = String.format("Duplicate (offset,size) pair for registers: %s (%s) and %s (%s)",
sym.getName(), sym.getLocation(), res.first.get().getName(), res.first.get().getLocation());
buffer.append(msg + "\n");
reportError(sym.getLocation(), msg);
reportError(res.first.get().getLocation(), msg);
errors += 1;
errorPairs.add(sym);
errorPairs.add(res.first.get());
}
} else if (sym.getType() == symbol_type.userop_symbol) {
int index = ((UserOpSymbol) sym).getIndex();
@ -117,9 +93,6 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
registerContext(csym.getName(), startbit, endbit);
}
}
if (errors > 0) {
throw new SleighError(buffer.toString(), null);
}
}
protected void reregisterContext() {

View file

@ -25,8 +25,6 @@ import ghidra.pcodeCPort.semantics.ConstTpl.const_type;
import ghidra.pcodeCPort.semantics.ConstTpl.v_field;
import ghidra.pcodeCPort.slghsymbol.*;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
import ghidra.util.Msg;
class ConsistencyChecker {
@ -35,6 +33,7 @@ class ConsistencyChecker {
int writenoread;
boolean printextwarning;
boolean printdeadwarning;
SleighCompile compiler;
SubtableSymbol root_symbol;
VectorSTL<SubtableSymbol> postorder = new VectorSTL<>();
@ -480,30 +479,6 @@ class ConsistencyChecker {
}
}
private void reportError(Location location, CharSequence message) {
if (location == null) {
Msg.error(this, message);
return;
}
StringBuilder sb = new StringBuilder();
sb.append(location).append(": ").append(message);
Msg.error(this, sb.toString());
}
private void reportWarning(Location location, CharSequence message) {
if (location == null) {
Msg.warn(this, message);
return;
}
StringBuilder sb = new StringBuilder();
sb.append(location).append(": ").append(message);
Msg.warn(this, sb.toString());
}
void printOpError(OpTpl op, Constructor ct, int err1, int err2, String message) {
SubtableSymbol sym = ct.getParent();
OperandSymbol op1, op2;
@ -537,7 +512,7 @@ class ConsistencyChecker {
sb.append("\n ").append(message);
reportError(op.location, sb);
compiler.reportError(op.location, sb.toString());
}
@ -576,7 +551,7 @@ class ConsistencyChecker {
}
private void handle(String msg, Constructor ct) {
reportError(ct.location, " Unsigned comparison with " + msg + " in constructor");
compiler.reportError(ct.location, " Unsigned comparison with " + msg + " in constructor");
}
private void handleZero(String trueOrFalse, Constructor ct) {
@ -740,7 +715,7 @@ class ConsistencyChecker {
HandleTpl exportres = ct.getTempl().getResult();
if (exportres != null) {
if (seenemptyexport && (!seennonemptyexport)) {
reportError(ct.location, String.format(
compiler.reportError(ct.location, String.format(
"Table '%s' exports inconsistently; Constructor at %s is first inconsitency",
sym.getName(), ct.location));
testresult = false;
@ -751,7 +726,7 @@ class ConsistencyChecker {
tablesize = exsize;
}
if ((exsize != 0) && (exsize != tablesize)) {
reportError(ct.location, String.format(
compiler.reportError(ct.location, String.format(
"Table '%s' has inconsistent export size; Constructor at %s is first conflict",
sym.getName(), ct.location));
testresult = false;
@ -759,7 +734,7 @@ class ConsistencyChecker {
}
else {
if (seennonemptyexport && (!seenemptyexport)) {
reportError(ct.location, String.format(
compiler.reportError(ct.location, String.format(
"Table '%s' exports inconsistently; Constructor at %s is first inconsitency",
sym.getName(), ct.location));
testresult = false;
@ -769,7 +744,8 @@ class ConsistencyChecker {
}
if (seennonemptyexport) {
if (tablesize == 0) {
reportWarning(sym.location, "Table '" + sym.getName() + "' exports size 0");
compiler.reportWarning(sym.location,
"Table '" + sym.getName() + "' exports size 0");
}
sizemap.put(sym, tablesize); // Remember recovered size
@ -785,7 +761,7 @@ class ConsistencyChecker {
// input size is the same as the output size
void dealWithUnnecessaryExt(OpTpl op, Constructor ct) {
if (printextwarning) {
reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
compiler.reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
}
op.setOpcode(OpCode.CPUI_COPY); // Equivalent to copy
unnecessarypcode += 1;
@ -793,7 +769,7 @@ class ConsistencyChecker {
void dealWithUnnecessaryTrunc(OpTpl op, Constructor ct) {
if (printextwarning) {
reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
compiler.reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
}
op.setOpcode(OpCode.CPUI_COPY); // Equivalent to copy
op.removeInput(1);
@ -1144,12 +1120,12 @@ class ConsistencyChecker {
OptimizeRecord currec = pair.second;
if (currec.readcount == 0) {
if (printdeadwarning) {
reportWarning(ct.location, "Temporary is written but not read");
compiler.reportWarning(ct.location, "Temporary is written but not read");
}
writenoread += 1;
}
else if (currec.writecount == 0) {
reportError(ct.location, "Temporary is read but not written");
compiler.reportError(ct.location, "Temporary is read but not written");
readnowrite += 1;
}
iter.increment();
@ -1175,7 +1151,8 @@ class ConsistencyChecker {
checkUnusedTemps(ct, recs);
}
ConsistencyChecker(SubtableSymbol rt, boolean unnecessary, boolean warndead) {
ConsistencyChecker(SleighCompile cp, SubtableSymbol rt, boolean unnecessary, boolean warndead) {
compiler = cp;
root_symbol = rt;
unnecessarypcode = 0;
readnowrite = 0;

View file

@ -499,7 +499,7 @@ public class SleighCompile extends SleighBase {
void checkConsistency() {
entry("checkConsistency");
ConsistencyChecker checker =
new ConsistencyChecker(root, warnunnecessarypcode, warndeadtemps);
new ConsistencyChecker(this, root, warnunnecessarypcode, warndeadtemps);
if (!checker.test()) {
errors += 1;
@ -650,26 +650,23 @@ public class SleighCompile extends SleighBase {
}
@Override
public void reportError(Location location, String msg) {
entry("reportError", location, msg);
super.reportError(location, msg);
Msg.error(this, MessageFormattingUtils.format(location, msg));
errors += 1;
}
@Override
public void reportError(Location location, String msg, Throwable t) {
entry("reportError", location, msg);
super.reportError(location, msg, t);
Msg.error(this, MessageFormattingUtils.format(location, msg), t);
errors += 1;
}
@Override
public void reportWarning(Location location, String msg) {
entry("reportWarning", location, msg);
super.reportWarning(location, msg);
Msg.warn(this, MessageFormattingUtils.format(location, msg));
warnings += 1;
}
@ -757,11 +754,19 @@ public class SleighCompile extends SleighBase {
if (errors > 0) {
return;
}
try {
buildXrefs(); // Make sure we can build crossrefs properly
}
catch (SleighError err) {
Msg.error(this, err.location + ": " + err.getMessage(), err);
ArrayList<SleighSymbol> errorPairs = new ArrayList<SleighSymbol>();
buildXrefs(errorPairs); // Make sure we can build crossrefs properly
if (!errorPairs.isEmpty()) {
for (int i = 0; i < errorPairs.size(); i += 2) {
SleighSymbol sym1 = errorPairs.get(i);
SleighSymbol sym2 = errorPairs.get(i + 1);
String msg =
String.format("Duplicate (offset,size) pair for registers: %s (%s) and %s (%s)",
sym1.getName(), sym1.getLocation(), sym2.getName(), sym2.getLocation());
reportError(sym1.getLocation(), msg);
reportError(sym2.getLocation(), msg);
}
errors += 1;
return;
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.