mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Refactor buildXrefs, parallel versions of ConsistencyCheck
This commit is contained in:
parent
0ed1540e3a
commit
efb6148b6c
9 changed files with 79 additions and 118 deletions
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue