mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
A first cut at normalizing the structure of sleigh error messages
This commit is contained in:
parent
b0609a1cb3
commit
0ed1540e3a
22 changed files with 661 additions and 408 deletions
|
@ -66,7 +66,7 @@ scope Block {
|
|||
}
|
||||
|
||||
private void redefinedError(SleighSymbol sym, Tree t, String what) {
|
||||
String msg = "symbol " + sym.getName() + " (from " + sym.getLocation() + ") redefined as " + what;
|
||||
String msg = "symbol '" + sym.getName() + "' (from " + sym.getLocation() + ") redefined as " + what;
|
||||
reportError(find(t), msg);
|
||||
}
|
||||
|
||||
|
@ -76,17 +76,17 @@ scope Block {
|
|||
}
|
||||
|
||||
private void wrongSymbolTypeError(SleighSymbol sym, Location where, String type, String purpose) {
|
||||
String msg = sym.getType() + " " + sym + " (defined at " + sym.getLocation() + ") is wrong type (should be " + type + ") in " + purpose;
|
||||
String msg = sym.getType() + " '" + sym + "' (defined at " + sym.getLocation() + ") is wrong type (should be " + type + ") in " + purpose;
|
||||
reportError(where, msg);
|
||||
}
|
||||
|
||||
private void undeclaredSymbolError(SleighSymbol sym, Location where, String purpose) {
|
||||
String msg = sym + " (used in " + purpose + ") is not declared in the pattern list";
|
||||
String msg = "'" + sym + "' (used in " + purpose + ") is not declared in the pattern list";
|
||||
reportError(where, msg);
|
||||
}
|
||||
|
||||
private void unknownSymbolError(String text, Location loc, String type, String purpose) {
|
||||
String msg = "unknown " + type + " " + text + " in " + purpose;
|
||||
String msg = "unknown " + type + " '" + text + "' in " + purpose;
|
||||
reportError(loc, msg);
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ fielddef
|
|||
long start = $s.value.longValue();
|
||||
long finish = $e.value.longValue();
|
||||
if (finish < start) {
|
||||
reportError(find($t), "field " + $n.value.getText() + " starts at " + start + " and ends at " + finish);
|
||||
reportError(find($t), "field '" + $n.value.getText() + "' starts at " + start + " and ends at " + finish);
|
||||
}
|
||||
$fielddef::fieldQuality = new FieldQuality($n.value.getText(), find($t), $s.value.longValue(), $e.value.longValue());
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ typemod
|
|||
space_class type = space_class.valueOf(typeName);
|
||||
$spacedef::quality.type = type;
|
||||
} catch(IllegalArgumentException e) {
|
||||
reportError(find(n), "invalid space type " + typeName);
|
||||
reportError(find(n), "invalid space type '" + typeName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -829,7 +829,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
|
|||
} else if(sym.getType() == symbol_type.operand_symbol) {
|
||||
OperandSymbol os = (OperandSymbol) sym;
|
||||
if (os.getDefiningSymbol() != null && os.getDefiningSymbol().getType() == symbol_type.subtable_symbol) {
|
||||
reportError(find($s), "Subtable symbol " + sym.getName() + " is not allowed in context block");
|
||||
reportError(find($s), "Subtable symbol '" + sym.getName() + "' is not allowed in context block");
|
||||
}
|
||||
$expr = os.getPatternExpression();
|
||||
} else if(sym.getType() == symbol_type.start_symbol
|
||||
|
@ -847,7 +847,7 @@ pattern_symbol[String purpose] returns [PatternExpression expr]
|
|||
FamilySymbol z = (FamilySymbol) sym;
|
||||
$expr = z.getPatternValue();
|
||||
} else {
|
||||
reportError(find($s), "Global symbol " + sym.getName() + " is not allowed in action expression");
|
||||
reportError(find($s), "Global symbol '" + sym.getName() + "' is not allowed in action expression");
|
||||
}
|
||||
} else {
|
||||
wrongSymbolTypeError(sym, find($s), "start, end, operand, epsilon, or varnode", purpose);
|
||||
|
@ -908,7 +908,7 @@ cstatement[VectorSTL<ContextChange> r]
|
|||
} else if(sym.getType() == symbol_type.context_symbol) {
|
||||
ContextSymbol t = (ContextSymbol) sym;
|
||||
if (!sc.contextMod(r, t, e)) {
|
||||
reportError(find($id), "Cannot use 'inst_next' to set context variable: " + t.getName());
|
||||
reportError(find($id), "Cannot use 'inst_next' to set context variable: '" + t.getName() + "'");
|
||||
}
|
||||
} else if(sym.getType() == symbol_type.operand_symbol) {
|
||||
OperandSymbol t = (OperandSymbol) sym;
|
||||
|
@ -919,7 +919,7 @@ cstatement[VectorSTL<ContextChange> r]
|
|||
}
|
||||
| ^(OP_APPLY ^(OP_IDENTIFIER id=.) ^(OP_IDENTIFIER arg1=.) ^(OP_IDENTIFIER arg2=.)) {
|
||||
if (!"globalset".equals(id.getText())) {
|
||||
reportError(find($id), "unknown context block function " + id.getText());
|
||||
reportError(find($id), "unknown context block function '" + id.getText() + "'");
|
||||
} else {
|
||||
SleighSymbol sym = sc.findSymbol($arg2.getText());
|
||||
if (sym == null) {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package ghidra.pcode.utils;
|
||||
|
||||
import ghidra.sleigh.grammar.Location;
|
||||
|
||||
public final class MessageFormattingUtils {
|
||||
|
||||
/**
|
||||
* Format a log message.
|
||||
*
|
||||
* @param location Referenced file location
|
||||
* @param message Message
|
||||
* @return Formatted string with location prepended to message.
|
||||
*/
|
||||
public static String format(Location location, CharSequence message) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (location != null) {
|
||||
sb.append(location).append(": ");
|
||||
}
|
||||
sb.append(message);
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
}
|
|
@ -171,7 +171,7 @@ public class ParserContext {
|
|||
}
|
||||
|
||||
public int getInstructionBytes(int bytestart, int size, int off) {
|
||||
// Get bytes from the instruction stream into a intm
|
||||
// Get bytes from the instruction stream into an int
|
||||
// (assuming big endian format)
|
||||
off += bytestart;
|
||||
if (off >= 16) {
|
||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.pcodeCPort.sleighbase;
|
|||
import java.io.PrintStream;
|
||||
|
||||
import generic.stl.*;
|
||||
import ghidra.pcode.utils.MessageFormattingUtils;
|
||||
import ghidra.pcodeCPort.context.SleighError;
|
||||
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
|
||||
import ghidra.pcodeCPort.slghpatexpress.ContextField;
|
||||
|
@ -26,10 +27,13 @@ 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 {
|
||||
|
||||
// NOTE: restoreXml method removed as it is only used by the decompiler's implementation
|
||||
// NOTE: restoreXml method removed as it is only used by the decompiler's
|
||||
// implementation
|
||||
|
||||
public static final int SLA_FORMAT_VERSION = 2; // What format of the .sla file this produces
|
||||
// This value should always match SleighLanguage.SLA_FORMAT_VERSION
|
||||
|
@ -65,6 +69,18 @@ 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() {
|
||||
SymbolScope glb = symtab.getGlobalScope();
|
||||
int errors = 0;
|
||||
|
@ -74,29 +90,26 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
|
|||
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);
|
||||
Pair<IteratorSTL<VarnodeSymbol>, Boolean> res = varnode_xref.insert((VarnodeSymbol) sym);
|
||||
if (!res.second) {
|
||||
buffer.append("Duplicate (offset,size) pair for registers: ");
|
||||
buffer.append(sym.getName());
|
||||
buffer.append(" (");
|
||||
buffer.append(sym.getLocation());
|
||||
buffer.append(") and ");
|
||||
buffer.append(res.first.get().getName());
|
||||
buffer.append(" (");
|
||||
buffer.append(res.first.get().getLocation());
|
||||
buffer.append(")\n");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (sym.getType() == symbol_type.userop_symbol) {
|
||||
} else if (sym.getType() == symbol_type.userop_symbol) {
|
||||
int index = ((UserOpSymbol) sym).getIndex();
|
||||
while (userop.size() <= index) {
|
||||
userop.push_back("");
|
||||
}
|
||||
userop.set(index, sym.getName());
|
||||
}
|
||||
else if (sym.getType() == symbol_type.context_symbol) {
|
||||
} else if (sym.getType() == symbol_type.context_symbol) {
|
||||
ContextSymbol csym = (ContextSymbol) sym;
|
||||
ContextField field = (ContextField) csym.getPatternValue();
|
||||
int startbit = field.getStartBit();
|
||||
|
@ -137,10 +150,10 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
|
|||
public VarnodeData getRegister(String nm) {
|
||||
VarnodeSymbol sym = (VarnodeSymbol) findSymbol(nm);
|
||||
if (sym == null) {
|
||||
throw new SleighError("Unknown register name: " + nm, null);
|
||||
throw new SleighError("Unknown register name '" + nm + "'", null);
|
||||
}
|
||||
if (sym.getType() != symbol_type.varnode_symbol) {
|
||||
throw new SleighError("Symbol is not a register: " + nm, null);
|
||||
throw new SleighError("Symbol is not a register '" + nm + "'", sym.location);
|
||||
}
|
||||
return sym.getFixedVarnode();
|
||||
}
|
||||
|
@ -208,8 +221,8 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
|
|||
s.append(">\n");
|
||||
for (int i = 0; i < numSpaces(); ++i) {
|
||||
AddrSpace spc = getSpace(i);
|
||||
if ((spc.getType() == spacetype.IPTR_CONSTANT) ||
|
||||
(spc.getType() == spacetype.IPTR_FSPEC) || (spc.getType() == spacetype.IPTR_IOP)) {
|
||||
if ((spc.getType() == spacetype.IPTR_CONSTANT) || (spc.getType() == spacetype.IPTR_FSPEC)
|
||||
|| (spc.getType() == spacetype.IPTR_IOP)) {
|
||||
continue;
|
||||
}
|
||||
spc.saveXml(s);
|
||||
|
|
|
@ -25,6 +25,7 @@ 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 {
|
||||
|
@ -97,7 +98,8 @@ class ConsistencyChecker {
|
|||
if ((vnout == 0) || (vn0 == 0)) {
|
||||
return true;
|
||||
}
|
||||
printOpError(op, ct, -1, 0, "Input and output sizes must match");
|
||||
printOpError(op, ct, -1, 0, "Input and output sizes must match; " +
|
||||
op.getIn(0).getSize() + " != " + op.getOut().getSize());
|
||||
return false;
|
||||
case CPUI_INT_ADD:
|
||||
case CPUI_INT_SUB:
|
||||
|
@ -324,7 +326,7 @@ class ConsistencyChecker {
|
|||
if ((vnout == 0) || (vn0 == 0)) {
|
||||
return true;
|
||||
}
|
||||
if ((vnout == vn0) && (vn1 == 0)) { // No actual truncation is occuring
|
||||
if ((vnout == vn0) && (vn1 == 0)) { // No actual truncation is occurring
|
||||
dealWithUnnecessaryTrunc(op, ct);
|
||||
return true;
|
||||
}
|
||||
|
@ -478,6 +480,30 @@ 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;
|
||||
|
@ -489,24 +515,30 @@ class ConsistencyChecker {
|
|||
else {
|
||||
op2 = null;
|
||||
}
|
||||
Msg.error(this, "Size restriction error in table \"" + sym.getName() +
|
||||
"\" in constructor at " + ct.location + " from operation located at " + op.location);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Size restriction error in table '")
|
||||
.append(sym.getName())
|
||||
.append("' in constructor at ").append(ct.location)
|
||||
.append("\n");
|
||||
|
||||
|
||||
sb.append(" Problem");
|
||||
if ((op1 != null) && (op2 != null)) {
|
||||
sb.append(" with \"" + op1.getName() + "\" and \"" + op2.getName() + "\"");
|
||||
sb.append(" with '" + op1.getName() + "' and '" + op2.getName() + "'");
|
||||
}
|
||||
else if (op1 != null) {
|
||||
sb.append(" with \"" + op1.getName() + "\"");
|
||||
sb.append(" with '" + op1.getName() + "'");
|
||||
}
|
||||
else if (op2 != null) {
|
||||
sb.append(" with \"" + op2.getName() + "\"");
|
||||
sb.append(" with '" + op2.getName() + "'");
|
||||
}
|
||||
sb.append(" in \"" + getOpName(op) + "\" operator");
|
||||
Msg.error(this, sb.toString());
|
||||
sb.append(" in '" + getOpName(op) + "' operator");
|
||||
|
||||
sb.append("\n ").append(message);
|
||||
|
||||
reportError(op.location, sb);
|
||||
|
||||
Msg.error(this, " " + message);
|
||||
}
|
||||
|
||||
int recoverSize(ConstTpl sizeconst, Constructor ct) {
|
||||
|
@ -544,7 +576,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
private void handle(String msg, Constructor ct) {
|
||||
Msg.error(this, "Unsigned comparison with " + msg + " in constructor at " + ct.location);
|
||||
reportError(ct.location, " Unsigned comparison with " + msg + " in constructor");
|
||||
}
|
||||
|
||||
private void handleZero(String trueOrFalse, Constructor ct) {
|
||||
|
@ -708,8 +740,9 @@ class ConsistencyChecker {
|
|||
HandleTpl exportres = ct.getTempl().getResult();
|
||||
if (exportres != null) {
|
||||
if (seenemptyexport && (!seennonemptyexport)) {
|
||||
Msg.error(this, "Table " + sym.getName() + " exports inconsistently");
|
||||
Msg.error(this, "Constructor at " + ct.location + " is first inconsistency");
|
||||
reportError(ct.location, String.format(
|
||||
"Table '%s' exports inconsistently; Constructor at %s is first inconsitency",
|
||||
sym.getName(), ct.location));
|
||||
testresult = false;
|
||||
}
|
||||
seennonemptyexport = true;
|
||||
|
@ -718,15 +751,17 @@ class ConsistencyChecker {
|
|||
tablesize = exsize;
|
||||
}
|
||||
if ((exsize != 0) && (exsize != tablesize)) {
|
||||
Msg.error(this, "Table " + sym.getName() + " has inconsistent export size.");
|
||||
Msg.error(this, "Constructor at " + ct.location + " is first conflict");
|
||||
reportError(ct.location, String.format(
|
||||
"Table '%s' has inconsistent export size; Constructor at %s is first conflict",
|
||||
sym.getName(), ct.location));
|
||||
testresult = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (seennonemptyexport && (!seenemptyexport)) {
|
||||
Msg.error(this, "Table " + sym.getName() + " exports inconsistently");
|
||||
Msg.error(this, "Constructor at " + ct.location + " is first inconsistency");
|
||||
reportError(ct.location, String.format(
|
||||
"Table '%s' exports inconsistently; Constructor at %s is first inconsitency",
|
||||
sym.getName(), ct.location));
|
||||
testresult = false;
|
||||
}
|
||||
seenemptyexport = true;
|
||||
|
@ -734,7 +769,8 @@ class ConsistencyChecker {
|
|||
}
|
||||
if (seennonemptyexport) {
|
||||
if (tablesize == 0) {
|
||||
Msg.error(this, "Warning: Table " + sym.getName() + " exports size 0");
|
||||
reportWarning(sym.location, "Table '" + sym.getName() + "' exports size 0");
|
||||
|
||||
}
|
||||
sizemap.put(sym, tablesize); // Remember recovered size
|
||||
}
|
||||
|
@ -749,8 +785,7 @@ class ConsistencyChecker {
|
|||
// input size is the same as the output size
|
||||
void dealWithUnnecessaryExt(OpTpl op, Constructor ct) {
|
||||
if (printextwarning) {
|
||||
Msg.error(this, "Unnecessary \"" + getOpName(op) + "\" in constructor from " +
|
||||
ct.getFilename() + " starting at line " + ct.getLineno());
|
||||
reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
|
||||
}
|
||||
op.setOpcode(OpCode.CPUI_COPY); // Equivalent to copy
|
||||
unnecessarypcode += 1;
|
||||
|
@ -758,8 +793,7 @@ class ConsistencyChecker {
|
|||
|
||||
void dealWithUnnecessaryTrunc(OpTpl op, Constructor ct) {
|
||||
if (printextwarning) {
|
||||
Msg.error(this, "Unnecessary \"" + getOpName(op) + "\" in constructor from " +
|
||||
ct.getFilename() + " starting at line " + ct.getLineno());
|
||||
reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
|
||||
}
|
||||
op.setOpcode(OpCode.CPUI_COPY); // Equivalent to copy
|
||||
op.removeInput(1);
|
||||
|
@ -853,14 +887,8 @@ class ConsistencyChecker {
|
|||
}
|
||||
}
|
||||
|
||||
static boolean possibleIntersection(VarnodeTpl vn1, VarnodeTpl vn2) { // Conservatively
|
||||
// test
|
||||
// whether
|
||||
// vn1
|
||||
// and
|
||||
// vn2
|
||||
// can
|
||||
// intersect
|
||||
static boolean possibleIntersection(VarnodeTpl vn1, VarnodeTpl vn2) {
|
||||
// Conservatively test whether vn1 and vn2 can intersect
|
||||
if (vn1.getSpace().isConstSpace()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1116,15 +1144,12 @@ class ConsistencyChecker {
|
|||
OptimizeRecord currec = pair.second;
|
||||
if (currec.readcount == 0) {
|
||||
if (printdeadwarning) {
|
||||
Msg.error(this,
|
||||
"Warning: temporary is written but not read in constructor at " +
|
||||
ct.location);
|
||||
reportWarning(ct.location, "Temporary is written but not read");
|
||||
}
|
||||
writenoread += 1;
|
||||
}
|
||||
else if (currec.writecount == 0) {
|
||||
Msg.error(this,
|
||||
"Error: temporary is read but not written in constructor at " + ct.location);
|
||||
reportError(ct.location, "Temporary is read but not written");
|
||||
readnowrite += 1;
|
||||
}
|
||||
iter.increment();
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
*/
|
||||
package ghidra.pcodeCPort.slgh_compile;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import generic.stl.IteratorSTL;
|
||||
import generic.stl.VectorSTL;
|
||||
import ghidra.pcode.utils.MessageFormattingUtils;
|
||||
import ghidra.pcodeCPort.context.SleighError;
|
||||
import ghidra.pcodeCPort.opcodes.OpCode;
|
||||
import ghidra.pcodeCPort.semantics.*;
|
||||
|
@ -89,12 +92,9 @@ public abstract class PcodeCompile {
|
|||
|
||||
public void reportError(Location location, String msg) {
|
||||
entry("reportError", location, msg);
|
||||
if (location == null) {
|
||||
log.error(msg);
|
||||
}
|
||||
else {
|
||||
log.error(location + ": " + msg);
|
||||
}
|
||||
|
||||
log.error(MessageFormattingUtils.format(location, msg));
|
||||
|
||||
++errors;
|
||||
}
|
||||
|
||||
|
@ -104,12 +104,9 @@ public abstract class PcodeCompile {
|
|||
|
||||
public void reportWarning(Location location, String msg) {
|
||||
entry("reportWarning", location, msg);
|
||||
if (location == null) {
|
||||
log.warn(msg);
|
||||
}
|
||||
else {
|
||||
log.warn(location + ": " + msg);
|
||||
}
|
||||
|
||||
log.warn(MessageFormattingUtils.format(location, msg));
|
||||
|
||||
++warnings;
|
||||
}
|
||||
|
||||
|
@ -147,7 +144,8 @@ public abstract class PcodeCompile {
|
|||
if ((size.getType() == ConstTpl.const_type.real) &&
|
||||
(vn.getSize().getType() == ConstTpl.const_type.real) &&
|
||||
(vn.getSize().getReal() != 0) && (vn.getSize().getReal() != size.getReal())) {
|
||||
throw new SleighError("Localtemp size mismatch", null);
|
||||
throw new SleighError(String.format("Localtemp size mismatch: %d vs %d",
|
||||
vn.getSize().getReal(), size.getReal()), op.location);
|
||||
}
|
||||
vn.setSize(size);
|
||||
}
|
||||
|
@ -158,7 +156,8 @@ public abstract class PcodeCompile {
|
|||
if ((size.getType() == ConstTpl.const_type.real) &&
|
||||
(vn.getSize().getType() == ConstTpl.const_type.real) &&
|
||||
(vn.getSize().getReal() != 0) && (vn.getSize().getReal() != size.getReal())) {
|
||||
throw new SleighError("Localtemp size mismatch", null);
|
||||
throw new SleighError(String.format("Input size mismatch: %d vs %d",
|
||||
vn.getSize().getReal(), size.getReal()), op.location);
|
||||
}
|
||||
vn.setSize(size);
|
||||
}
|
||||
|
@ -189,9 +188,8 @@ public abstract class PcodeCompile {
|
|||
public VectorSTL<OpTpl> placeLabel(Location location, LabelSymbol labsym) {
|
||||
entry("placeLabel", location, labsym);
|
||||
if (labsym.isPlaced()) {
|
||||
String errmsg = "Label " + labsym.getName();
|
||||
errmsg += " is placed more than once";
|
||||
reportError(labsym.getLocation(), errmsg);
|
||||
reportError(labsym.getLocation(),
|
||||
String.format("Label '%s' is placed more than once", labsym.getName()));
|
||||
}
|
||||
labsym.setPlaced();
|
||||
VectorSTL<OpTpl> res = new VectorSTL<OpTpl>();
|
||||
|
@ -272,7 +270,7 @@ public abstract class PcodeCompile {
|
|||
tmpvn.getOffset().getReal(), (int) tmpvn.getSize().getReal());
|
||||
addSymbol(sym);
|
||||
if ((!usesLocalKey) && enforceLocalKey) {
|
||||
reportError(location, "Must use 'local' keyword to define symbol: " + varname);
|
||||
reportError(location, "Must use 'local' keyword to define symbol '" + varname + "'");
|
||||
}
|
||||
return ExprTree.toVector(rhs);
|
||||
}
|
||||
|
@ -465,7 +463,8 @@ public abstract class PcodeCompile {
|
|||
return null;
|
||||
}
|
||||
if (byteoffset + numbytes > fullsz) {
|
||||
throw new SleighError("Requested bit range out of bounds", loc);
|
||||
throw new SleighError(String.format("Requested bit range out of bounds -- %d > %d",
|
||||
(byteoffset + numbytes), fullsz), loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,10 +840,12 @@ public abstract class PcodeCompile {
|
|||
}
|
||||
break;
|
||||
case CPUI_CPOOLREF:
|
||||
if (op.getOut().isZeroSize() && (!op.getIn(0).isZeroSize()))
|
||||
if (op.getOut().isZeroSize() && (!op.getIn(0).isZeroSize())) {
|
||||
force_size(op.getOut(),op.getIn(0).getSize(),ops);
|
||||
if (op.getIn(0).isZeroSize() && (!op.getOut().isZeroSize()))
|
||||
}
|
||||
if (op.getIn(0).isZeroSize() && (!op.getOut().isZeroSize())) {
|
||||
force_size(op.getIn(0),op.getOut().getSize(),ops);
|
||||
}
|
||||
for(i=1;i<op.numInput();++i) {
|
||||
force_size(op.getIn(i), new ConstTpl(ConstTpl.const_type.real, 8), ops);
|
||||
}
|
||||
|
@ -891,19 +892,10 @@ public abstract class PcodeCompile {
|
|||
|
||||
public static void entry(String name, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
sb.append("(");
|
||||
int argsSoFar = 0;
|
||||
for (int ii = 0; ii < args.length; ++ii) {
|
||||
if (!isLocationIsh(args[ii])) {
|
||||
if (argsSoFar > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(args[ii]);
|
||||
++argsSoFar;
|
||||
}
|
||||
}
|
||||
sb.append(name).append("(");
|
||||
sb.append(Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", ")));
|
||||
sb.append(")");
|
||||
|
||||
log.trace(sb.toString());
|
||||
}
|
||||
|
||||
|
@ -991,13 +983,15 @@ public abstract class PcodeCompile {
|
|||
return createOpConst(location, OpCode.CPUI_INDIRECT, r.outvn.getOffset().getReal());
|
||||
}
|
||||
if ("cpool".equals(name)) {
|
||||
if (operands.size() >= 2) // At least two parameters
|
||||
if (operands.size() >= 2) { // At least two parameters
|
||||
return createVariadic(location, OpCode.CPUI_CPOOLREF, operands);
|
||||
}
|
||||
reportError(location,name+"() expects at least two arguments");
|
||||
}
|
||||
if ("newobject".equals(name)) {
|
||||
if (operands.size() >= 1) // At least one parameter
|
||||
if (operands.size() >= 1) { // At least one parameter
|
||||
return createVariadic(location, OpCode.CPUI_NEW, operands);
|
||||
}
|
||||
reportError(location,name+"() expects at least one argument");
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.pcodeCPort.slgh_compile;
|
|||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
|
@ -27,6 +28,7 @@ import org.jdom.*;
|
|||
import generic.stl.VectorSTL;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighException;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||
import ghidra.pcode.utils.MessageFormattingUtils;
|
||||
import ghidra.pcodeCPort.address.Address;
|
||||
import ghidra.pcodeCPort.context.SleighError;
|
||||
import ghidra.pcodeCPort.error.LowlevelError;
|
||||
|
@ -171,24 +173,24 @@ public class PcodeParser extends PcodeCompile {
|
|||
|
||||
// Make sure label symbols are used properly
|
||||
private String checkLabels() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
List<String> errors = new ArrayList<>();
|
||||
for (SleighSymbol sym : symbolMap.values()) {
|
||||
if (sym.getType() != symbol_type.label_symbol) {
|
||||
continue;
|
||||
}
|
||||
LabelSymbol labsym = (LabelSymbol) sym;
|
||||
if (labsym.getRefCount() == 0) {
|
||||
s.append(" Label <");
|
||||
s.append(sym.getName());
|
||||
s.append("> was placed but not used");
|
||||
errors.add(MessageFormattingUtils.format(labsym.location,
|
||||
String.format("Label <%s> was placed but never used", sym.getName())));
|
||||
|
||||
}
|
||||
else if (!labsym.isPlaced()) {
|
||||
s.append(" Label <");
|
||||
s.append(sym.getName());
|
||||
s.append("> was referenced but never placed");
|
||||
errors.add(MessageFormattingUtils.format(labsym.location,
|
||||
String.format("Label <%s> was referenced but never placed", sym.getName())));
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
return errors.stream().collect(Collectors.joining(" "));
|
||||
|
||||
}
|
||||
|
||||
private ConstructTpl buildConstructor(ConstructTpl rtl) {
|
||||
|
|
|
@ -20,11 +20,13 @@ import java.io.PrintStream;
|
|||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.jdom.JDOMException;
|
||||
|
||||
import generic.stl.*;
|
||||
import ghidra.pcode.utils.MessageFormattingUtils;
|
||||
import ghidra.pcodeCPort.address.Address;
|
||||
import ghidra.pcodeCPort.context.SleighError;
|
||||
import ghidra.pcodeCPort.error.LowlevelError;
|
||||
|
@ -72,25 +74,21 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
|
||||
public static void entry(String name, Object... args) {
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// sb.append(name);
|
||||
// sb.append("(");
|
||||
// int argsSoFar = 0;
|
||||
// for (int ii = 0; ii < args.length; ++ii) {
|
||||
// if (!isLocationIsh(args[ii])) {
|
||||
// if (argsSoFar > 0) {
|
||||
// sb.append(", ");
|
||||
// }
|
||||
// sb.append(args[ii]);
|
||||
// ++argsSoFar;
|
||||
// }
|
||||
// }
|
||||
// sb.append(")");
|
||||
// Msg.trace(SleighCompile.class, sb.toString());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name).append("(");
|
||||
// @formatter:off
|
||||
sb.append(Arrays.stream(args)
|
||||
.filter(a -> isLocationIsh(a))
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.joining(", ")));
|
||||
// @formatter:on
|
||||
sb.append(")");
|
||||
Msg.trace(SleighCompile.class, sb.toString());
|
||||
}
|
||||
|
||||
// Semantic pcode compiler
|
||||
public final PcodeCompile pcode = new PcodeCompile() {
|
||||
|
||||
@Override
|
||||
public void reportError(Location location, String msg) {
|
||||
SleighCompile.this.reportError(location, msg);
|
||||
|
@ -382,8 +380,10 @@ public class SleighCompile extends SleighBase {
|
|||
|
||||
final int symSize = sym.getSize();
|
||||
if (symSize % 4 != 0) {
|
||||
reportError(sym.location, "Invalid size of context register \"" + sym.getName() +
|
||||
"\" (" + symSize + "); must be a multiple of 4");
|
||||
reportError(sym.location,
|
||||
String.format(
|
||||
"Invalid size of context register '%s' (%d); must be a multiple of 4",
|
||||
sym.getName(), symSize));
|
||||
}
|
||||
final int maxBits = symSize * 8 - 1;
|
||||
|
||||
|
@ -395,13 +395,15 @@ public class SleighCompile extends SleighBase {
|
|||
int max = qual.high;
|
||||
if (max - min > (8 * 4)) {
|
||||
reportError(qual.location,
|
||||
"Size of bitfield " + qual.name + "=(" + min + "," + max + ") larger than " +
|
||||
(8 * 4) + " bits in context register \"" + sym.getName() + "\"");
|
||||
String.format(
|
||||
"Size of bitfield %s=(%d,%d) larger than %d bits in context register '%s'",
|
||||
qual.name, min, (8 * 4), sym.getName()));
|
||||
|
||||
}
|
||||
if (max > maxBits) {
|
||||
reportError(qual.location,
|
||||
"Scope of bitfield " + qual.name + "=(" + min + "," + max +
|
||||
") extends beyond the size of context register \"" + sym.getName() + "\"");
|
||||
reportError(qual.location, String.format(
|
||||
"Scope of bitfield %s=(%d,%d) extends beyond the size of context register '%s' (%d)",
|
||||
qual.name, min, max, sym.getName(), maxBits));
|
||||
}
|
||||
|
||||
j = i + 1;
|
||||
|
@ -489,7 +491,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
if (tables.get(i).getPattern() == null) {
|
||||
reportWarning(tables.get(i).getLocation(),
|
||||
"Unreferenced table: " + tables.get(i).getName());
|
||||
"Unreferenced table: '" + tables.get(i).getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,9 +510,9 @@ public class SleighCompile extends SleighBase {
|
|||
return;
|
||||
}
|
||||
if ((!warnunnecessarypcode) && (checker.getNumUnnecessaryPcode() > 0)) {
|
||||
Msg.warn(this, checker.getNumUnnecessaryPcode() +
|
||||
reportWarning(null, checker.getNumUnnecessaryPcode() +
|
||||
" unnecessary extensions/truncations were converted to copies");
|
||||
Msg.warn(this, "Use -u switch to list each individually");
|
||||
reportWarning(null, "Use -u switch to list each individually");
|
||||
}
|
||||
checker.optimizeAll();
|
||||
if (checker.getNumReadNoWrite() > 0) {
|
||||
|
@ -518,9 +520,9 @@ public class SleighCompile extends SleighBase {
|
|||
return;
|
||||
}
|
||||
if ((!warndeadtemps) && (checker.getNumWriteNoRead() > 0)) {
|
||||
Msg.warn(this, checker.getNumWriteNoRead() +
|
||||
reportWarning(null, checker.getNumWriteNoRead() +
|
||||
" operations wrote to temporaries that were not read");
|
||||
Msg.warn(this, "Use -t switch to list each individually");
|
||||
reportWarning(null, "Use -t switch to list each individually");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,10 +562,11 @@ public class SleighCompile extends SleighBase {
|
|||
if (collideOperand >= 0) {
|
||||
noCollisions = false;
|
||||
if (warnalllocalcollisions) {
|
||||
Msg.warn(this, "Possible collision with symbol " +
|
||||
ct.getOperand(collideOperand).getName() + " and " +
|
||||
ct.getOperand(i).getName() + " in constructor from " + ct.getFilename() +
|
||||
" starting at line " + Integer.toString(ct.getLineno()));
|
||||
reportWarning(ct.location,
|
||||
String.format(
|
||||
"Possible operand collision between symbols '%s' and '%s'",
|
||||
ct.getOperand(collideOperand).getName(), ct.getOperand(i).getName()));
|
||||
|
||||
}
|
||||
break; // Don't continue
|
||||
}
|
||||
|
@ -589,10 +592,10 @@ public class SleighCompile extends SleighBase {
|
|||
sym = tables.get(i);
|
||||
}
|
||||
if (collisionCount > 0) {
|
||||
Msg.warn(this, "WARNING: " + Integer.toString(collisionCount) +
|
||||
" constructors with local collisions between operands");
|
||||
reportWarning(null,
|
||||
collisionCount + " constructors with local collisions between operands");
|
||||
if (!warnalllocalcollisions) {
|
||||
Msg.warn(this, "Use -c switch to list each individually");
|
||||
reportWarning(null, "Use -c switch to list each individually");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -600,7 +603,7 @@ public class SleighCompile extends SleighBase {
|
|||
// Make sure label symbols are used properly
|
||||
String checkSymbols(SymbolScope scope) {
|
||||
entry("checkSymbols", scope);
|
||||
StringBuilder s = new StringBuilder();
|
||||
List<String> errors = new ArrayList<>();
|
||||
IteratorSTL<SleighSymbol> iter;
|
||||
for (iter = scope.begin(); !iter.equals(scope.end()); iter.increment()) {
|
||||
SleighSymbol sym = iter.get();
|
||||
|
@ -609,17 +612,15 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
LabelSymbol labsym = (LabelSymbol) sym;
|
||||
if (labsym.getRefCount() == 0) {
|
||||
s.append(" Label <");
|
||||
s.append(sym.getName());
|
||||
s.append("> was placed but not used");
|
||||
errors.add(MessageFormattingUtils.format(labsym.location,
|
||||
String.format("Label <%s> was placed but never used", sym.getName())));
|
||||
}
|
||||
else if (!labsym.isPlaced()) {
|
||||
s.append(" Label <");
|
||||
s.append(sym.getName());
|
||||
s.append("> was referenced but never placed");
|
||||
errors.add(MessageFormattingUtils.format(labsym.location,
|
||||
String.format("Label <%s> was referenced but never placed", sym.getName())));
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
return errors.stream().collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
// Make sure symbol table errors are caught
|
||||
|
@ -648,25 +649,28 @@ public class SleighCompile extends SleighBase {
|
|||
pcode.resetLabelCount();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reportError(Location location, String msg) {
|
||||
entry("reportError", location, msg);
|
||||
if (location == null) {
|
||||
Msg.error(this, msg);
|
||||
}
|
||||
else {
|
||||
Msg.error(this, location + ": " + msg);
|
||||
}
|
||||
super.reportError(location, msg);
|
||||
|
||||
errors += 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportError(Location location, String msg, Throwable t) {
|
||||
entry("reportError", location, msg);
|
||||
super.reportError(location, msg, t);
|
||||
|
||||
errors += 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportWarning(Location location, String msg) {
|
||||
entry("reportWarning", location, msg);
|
||||
if (location == null) {
|
||||
Msg.warn(this, msg);
|
||||
}
|
||||
else {
|
||||
Msg.warn(this, location + ": " + msg);
|
||||
}
|
||||
super.reportWarning(location, msg);
|
||||
|
||||
warnings += 1;
|
||||
}
|
||||
|
||||
|
@ -757,7 +761,7 @@ public class SleighCompile extends SleighBase {
|
|||
buildXrefs(); // Make sure we can build crossrefs properly
|
||||
}
|
||||
catch (SleighError err) {
|
||||
Msg.error(this, err.getMessage(), err);
|
||||
Msg.error(this, err.location + ": " + err.getMessage(), err);
|
||||
errors += 1;
|
||||
return;
|
||||
}
|
||||
|
@ -837,7 +841,8 @@ public class SleighCompile extends SleighBase {
|
|||
entry("defineToken", location, name, sz);
|
||||
int size = (int) sz;
|
||||
if ((size & 7) != 0) {
|
||||
reportError(location, name + "token size must be multiple of 8");
|
||||
reportError(location,
|
||||
"Definition of '" + name + "' token -- size must be multiple of 8");
|
||||
size = (size / 8) + 1;
|
||||
}
|
||||
else {
|
||||
|
@ -879,21 +884,24 @@ public class SleighCompile extends SleighBase {
|
|||
public void newSpace(Location location, SpaceQuality qual) {
|
||||
entry("newSpace", location, qual);
|
||||
if (qual.size == 0) {
|
||||
reportError(location, "Space definition missing size attribute");
|
||||
reportError(location, "Space definition '" + qual.name + "' missing size attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
if (qual.size <= 0 || qual.size > 8) {
|
||||
throw new SleighError("Space " + qual.name + " has unsupported size: " + 16, location);
|
||||
throw new SleighError("Space '" + qual.name + "' has unsupported size: " + qual.size,
|
||||
location);
|
||||
}
|
||||
if (qual.wordsize < 1 || qual.wordsize > 8) {
|
||||
throw new SleighError(
|
||||
"Space " + qual.name + " has unsupported wordsize: " + qual.wordsize, location);
|
||||
"Space '" + qual.name + "' has unsupported wordsize: " + qual.wordsize, location);
|
||||
}
|
||||
int addressBits = bitsConsumedByUnitSize(qual.wordsize) + (8 * qual.size);
|
||||
if (addressBits > 64) {
|
||||
throw new SleighError("Space " + qual.name + " has unsupported dimensions, requires " +
|
||||
addressBits + "-bits (limit is 64-bits)", location);
|
||||
throw new SleighError(
|
||||
"Space '" + qual.name + "' has unsupported dimensions: requires " + addressBits +
|
||||
" bits -- limit is 64 bits",
|
||||
location);
|
||||
}
|
||||
|
||||
int delay = (qual.type == space_class.register_space) ? 0 : 1;
|
||||
|
@ -902,7 +910,9 @@ public class SleighCompile extends SleighBase {
|
|||
insertSpace(spc);
|
||||
if (qual.isdefault) {
|
||||
if (getDefaultSpace() != null) {
|
||||
reportError(location, "Multiple default spaces");
|
||||
reportError(location,
|
||||
"Multiple default spaces -- '" + getDefaultSpace().getName() + "', '" +
|
||||
qual.name + "'");
|
||||
}
|
||||
else {
|
||||
setDefaultSpace(spc.getIndex()); // Make the flagged space
|
||||
|
@ -949,11 +959,11 @@ public class SleighCompile extends SleighBase {
|
|||
String namecopy = name;
|
||||
int size = 8 * sym.getSize(); // Number of bits
|
||||
if (numb == 0) {
|
||||
reportError(location, "Size of bitrange is zero for: " + namecopy);
|
||||
reportError(location, "Size of bitrange is zero for '" + namecopy + "'");
|
||||
return;
|
||||
}
|
||||
if ((bitoffset >= size) || ((bitoffset + numb) > size)) {
|
||||
reportError(location, "Bad bitrange for: " + namecopy);
|
||||
reportError(location, "Bad bitrange for '" + namecopy + "'");
|
||||
return;
|
||||
}
|
||||
if ((bitoffset % 8 == 0) && (numb % 8 == 0)) {
|
||||
|
@ -971,8 +981,8 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
else {
|
||||
if (size > 64) {
|
||||
reportError(location,
|
||||
"Illegal bitrange on varnode larger than 64 bits: " + sym.getName());
|
||||
reportError(location, "'" + sym.getName() + "': " +
|
||||
"Illegal bitrange on varnode larger than 64 bits");
|
||||
}
|
||||
// Otherwise define the special symbol
|
||||
addSymbol(new BitrangeSymbol(location, namecopy, sym, bitoffset, numb));
|
||||
|
@ -984,8 +994,8 @@ public class SleighCompile extends SleighBase {
|
|||
for (int i = 0; i < names.size(); ++i) {
|
||||
boolean isInternal = pcode.isInternalFunction(names.get(i));
|
||||
if (isInternal) {
|
||||
reportError(locations.get(i),
|
||||
names.get(i) + " is an internal pcodeop and cannot be redefined as a pseudoop");
|
||||
reportError(locations.get(i), "'" + names.get(i) +
|
||||
"' is an internal pcodeop and cannot be redefined as a pseudoop");
|
||||
}
|
||||
UserOpSymbol sym = new UserOpSymbol(locations.get(i), names.get(i));
|
||||
sym.setIndex(userop_count++);
|
||||
|
@ -1020,7 +1030,7 @@ public class SleighCompile extends SleighBase {
|
|||
SleighSymbol dupsym = dedupSymbolList(symlist);
|
||||
if (dupsym != null) {
|
||||
reportWarning(dupsym.location,
|
||||
"\"attach values\" list contains duplicate entries: " + dupsym.getName());
|
||||
"'attach values' list contains duplicate entries: " + dupsym.getName());
|
||||
}
|
||||
for (int i = 0; i < symlist.size(); ++i) {
|
||||
Location location = locations.get(i);
|
||||
|
@ -1030,7 +1040,8 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
PatternValue patval = sym.getPatternValue();
|
||||
if (patval.maxValue() + 1 != numlist.size()) {
|
||||
reportError(location, "Attach value " + sym + " is wrong size for list " + numlist);
|
||||
reportError(location,
|
||||
"Attach value '" + sym + "' is wrong size for list: " + numlist);
|
||||
}
|
||||
symtab.replaceSymbol(sym, new ValueMapSymbol(location, sym.getName(), patval, numlist));
|
||||
}
|
||||
|
@ -1042,7 +1053,7 @@ public class SleighCompile extends SleighBase {
|
|||
SleighSymbol dupsym = dedupSymbolList(symlist);
|
||||
if (dupsym != null) {
|
||||
reportWarning(dupsym.location,
|
||||
"\"attach names\" list contains duplicate entries: " + dupsym.getName());
|
||||
"'attach names' list contains duplicate entries: " + dupsym.getName());
|
||||
}
|
||||
for (int i = 0; i < symlist.size(); ++i) {
|
||||
Location location = locations.get(i);
|
||||
|
@ -1052,7 +1063,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
PatternValue patval = sym.getPatternValue();
|
||||
if (patval.maxValue() + 1 != names.size()) {
|
||||
reportError(location, "Attach name " + sym + " is wrong size for list " + names);
|
||||
reportError(location, "Attach name '" + sym + "' is wrong size for list: " + names);
|
||||
}
|
||||
symtab.replaceSymbol(sym, new NameSymbol(location, sym.getName(), patval, names));
|
||||
}
|
||||
|
@ -1064,7 +1075,7 @@ public class SleighCompile extends SleighBase {
|
|||
SleighSymbol dupsym = dedupSymbolList(symlist);
|
||||
if (dupsym != null) {
|
||||
reportWarning(dupsym.location,
|
||||
"\"attach variables\" list contains duplicate entries: " + dupsym.getName());
|
||||
"'attach variables' list contains duplicate entries: " + dupsym.getName());
|
||||
}
|
||||
for (int i = 0; i < symlist.size(); ++i) {
|
||||
Location location = locations.get(i);
|
||||
|
@ -1073,7 +1084,7 @@ public class SleighCompile extends SleighBase {
|
|||
continue;
|
||||
}
|
||||
if (firstContextField != null && sym.getId() == firstContextField) {
|
||||
reportError(location, sym.getName() +
|
||||
reportError(location, "'" + sym.getName() + "'" +
|
||||
" cannot be used to attach variables because it occurs at the lowest bit position in context at " +
|
||||
sym.getLocation());
|
||||
continue;
|
||||
|
@ -1081,7 +1092,7 @@ public class SleighCompile extends SleighBase {
|
|||
PatternValue patval = sym.getPatternValue();
|
||||
if (patval.maxValue() + 1 != varlist.size()) {
|
||||
reportError(location,
|
||||
"Attach varnode " + sym + " is wrong size for list " + varlist);
|
||||
"Attach varnode '" + sym + "' is wrong size for list: " + varlist);
|
||||
}
|
||||
int sz = 0;
|
||||
for (int j = 0; j < varlist.size(); ++j) {
|
||||
|
@ -1183,7 +1194,7 @@ public class SleighCompile extends SleighBase {
|
|||
entry("selfDefine", sym);
|
||||
SleighSymbol sleighSymbol = symtab.findSymbol(sym.getName(), 1);
|
||||
if (!(sleighSymbol instanceof TripleSymbol)) {
|
||||
reportError(sym.getLocation(), sym.getName() + ": No matching global symbol");
|
||||
reportError(sym.getLocation(), "No matching global symbol '" + sym.getName() + "'");
|
||||
return;
|
||||
}
|
||||
TripleSymbol glob = (TripleSymbol) sleighSymbol;
|
||||
|
@ -1280,14 +1291,10 @@ public class SleighCompile extends SleighBase {
|
|||
VectorSTL<ExprTree> param) {
|
||||
entry("createMacroUse", location, sym, param);
|
||||
if (sym.getNumOperands() != param.size()) {
|
||||
String errmsg = "Invocation of macro \"" + sym.getName();
|
||||
if (param.size() > sym.getNumOperands()) {
|
||||
errmsg += "\" passes too many parameters";
|
||||
}
|
||||
else {
|
||||
errmsg += "\" passes too few parameters";
|
||||
}
|
||||
reportError(sym.getLocation(), errmsg);
|
||||
boolean tooManyParams = param.size() > sym.getNumOperands();
|
||||
reportError(sym.getLocation(), String.format("Invocation of macro '%s' passes too " +
|
||||
(tooManyParams ? "many" : "few") + " parameters", sym.getName()));
|
||||
|
||||
return new VectorSTL<>();
|
||||
}
|
||||
compareMacroParams(sym, param);
|
||||
|
@ -1416,28 +1423,34 @@ public class SleighCompile extends SleighBase {
|
|||
String sectionstring = " Main section: ";
|
||||
int max = vec.getMaxId();
|
||||
for (;;) {
|
||||
|
||||
String scopeString = cur.section.loc + ": " + sectionstring;
|
||||
|
||||
String errstring;
|
||||
|
||||
errstring = checkSymbols(cur.scope); // Check labels in the section's scope
|
||||
if (errstring.length() == 0) {
|
||||
if (errstring.length() != 0) {
|
||||
myErrors.push_back(scopeString + errstring);
|
||||
}
|
||||
else {
|
||||
if (!expandMacros(cur.section)) {
|
||||
myErrors.push_back(sectionstring + "Could not expand macros");
|
||||
myErrors.push_back(scopeString + "Could not expand macros");
|
||||
}
|
||||
VectorSTL<Integer> check = new VectorSTL<>();
|
||||
big.markSubtableOperands(check);
|
||||
Pair<Integer, Location> res = cur.section.fillinBuild(check, getConstantSpace());
|
||||
if (res.first == 1) {
|
||||
myErrors.push_back(
|
||||
sectionstring + "Duplicate BUILD statements at " + res.second);
|
||||
scopeString + "Duplicate BUILD statements at " + res.second);
|
||||
}
|
||||
if (res.first == 2) {
|
||||
myErrors.push_back(
|
||||
sectionstring + "Unnecessary BUILD statements at " + res.second);
|
||||
scopeString + "Unnecessary BUILD statements at " + res.second);
|
||||
}
|
||||
|
||||
if (!pcode.propagateSize(cur.section)) {
|
||||
myErrors.push_back(
|
||||
sectionstring + "Could not resolve at least 1 variable size");
|
||||
scopeString + "Could not resolve at least 1 variable size");
|
||||
}
|
||||
}
|
||||
if (i < 0) { // These potential errors only apply to main section
|
||||
|
@ -1452,7 +1465,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
if (cur.section.delaySlot() != 0) { // Delay slot is present in this constructor
|
||||
if (root != big.getParent()) { // it is not in a root constructor
|
||||
reportWarning(null, "Delay slot used in " + big);
|
||||
reportWarning(big.location, "Delay slot used in " + big);
|
||||
}
|
||||
if (cur.section.delaySlot() > maxdelayslotbytes) {
|
||||
maxdelayslotbytes = cur.section.delaySlot();
|
||||
|
@ -1476,7 +1489,7 @@ public class SleighCompile extends SleighBase {
|
|||
if (!myErrors.empty()) {
|
||||
reportError(big.location, "in " + big);
|
||||
for (int j = 0; j < myErrors.size(); ++j) {
|
||||
reportError(null, myErrors.get(j));
|
||||
reportError(big.location, myErrors.get(j));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1594,8 +1607,8 @@ public class SleighCompile extends SleighBase {
|
|||
PatternValue patternValue = valueSymbol.getPatternValue();
|
||||
if (patternValue instanceof TokenField) {
|
||||
if (sleighSymbol.location != Location.INTERNALLY_DEFINED) {
|
||||
reportWarning(patternValue.location, "token field " +
|
||||
sleighSymbol.getName() + " defined but never used");
|
||||
reportWarning(patternValue.location, "token field '" +
|
||||
sleighSymbol.getName() + "' defined but never used");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1648,12 +1661,12 @@ public class SleighCompile extends SleighBase {
|
|||
String errstring = checkSymbols(symtab.getCurrentScope());
|
||||
if (errstring.length() != 0) {
|
||||
reportError(sym.getLocation(),
|
||||
" in definition of macro " + sym.getName() + ":" + errstring);
|
||||
"Error in definition of macro '" + sym.getName() + "': " + errstring);
|
||||
return;
|
||||
}
|
||||
if (!expandMacros(rtl)) {
|
||||
reportError(sym.getLocation(),
|
||||
"Could not expand submacro in definition of macro " + sym.getName());
|
||||
"Could not expand submacro in definition of macro '" + sym.getName() + "'");
|
||||
return;
|
||||
}
|
||||
pcode.propagateSize(rtl); // Propagate size information (as much as possible)
|
||||
|
|
|
@ -118,7 +118,8 @@ public class TokenPattern {
|
|||
setLeftEllipsis(true);
|
||||
}
|
||||
else if (tok1.toklist.size() != minsize) {
|
||||
throw new SleighError("Mismatched pattern sizes", location);
|
||||
throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
|
||||
tok1.toklist.size(), minsize), location);
|
||||
}
|
||||
else if (tok1.toklist.size() == tok2.toklist.size()) {
|
||||
throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
|
||||
|
@ -132,7 +133,8 @@ public class TokenPattern {
|
|||
setRightEllipsis(true);
|
||||
}
|
||||
else if (tok1.toklist.size() != minsize) {
|
||||
throw new SleighError("Mismatched pattern sizes", location);
|
||||
throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
|
||||
tok1.toklist.size(), minsize), location);
|
||||
}
|
||||
else if (tok1.toklist.size() == tok2.toklist.size()) {
|
||||
throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
|
||||
|
@ -142,7 +144,8 @@ public class TokenPattern {
|
|||
if (tok2.getLeftEllipsis()) {
|
||||
reversedirection = true;
|
||||
if (tok2.toklist.size() != minsize) {
|
||||
throw new SleighError("Mismatched pattern sizes", location);
|
||||
throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
|
||||
tok2.toklist.size(), minsize), location);
|
||||
}
|
||||
else if (tok1.toklist.size() == tok2.toklist.size()) {
|
||||
throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
|
||||
|
@ -150,7 +153,8 @@ public class TokenPattern {
|
|||
}
|
||||
else if (tok2.getRightEllipsis()) {
|
||||
if (tok2.toklist.size() != minsize) {
|
||||
throw new SleighError("Mismatched pattern sizes", location);
|
||||
throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
|
||||
tok1.toklist.size(), minsize), location);
|
||||
}
|
||||
else if (tok1.toklist.size() == tok2.toklist.size()) {
|
||||
throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
|
||||
|
@ -158,7 +162,8 @@ public class TokenPattern {
|
|||
}
|
||||
else {
|
||||
if (tok2.toklist.size() != tok1.toklist.size()) {
|
||||
throw new SleighError("Mismatched pattern sizes", location);
|
||||
throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
|
||||
tok2.toklist.size(), tok1.toklist.size()), location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.pcodeCPort.slghsymbol;
|
||||
|
||||
import generic.stl.VectorSTL;
|
||||
import ghidra.pcode.utils.MessageFormattingUtils;
|
||||
import ghidra.pcodeCPort.slghpattern.DisjointPattern;
|
||||
|
||||
public class DecisionProperties {
|
||||
|
@ -35,7 +36,10 @@ public class DecisionProperties {
|
|||
if ((!a.isError()) && (!b.isError())) {
|
||||
a.setError(true);
|
||||
b.setError(true);
|
||||
identerrors.push_back("Constructors with identical patterns: \n " + a + "\n " + b);
|
||||
|
||||
String msg = "Constructors with identical patterns:\n " + a + "\n " + b;
|
||||
identerrors.push_back(MessageFormattingUtils.format(a.location, msg));
|
||||
identerrors.push_back(MessageFormattingUtils.format(b.location, msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,9 +49,12 @@ public class DecisionProperties {
|
|||
if ((!a.isError()) && (!b.isError())) {
|
||||
a.setError(true);
|
||||
b.setError(true);
|
||||
conflicterrors.push_back("Constructor patterns cannot be distinguished: \n" //
|
||||
|
||||
String msg = "Constructor patterns cannot be distinguished: \n" //
|
||||
+ " " + pa + " " + a + "\n" //
|
||||
+ " " + pb + " " + b);
|
||||
+ " " + pb + " " + b;
|
||||
conflicterrors.push_back(MessageFormattingUtils.format(a.location, msg));
|
||||
conflicterrors.push_back(MessageFormattingUtils.format(b.location, msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,8 @@ public class SubtableSymbol extends TripleSymbol {
|
|||
|
||||
private TokenPattern pattern;
|
||||
private boolean beingbuilt, errors;
|
||||
private VectorSTL<Constructor> construct = new VectorSTL<Constructor>(); // All
|
||||
// the
|
||||
// Constructors in
|
||||
// this table
|
||||
// All the Constructors in this table
|
||||
private VectorSTL<Constructor> construct = new VectorSTL<Constructor>();
|
||||
private DecisionNode decisiontree;
|
||||
|
||||
public SubtableSymbol(Location location) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue