mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-927_SleighCaseSensitiveRegisters' into Ghidra_10.0
This commit is contained in:
commit
43a9499e39
14 changed files with 1607 additions and 808 deletions
|
@ -41,7 +41,7 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
|
|||
public static final int SLA_FORMAT_VERSION = 3;
|
||||
|
||||
public static final long MAX_UNIQUE_SIZE = 128; //Maximum size of a varnode in the unique space.
|
||||
//Should match value in sleighbase.cc
|
||||
//Should match value in sleighbase.cc
|
||||
|
||||
private VectorSTL<String> userop = new VectorSTL<>();
|
||||
private address_set varnode_xref = new address_set(); // Cross-reference registers by address
|
||||
|
@ -127,12 +127,6 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegister(String nm, AddrSpace base, long offset, int size) {
|
||||
VarnodeSymbol sym = new VarnodeSymbol(null, nm, base, offset, size);
|
||||
symtab.addSymbol(sym);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VarnodeData getRegister(String nm) {
|
||||
VarnodeSymbol sym = (VarnodeSymbol) findSymbol(nm);
|
||||
|
|
|
@ -29,24 +29,22 @@ import ghidra.pcodeCPort.space.AddrSpace;
|
|||
|
||||
class ConsistencyChecker {
|
||||
|
||||
int unnecessarypcode;
|
||||
int readnowrite;
|
||||
int writenoread;
|
||||
// number of constructors using a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
int largetemp;
|
||||
boolean printextwarning;
|
||||
boolean printdeadwarning;
|
||||
//if true, print information about constructors using temporary varnodes larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
boolean printlargetempwarning;
|
||||
SleighCompile compiler;
|
||||
SubtableSymbol root_symbol;
|
||||
VectorSTL<SubtableSymbol> postorder = new VectorSTL<>();
|
||||
private int unnecessarypcode;
|
||||
private int readnowrite;
|
||||
private int writenoread;
|
||||
|
||||
private int largetemp; // number of constructors using a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
private boolean printextwarning;
|
||||
private boolean printdeadwarning;
|
||||
private boolean printlargetempwarning; // if true, warning about temporary varnodes larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
private SleighCompile compiler;
|
||||
private SubtableSymbol root_symbol;
|
||||
private VectorSTL<SubtableSymbol> postorder = new VectorSTL<>();
|
||||
|
||||
// Sizes associated with tables
|
||||
MapSTL<SubtableSymbol, Integer> sizemap =
|
||||
new MapSTL<>((s1, s2) -> s1.compareTo(s2));
|
||||
private MapSTL<SubtableSymbol, Integer> sizemap = new MapSTL<>((s1, s2) -> s1.compareTo(s2));
|
||||
|
||||
OperandSymbol getOperandSymbol(int slot, OpTpl op, Constructor ct) {
|
||||
private OperandSymbol getOperandSymbol(int slot, OpTpl op, Constructor ct) {
|
||||
VarnodeTpl vn;
|
||||
OperandSymbol opsym = null;
|
||||
int handindex;
|
||||
|
@ -69,9 +67,8 @@ class ConsistencyChecker {
|
|||
return opsym;
|
||||
}
|
||||
|
||||
boolean sizeRestriction(OpTpl op, Constructor ct)
|
||||
|
||||
{ // Make sure op template meets size restrictions
|
||||
private boolean sizeRestriction(OpTpl op, Constructor ct) {
|
||||
// Make sure op template meets size restrictions
|
||||
// Return false and any info about mismatched sizes
|
||||
int vnout, vn0, vn1;
|
||||
AddrSpace spc;
|
||||
|
@ -103,7 +100,7 @@ class ConsistencyChecker {
|
|||
return true;
|
||||
}
|
||||
printOpError(op, ct, -1, 0, "Input and output sizes must match; " +
|
||||
op.getIn(0).getSize() + " != " + op.getOut().getSize());
|
||||
op.getIn(0).getSize() + " != " + op.getOut().getSize());
|
||||
return false;
|
||||
case CPUI_INT_ADD:
|
||||
case CPUI_INT_SUB:
|
||||
|
@ -240,8 +237,8 @@ class ConsistencyChecker {
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
// The shift amount does not necessarily have to be the same size
|
||||
// But the output and first parameter must be same size
|
||||
// The shift amount does not necessarily have to be the same size
|
||||
// But the output and first parameter must be same size
|
||||
case CPUI_INT_LEFT:
|
||||
case CPUI_INT_RIGHT:
|
||||
case CPUI_INT_SRIGHT:
|
||||
|
@ -284,7 +281,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
else if (vnout < vn0) {
|
||||
printOpError(op, ct, -1, 0,
|
||||
"Output size must be strictly bigger than input size");
|
||||
"Output size must be strictly bigger than input size");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -349,7 +346,7 @@ class ConsistencyChecker {
|
|||
return true;
|
||||
}
|
||||
|
||||
String getOpName(OpTpl op) {
|
||||
private String getOpName(OpTpl op) {
|
||||
switch (op.getOpcode()) {
|
||||
case CPUI_COPY:
|
||||
return "Copy(=)";
|
||||
|
@ -484,7 +481,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
}
|
||||
|
||||
void printOpError(OpTpl op, Constructor ct, int err1, int err2, String message) {
|
||||
private void printOpError(OpTpl op, Constructor ct, int err1, int err2, String message) {
|
||||
SubtableSymbol sym = ct.getParent();
|
||||
OperandSymbol op1, op2;
|
||||
|
||||
|
@ -498,10 +495,10 @@ class ConsistencyChecker {
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Size restriction error in table '")
|
||||
.append(sym.getName())
|
||||
.append("' in constructor at ").append(ct.location)
|
||||
.append("\n");
|
||||
|
||||
.append(sym.getName())
|
||||
.append("' in constructor at ")
|
||||
.append(ct.location)
|
||||
.append("\n");
|
||||
|
||||
sb.append(" Problem");
|
||||
if ((op1 != null) && (op2 != null)) {
|
||||
|
@ -521,7 +518,7 @@ class ConsistencyChecker {
|
|||
|
||||
}
|
||||
|
||||
int recoverSize(ConstTpl sizeconst, Constructor ct) {
|
||||
private int recoverSize(ConstTpl sizeconst, Constructor ct) {
|
||||
int size = 0, handindex;
|
||||
OperandSymbol opsym;
|
||||
SubtableSymbol tabsym;
|
||||
|
@ -572,7 +569,7 @@ class ConsistencyChecker {
|
|||
"\" (or did you mean to use signed comparison?)", ct);
|
||||
}
|
||||
|
||||
boolean checkOpMisuse(OpTpl op, Constructor ct) {
|
||||
private boolean checkOpMisuse(OpTpl op, Constructor ct) {
|
||||
switch (op.getOpcode()) {
|
||||
case CPUI_INT_LESS: {
|
||||
VarnodeTpl vn0 = op.getIn(0);
|
||||
|
@ -594,7 +591,7 @@ class ConsistencyChecker {
|
|||
handleBetter("!= 0", ct);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case CPUI_INT_LESSEQUAL: {
|
||||
VarnodeTpl vn0 = op.getIn(0);
|
||||
VarnodeTpl vn1 = op.getIn(1);
|
||||
|
@ -615,14 +612,14 @@ class ConsistencyChecker {
|
|||
handleBetter("== 0", ct);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean checkConstructorSection(Constructor ct, ConstructTpl cttpl) {
|
||||
private boolean checkConstructorSection(Constructor ct, ConstructTpl cttpl) {
|
||||
// Check all the OpTpl s within the given section for consistency, return true if all tests pass
|
||||
if (cttpl == null) {
|
||||
return true; // Nothing to check
|
||||
|
@ -649,7 +646,7 @@ class ConsistencyChecker {
|
|||
* @param opTpl the op to check
|
||||
* @return true if {@code opTpl} uses a large temporary varnode
|
||||
*/
|
||||
boolean hasLargeTemporary(OpTpl opTpl) {
|
||||
private boolean hasLargeTemporary(OpTpl opTpl) {
|
||||
VarnodeTpl out = opTpl.getOut();
|
||||
if (out != null && isTemporaryAndTooBig(out)) {
|
||||
return true;
|
||||
|
@ -659,7 +656,7 @@ class ConsistencyChecker {
|
|||
if (isTemporaryAndTooBig(in)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -669,12 +666,12 @@ class ConsistencyChecker {
|
|||
* @param vn varnode template to check
|
||||
* @return true if it uses a large temporary
|
||||
*/
|
||||
boolean isTemporaryAndTooBig(VarnodeTpl vn) {
|
||||
return vn.getSpace().isUniqueSpace() &&
|
||||
vn.getSize().getReal() > SleighBase.MAX_UNIQUE_SIZE;
|
||||
private boolean isTemporaryAndTooBig(VarnodeTpl vn) {
|
||||
return vn.getSpace().isUniqueSpace() && vn.getSize().getReal() > SleighBase.MAX_UNIQUE_SIZE;
|
||||
}
|
||||
|
||||
boolean checkVarnodeTruncation(Constructor ct,int slot,OpTpl op,VarnodeTpl vn,boolean isbigendian) {
|
||||
private boolean checkVarnodeTruncation(Constructor ct, int slot, OpTpl op, VarnodeTpl vn,
|
||||
boolean isbigendian) {
|
||||
ConstTpl off = vn.getOffset();
|
||||
if (off.getType() != const_type.handle) {
|
||||
return true;
|
||||
|
@ -683,24 +680,25 @@ class ConsistencyChecker {
|
|||
return true;
|
||||
}
|
||||
const_type sztype = vn.getSize().getType();
|
||||
if ((sztype != const_type.real)&&(sztype != const_type.handle)){
|
||||
printOpError(op,ct,slot,slot,"Bad truncation expression");
|
||||
if ((sztype != const_type.real) && (sztype != const_type.handle)) {
|
||||
printOpError(op, ct, slot, slot, "Bad truncation expression");
|
||||
return false;
|
||||
}
|
||||
int sz = recoverSize(off,ct); // Recover the size of the original operand
|
||||
int sz = recoverSize(off, ct); // Recover the size of the original operand
|
||||
if (sz <= 0) {
|
||||
printOpError(op,ct,slot,slot,"Could not recover size");
|
||||
printOpError(op, ct, slot, slot, "Could not recover size");
|
||||
return false;
|
||||
}
|
||||
boolean res = vn.adjustTruncation(sz, isbigendian);
|
||||
if (!res) {
|
||||
printOpError(op,ct,slot,slot,"Truncation operator out of bounds");
|
||||
printOpError(op, ct, slot, slot, "Truncation operator out of bounds");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean checkSectionTruncations(Constructor ct,ConstructTpl cttpl,boolean isbigendian) {
|
||||
private boolean checkSectionTruncations(Constructor ct, ConstructTpl cttpl,
|
||||
boolean isbigendian) {
|
||||
// Check all the varnodes that have an offset_plus template
|
||||
// adjust the plus if we are big endian
|
||||
// make sure the truncation is valid
|
||||
|
@ -709,16 +707,16 @@ class ConsistencyChecker {
|
|||
Iterator<OpTpl> iter;
|
||||
|
||||
iter = ops.iterator();
|
||||
while(iter.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
OpTpl op = iter.next();
|
||||
VarnodeTpl outvn = op.getOut();
|
||||
if (outvn != null) {
|
||||
if (!checkVarnodeTruncation(ct,-1,op,outvn,isbigendian)) {
|
||||
if (!checkVarnodeTruncation(ct, -1, op, outvn, isbigendian)) {
|
||||
testresult = false;
|
||||
}
|
||||
}
|
||||
for(int i=0;i<op.numInput();++i) {
|
||||
if (!checkVarnodeTruncation(ct,i,op,op.getIn(i),isbigendian)) {
|
||||
for (int i = 0; i < op.numInput(); ++i) {
|
||||
if (!checkVarnodeTruncation(ct, i, op, op.getIn(i), isbigendian)) {
|
||||
testresult = false;
|
||||
}
|
||||
}
|
||||
|
@ -726,7 +724,7 @@ class ConsistencyChecker {
|
|||
return testresult;
|
||||
}
|
||||
|
||||
boolean checkSubtable(SubtableSymbol sym) {
|
||||
private boolean checkSubtable(SubtableSymbol sym) {
|
||||
int tablesize = 0;
|
||||
int numconstruct = sym.getNumConstructors();
|
||||
Constructor ct;
|
||||
|
@ -796,7 +794,7 @@ class ConsistencyChecker {
|
|||
|
||||
// Deal with detected extension (SEXT or ZEXT) where the
|
||||
// input size is the same as the output size
|
||||
void dealWithUnnecessaryExt(OpTpl op, Constructor ct) {
|
||||
private void dealWithUnnecessaryExt(OpTpl op, Constructor ct) {
|
||||
if (printextwarning) {
|
||||
compiler.reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
|
||||
}
|
||||
|
@ -804,7 +802,7 @@ class ConsistencyChecker {
|
|||
unnecessarypcode += 1;
|
||||
}
|
||||
|
||||
void dealWithUnnecessaryTrunc(OpTpl op, Constructor ct) {
|
||||
private void dealWithUnnecessaryTrunc(OpTpl op, Constructor ct) {
|
||||
if (printextwarning) {
|
||||
compiler.reportWarning(op.location, "Unnecessary '" + getOpName(op) + "'");
|
||||
}
|
||||
|
@ -814,7 +812,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
// Establish table ordering
|
||||
void setPostOrder(SubtableSymbol root) {
|
||||
private void setPostOrder(SubtableSymbol root) {
|
||||
postorder.clear();
|
||||
sizemap.clear();
|
||||
|
||||
|
@ -869,8 +867,8 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
// Optimization routines
|
||||
static void examineVn(MapSTL<Long, OptimizeRecord> recs, VarnodeTpl vn, int i, int inslot,
|
||||
int secnum) {
|
||||
private static void examineVn(MapSTL<Long, OptimizeRecord> recs, VarnodeTpl vn, int i,
|
||||
int inslot, int secnum) {
|
||||
if (vn == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -900,7 +898,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
}
|
||||
|
||||
static boolean possibleIntersection(VarnodeTpl vn1, VarnodeTpl vn2) {
|
||||
private static boolean possibleIntersection(VarnodeTpl vn1, VarnodeTpl vn2) {
|
||||
// Conservatively test whether vn1 and vn2 can intersect
|
||||
if (vn1.getSpace().isConstSpace()) {
|
||||
return false;
|
||||
|
@ -958,7 +956,7 @@ class ConsistencyChecker {
|
|||
// This is extremely conservative. Basically any op where
|
||||
// we can't see exactly what might be written is considered
|
||||
// interference
|
||||
boolean readWriteInterference(VarnodeTpl vn, OpTpl op, boolean checkread) {
|
||||
private boolean readWriteInterference(VarnodeTpl vn, OpTpl op, boolean checkread) {
|
||||
switch (op.getOpcode()) {
|
||||
case CPUI_MULTIEQUAL:
|
||||
case CPUI_PTRSUB:
|
||||
|
@ -999,7 +997,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
// Look for reads and writes to temporaries
|
||||
void optimizeGather1(Constructor ct, MapSTL<Long, OptimizeRecord> recs, int secnum) {
|
||||
private void optimizeGather1(Constructor ct, MapSTL<Long, OptimizeRecord> recs, int secnum) {
|
||||
ConstructTpl tpl;
|
||||
if (secnum < 0) {
|
||||
tpl = ct.getTempl();
|
||||
|
@ -1023,7 +1021,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
// Make sure any temp used by the export is not optimized away
|
||||
void optimizeGather2(Constructor ct, MapSTL<Long, OptimizeRecord> recs, int secnum) {
|
||||
private void optimizeGather2(Constructor ct, MapSTL<Long, OptimizeRecord> recs, int secnum) {
|
||||
ConstructTpl tpl;
|
||||
if (secnum < 0) {
|
||||
tpl = ct.getTempl();
|
||||
|
@ -1053,7 +1051,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
if (hand.getSpace().isUniqueSpace()) {
|
||||
if ((hand.getPtrSpace().getType() == ConstTpl.const_type.real) &&
|
||||
(hand.getPtrOffset().getType() == ConstTpl.const_type.real)) {
|
||||
(hand.getPtrOffset().getType() == ConstTpl.const_type.real)) {
|
||||
long offset = hand.getPtrOffset().getReal();
|
||||
recs.put(offset, new OptimizeRecord());
|
||||
IteratorSTL<Pair<Long, OptimizeRecord>> res = recs.find(offset);
|
||||
|
@ -1067,7 +1065,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
}
|
||||
|
||||
OptimizeRecord findValidRule(Constructor ct, MapSTL<Long, OptimizeRecord> recs) {
|
||||
private OptimizeRecord findValidRule(Constructor ct, MapSTL<Long, OptimizeRecord> recs) {
|
||||
IteratorSTL<Pair<Long, OptimizeRecord>> iter;
|
||||
iter = recs.begin();
|
||||
while (!iter.isEnd()) {
|
||||
|
@ -1075,7 +1073,7 @@ class ConsistencyChecker {
|
|||
iter.increment();
|
||||
|
||||
if ((currec.writecount == 1) && (currec.readcount == 1) &&
|
||||
(currec.readsection == currec.writesection)) {
|
||||
(currec.readsection == currec.writesection)) {
|
||||
// Temporary must be read and written exactly once
|
||||
ConstructTpl tpl;
|
||||
if (currec.readsection < 0) {
|
||||
|
@ -1123,7 +1121,7 @@ class ConsistencyChecker {
|
|||
return null;
|
||||
}
|
||||
|
||||
void applyOptimization(Constructor ct, OptimizeRecord rec) {
|
||||
private void applyOptimization(Constructor ct, OptimizeRecord rec) {
|
||||
VectorSTL<Integer> deleteops = new VectorSTL<>();
|
||||
ConstructTpl ctempl;
|
||||
if (rec.readsection < 0) {
|
||||
|
@ -1150,7 +1148,7 @@ class ConsistencyChecker {
|
|||
ctempl.deleteOps(deleteops);
|
||||
}
|
||||
|
||||
void checkUnusedTemps(Constructor ct, MapSTL<Long, OptimizeRecord> recs) {
|
||||
private void checkUnusedTemps(Constructor ct, MapSTL<Long, OptimizeRecord> recs) {
|
||||
IteratorSTL<Pair<Long, OptimizeRecord>> iter = recs.begin();
|
||||
while (!iter.isEnd()) {
|
||||
Pair<Long, OptimizeRecord> pair = iter.get();
|
||||
|
@ -1168,30 +1166,29 @@ class ConsistencyChecker {
|
|||
iter.increment();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks {@code ct} to see whether it contains an {@link OpTpl} which
|
||||
* Checks {@code ct} to see whether p-code section contains an {@link OpTpl} which
|
||||
* uses a varnode in the unique space which is larger than {@link SleighBase#MAX_UNIQUE_SIZE}.
|
||||
* @param ct constructor to check
|
||||
* @param ctpl is the specific p-code section
|
||||
*/
|
||||
void checkLargeTemporaries(Constructor ct) {
|
||||
ConstructTpl ctTpl = ct.getTempl();
|
||||
if (ctTpl == null) {
|
||||
return;
|
||||
}
|
||||
VectorSTL<OpTpl> ops = ctTpl.getOpvec();
|
||||
private void checkLargeTemporaries(Constructor ct, ConstructTpl ctpl) {
|
||||
VectorSTL<OpTpl> ops = ctpl.getOpvec();
|
||||
for (IteratorSTL<OpTpl> iter = ops.begin(); !iter.isEnd(); iter.increment()) {
|
||||
if (hasLargeTemporary(iter.get())) {
|
||||
if (printlargetempwarning) {
|
||||
compiler.reportWarning(ct.location, "Constructor uses temporary varnode larger than " + SleighBase.MAX_UNIQUE_SIZE + " bytes.");
|
||||
}
|
||||
if (printlargetempwarning) {
|
||||
compiler.reportWarning(ct.location,
|
||||
"Constructor uses temporary varnode larger than " +
|
||||
SleighBase.MAX_UNIQUE_SIZE + " bytes.");
|
||||
}
|
||||
largetemp++;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void optimize(Constructor ct) {
|
||||
private void optimize(Constructor ct) {
|
||||
OptimizeRecord currec;
|
||||
MapSTL<Long, OptimizeRecord> recs = new ComparableMapSTL<>();
|
||||
int numsections = ct.getNumSections();
|
||||
|
@ -1208,17 +1205,17 @@ class ConsistencyChecker {
|
|||
}
|
||||
while (currec != null);
|
||||
checkUnusedTemps(ct, recs);
|
||||
checkLargeTemporaries(ct);
|
||||
}
|
||||
|
||||
ConsistencyChecker(SleighCompile cp, SubtableSymbol rt, boolean unnecessary, boolean warndead, boolean warnlargetemp) {
|
||||
public ConsistencyChecker(SleighCompile cp, SubtableSymbol rt, boolean unnecessary,
|
||||
boolean warndead, boolean warnlargetemp) {
|
||||
compiler = cp;
|
||||
root_symbol = rt;
|
||||
unnecessarypcode = 0;
|
||||
readnowrite = 0;
|
||||
writenoread = 0;
|
||||
//number of constructors which reference a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
largetemp = 0;
|
||||
largetemp = 0;
|
||||
printextwarning = unnecessary;
|
||||
printdeadwarning = warndead;
|
||||
//whether to print information about constructors which reference large temporary varnodes
|
||||
|
@ -1226,7 +1223,7 @@ class ConsistencyChecker {
|
|||
}
|
||||
|
||||
// Main entry point for size consistency check
|
||||
boolean test() {
|
||||
public boolean testSizeRestrictions() {
|
||||
setPostOrder(root_symbol);
|
||||
boolean testresult = true;
|
||||
|
||||
|
@ -1239,18 +1236,19 @@ class ConsistencyChecker {
|
|||
return testresult;
|
||||
}
|
||||
|
||||
boolean testTruncations(boolean isbigendian) {
|
||||
public boolean testTruncations() {
|
||||
// Now that the sizemap is calculated, we can check/adjust the offset_plus templates
|
||||
boolean testresult = true;
|
||||
for(int i=0;i<postorder.size();++i) {
|
||||
boolean isbigendian = compiler.isBigEndian();
|
||||
for (int i = 0; i < postorder.size(); ++i) {
|
||||
SubtableSymbol sym = postorder.get(i);
|
||||
int numconstruct = sym.getNumConstructors();
|
||||
Constructor ct;
|
||||
for(int j=0;j<numconstruct;++j) {
|
||||
for (int j = 0; j < numconstruct; ++j) {
|
||||
ct = sym.getConstructor(j);
|
||||
|
||||
int numsections = ct.getNumSections();
|
||||
for(int k=-1;k<numsections;++k) {
|
||||
for (int k = -1; k < numsections; ++k) {
|
||||
ConstructTpl tpl;
|
||||
if (k < 0) {
|
||||
tpl = ct.getTempl();
|
||||
|
@ -1261,7 +1259,7 @@ class ConsistencyChecker {
|
|||
if (tpl == null) {
|
||||
continue;
|
||||
}
|
||||
if (!checkSectionTruncations(ct,tpl,isbigendian)) {
|
||||
if (!checkSectionTruncations(ct, tpl, isbigendian)) {
|
||||
testresult = false;
|
||||
}
|
||||
}
|
||||
|
@ -1270,7 +1268,33 @@ class ConsistencyChecker {
|
|||
return testresult;
|
||||
}
|
||||
|
||||
void optimizeAll() {
|
||||
public void testLargeTemporary() {
|
||||
for (int i = 0; i < postorder.size(); ++i) {
|
||||
SubtableSymbol sym = postorder.get(i);
|
||||
int numconstruct = sym.getNumConstructors();
|
||||
Constructor ct;
|
||||
for (int j = 0; j < numconstruct; ++j) {
|
||||
ct = sym.getConstructor(j);
|
||||
|
||||
int numsections = ct.getNumSections();
|
||||
for (int k = -1; k < numsections; ++k) {
|
||||
ConstructTpl tpl;
|
||||
if (k < 0) {
|
||||
tpl = ct.getTempl();
|
||||
}
|
||||
else {
|
||||
tpl = ct.getNamedTempl(k);
|
||||
}
|
||||
if (tpl == null) {
|
||||
continue;
|
||||
}
|
||||
checkLargeTemporaries(ct, tpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void optimizeAll() {
|
||||
for (int i = 0; i < postorder.size(); ++i) {
|
||||
SubtableSymbol sym = postorder.get(i);
|
||||
int numconstruct = sym.getNumConstructors();
|
||||
|
@ -1282,24 +1306,24 @@ class ConsistencyChecker {
|
|||
}
|
||||
}
|
||||
|
||||
int getNumUnnecessaryPcode() {
|
||||
public int getNumUnnecessaryPcode() {
|
||||
return unnecessarypcode;
|
||||
}
|
||||
|
||||
int getNumReadNoWrite() {
|
||||
public int getNumReadNoWrite() {
|
||||
return readnowrite;
|
||||
}
|
||||
|
||||
int getNumWriteNoRead() {
|
||||
public int getNumWriteNoRead() {
|
||||
return writenoread;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of constructors which reference a varnode in the
|
||||
* unique space with size larger than {@link SleighBase#MAX_UNIQUE_SIZE}.
|
||||
* @return num constructors with large temp varnodes
|
||||
*/
|
||||
int getNumLargeTemporaries() {
|
||||
public int getNumLargeTemporaries() {
|
||||
return largetemp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,13 @@
|
|||
*/
|
||||
package ghidra.pcodeCPort.slgh_compile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
import org.jdom.JDOMException;
|
||||
|
||||
import generic.stl.*;
|
||||
|
@ -39,8 +38,10 @@ import ghidra.pcodeCPort.space.*;
|
|||
import ghidra.pcodeCPort.utils.Utils;
|
||||
import ghidra.pcodeCPort.xml.DocumentStorage;
|
||||
import ghidra.program.model.lang.BasicCompilerSpec;
|
||||
import ghidra.sleigh.grammar.Location;
|
||||
import ghidra.sleigh.grammar.*;
|
||||
import ghidra.util.Msg;
|
||||
import utilities.util.FileResolutionResult;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
* <code>SleighCompile</code> provides the ability to compile Sleigh language module (e.g., *.slaspec)
|
||||
|
@ -50,7 +51,7 @@ public class SleighCompile extends SleighBase {
|
|||
|
||||
static boolean yydebug = false;
|
||||
|
||||
static boolean isLocationIsh(Object o) {
|
||||
private static boolean isLocationIsh(Object o) {
|
||||
if (o instanceof Location) {
|
||||
return true;
|
||||
}
|
||||
|
@ -225,48 +226,45 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
|
||||
// Defines for the preprocessor
|
||||
MapSTL<String, String> preproc_defines = new MapSTL<>(new SelfComparator<String>());
|
||||
VectorSTL<FieldContext> contexttable = new VectorSTL<>();
|
||||
Integer firstContextField = null;
|
||||
VectorSTL<ConstructTpl> macrotable = new VectorSTL<>();
|
||||
VectorSTL<ghidra.pcodeCPort.context.Token> tokentable = new VectorSTL<>();
|
||||
VectorSTL<SubtableSymbol> tables = new VectorSTL<>();
|
||||
VectorSTL<SectionSymbol> sections = new VectorSTL<>();
|
||||
Constructor curct; // Current constructor being defined
|
||||
MacroSymbol curmacro; // Current macro being defined
|
||||
private MapSTL<String, String> preproc_defines = new MapSTL<>(new SelfComparator<String>());
|
||||
private VectorSTL<FieldContext> contexttable = new VectorSTL<>();
|
||||
private Integer firstContextField = null;
|
||||
private VectorSTL<ConstructTpl> macrotable = new VectorSTL<>();
|
||||
private VectorSTL<ghidra.pcodeCPort.context.Token> tokentable = new VectorSTL<>();
|
||||
private VectorSTL<SubtableSymbol> tables = new VectorSTL<>();
|
||||
private VectorSTL<SectionSymbol> sections = new VectorSTL<>();
|
||||
private Constructor curct; // Current constructor being defined
|
||||
private MacroSymbol curmacro; // Current macro being defined
|
||||
|
||||
// If the context layout has been established yet
|
||||
boolean contextlock;
|
||||
private boolean contextlock;
|
||||
|
||||
// Stack of current files being parsed
|
||||
// VectorSTL<String> filename = new VectorSTL<String>();
|
||||
String filename;
|
||||
|
||||
// Current line number for each file in stack
|
||||
// VectorSTL<Integer> lineno = new VectorSTL<Integer>();
|
||||
int lineno;
|
||||
int linenoDifferential;
|
||||
|
||||
int userop_count; // Number of userops defined
|
||||
private int userop_count; // Number of userops defined
|
||||
|
||||
boolean warnunnecessarypcode; // True if we warn of unnecessary ZEXT or SEXT
|
||||
boolean warndeadtemps; // True if we warn of temporaries that are written but not read
|
||||
boolean warnunusedfields; // True if fields are defined but not used
|
||||
boolean enforcelocalkeyword; // Force slaspec to use 'local' keyword when defining temporary varnodes
|
||||
boolean lenientconflicterrors; // True if we ignore most pattern conflict errors
|
||||
boolean largetemporarywarning; // True if we warn about temporaries larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
public boolean warnalllocalcollisions;
|
||||
public boolean warnallnops;
|
||||
public VectorSTL<String> noplist = new VectorSTL<>();
|
||||
private boolean warnunnecessarypcode; // True if we warn of unnecessary ZEXT or SEXT
|
||||
private boolean warndeadtemps; // True if we warn of temporaries that are written but not read
|
||||
private boolean warnunusedfields; // True if fields are defined but not used
|
||||
private boolean lenientconflicterrors; // True if we ignore most pattern conflict errors
|
||||
private boolean largetemporarywarning; // True if we warn about temporaries larger than SleighBase.MAX_UNIQUE_SIZE
|
||||
private boolean warnalllocalcollisions; // True if local export collisions generate individual warnings
|
||||
private boolean warnallnops; // True if pcode NOPs generate individual warnings
|
||||
private boolean failinsensitivedups; // True if case insensitive register duplicates cause error
|
||||
private VectorSTL<String> noplist = new VectorSTL<>();
|
||||
|
||||
public Deque<WithBlock> withstack = new LinkedList<>();
|
||||
private Deque<WithBlock> withstack = new LinkedList<>();
|
||||
|
||||
int errors;
|
||||
int warnings;
|
||||
private int errors;
|
||||
private int warnings;
|
||||
|
||||
// Define the "pre" defined spaces and symbols
|
||||
// This must happen after endian has been defined
|
||||
void predefinedSymbols() {
|
||||
private void predefinedSymbols() {
|
||||
entry("predefinedSymbols");
|
||||
symtab.addScope(); // Create global scope
|
||||
|
||||
|
@ -327,14 +325,14 @@ public class SleighCompile extends SleighBase {
|
|||
return res;
|
||||
}
|
||||
|
||||
SectionVector standaloneSection(ConstructTpl main) {
|
||||
protected SectionVector standaloneSection(ConstructTpl main) {
|
||||
entry("standaloneSection", main);
|
||||
// Create SectionVector for just the main rtl section with no named sections
|
||||
SectionVector res = new SectionVector(main, symtab.getCurrentScope());
|
||||
return res;
|
||||
}
|
||||
|
||||
SectionVector firstNamedSection(ConstructTpl main, SectionSymbol sym) {
|
||||
protected SectionVector firstNamedSection(ConstructTpl main, SectionSymbol sym) {
|
||||
entry("firstNamedSection", main);
|
||||
// Start the first named p-code section after the main p-code section
|
||||
sym.incrementDefineCount();
|
||||
|
@ -349,7 +347,8 @@ public class SleighCompile extends SleighBase {
|
|||
return res;
|
||||
}
|
||||
|
||||
SectionVector nextNamedSection(SectionVector vec, ConstructTpl section, SectionSymbol sym) {
|
||||
protected SectionVector nextNamedSection(SectionVector vec, ConstructTpl section,
|
||||
SectionSymbol sym) {
|
||||
entry("nextNamedSection", vec, section, sym);
|
||||
// Add additional named p-code sections
|
||||
sym.incrementDefineCount();
|
||||
|
@ -365,7 +364,7 @@ public class SleighCompile extends SleighBase {
|
|||
return vec;
|
||||
}
|
||||
|
||||
SectionVector finalNamedSection(SectionVector vec, ConstructTpl section) {
|
||||
protected SectionVector finalNamedSection(SectionVector vec, ConstructTpl section) {
|
||||
entry("finalNamedSection", vec, section);
|
||||
// Fill-in final named section to match the previous SectionSymbol
|
||||
vec.append(section, symtab.getCurrentScope());
|
||||
|
@ -373,7 +372,7 @@ public class SleighCompile extends SleighBase {
|
|||
return vec;
|
||||
}
|
||||
|
||||
int calcContextVarLayout(int start, int sz, int numbits) {
|
||||
private int calcContextVarLayout(int start, int sz, int numbits) {
|
||||
entry("calcContextVarLayout", start, sz, numbits);
|
||||
VarnodeSymbol sym = contexttable.get(start).sym;
|
||||
FieldQuality qual;
|
||||
|
@ -390,7 +389,7 @@ public class SleighCompile extends SleighBase {
|
|||
i = 0;
|
||||
while (i < sz) {
|
||||
|
||||
qual = contexttable.get(i).qual;
|
||||
qual = contexttable.get(i + start).qual;
|
||||
int min = qual.low;
|
||||
int max = qual.high;
|
||||
if (max - min > (8 * 4)) {
|
||||
|
@ -409,7 +408,7 @@ public class SleighCompile extends SleighBase {
|
|||
j = i + 1;
|
||||
// Find union of fields overlapping with first field
|
||||
while (j < sz) {
|
||||
qual = contexttable.get(j).qual;
|
||||
qual = contexttable.get(j + start).qual;
|
||||
if (qual.low <= max) { // We have overlap of context variables
|
||||
if (qual.high > max) {
|
||||
max = qual.high;
|
||||
|
@ -434,7 +433,7 @@ public class SleighCompile extends SleighBase {
|
|||
numbits += alloc;
|
||||
|
||||
for (; i < j; ++i) {
|
||||
qual = contexttable.get(i).qual;
|
||||
qual = contexttable.get(i + start).qual;
|
||||
int l = qual.low - min + low;
|
||||
int h = numbits - 1 - (max - qual.high);
|
||||
ContextField field = new ContextField(qual.location, qual.signext, l, h);
|
||||
|
@ -450,7 +449,7 @@ public class SleighCompile extends SleighBase {
|
|||
return numbits;
|
||||
}
|
||||
|
||||
void buildDecisionTrees() {
|
||||
private void buildDecisionTrees() {
|
||||
entry("buildDecisionTrees");
|
||||
DecisionProperties props = new DecisionProperties();
|
||||
root.buildDecisionTree(props);
|
||||
|
@ -474,7 +473,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void buildPatterns() {
|
||||
private void buildPatterns() {
|
||||
entry("buildPatterns");
|
||||
if (root == null) {
|
||||
reportError(null, "No patterns to match--could not find any constructors");
|
||||
|
@ -496,16 +495,16 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void checkConsistency() {
|
||||
private void checkConsistency() {
|
||||
entry("checkConsistency");
|
||||
ConsistencyChecker checker =
|
||||
new ConsistencyChecker(this, root, warnunnecessarypcode, warndeadtemps, largetemporarywarning);
|
||||
ConsistencyChecker checker = new ConsistencyChecker(this, root, warnunnecessarypcode,
|
||||
warndeadtemps, largetemporarywarning);
|
||||
|
||||
if (!checker.test()) {
|
||||
if (!checker.testSizeRestrictions()) {
|
||||
errors += 1;
|
||||
return;
|
||||
}
|
||||
if (!checker.testTruncations(isBigEndian())) {
|
||||
if (!checker.testTruncations()) {
|
||||
errors += 1;
|
||||
return;
|
||||
}
|
||||
|
@ -524,14 +523,17 @@ public class SleighCompile extends SleighBase {
|
|||
" operations wrote to temporaries that were not read");
|
||||
reportWarning(null, "Use -t switch to list each individually");
|
||||
}
|
||||
checker.testLargeTemporary();
|
||||
if ((!largetemporarywarning) && checker.getNumLargeTemporaries() > 0) {
|
||||
reportWarning(null, checker.getNumLargeTemporaries() +
|
||||
" constructors contain temporaries larger than " + SleighBase.MAX_UNIQUE_SIZE + " bytes.");
|
||||
reportWarning(null,
|
||||
checker.getNumLargeTemporaries() +
|
||||
" constructors contain temporaries larger than " + SleighBase.MAX_UNIQUE_SIZE +
|
||||
" bytes.");
|
||||
reportWarning(null, "Use -o switch to list each individually.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int findCollision(Map<Long, Integer> local2Operand, ArrayList<Long> locals,
|
||||
private static int findCollision(Map<Long, Integer> local2Operand, ArrayList<Long> locals,
|
||||
int operand) {
|
||||
Integer boxOperand = Integer.valueOf(operand);
|
||||
for (Long local : locals) {
|
||||
|
@ -545,7 +547,7 @@ public class SleighCompile extends SleighBase {
|
|||
return -1;
|
||||
}
|
||||
|
||||
boolean checkLocalExports(Constructor ct) {
|
||||
private boolean checkLocalExports(Constructor ct) {
|
||||
if (ct.getTempl() == null) {
|
||||
return true; // No template, collisions impossible
|
||||
}
|
||||
|
@ -556,9 +558,9 @@ public class SleighCompile extends SleighBase {
|
|||
return true; // Collisions can only happen with multiple operands
|
||||
}
|
||||
boolean noCollisions = true;
|
||||
Map<Long, Integer> collect = new TreeMap<Long, Integer>();
|
||||
Map<Long, Integer> collect = new TreeMap<>();
|
||||
for (int i = 0; i < ct.getNumOperands(); ++i) {
|
||||
ArrayList<Long> newCollect = new ArrayList<Long>();
|
||||
ArrayList<Long> newCollect = new ArrayList<>();
|
||||
ct.getOperand(i).collectLocalValues(newCollect);
|
||||
if (newCollect.isEmpty()) {
|
||||
continue;
|
||||
|
@ -578,7 +580,7 @@ public class SleighCompile extends SleighBase {
|
|||
return noCollisions;
|
||||
}
|
||||
|
||||
void checkLocalCollisions() {
|
||||
private void checkLocalCollisions() {
|
||||
int collisionCount = 0;
|
||||
SubtableSymbol sym = root; // Start with the instruction table
|
||||
int i = -1;
|
||||
|
@ -604,8 +606,53 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkNops() {
|
||||
if (noplist.size() > 0) {
|
||||
if (warnallnops) {
|
||||
IteratorSTL<String> iter;
|
||||
for (iter = noplist.begin(); !iter.isEnd(); iter.increment()) {
|
||||
Msg.warn(SleighCompile.class, iter.get());
|
||||
}
|
||||
}
|
||||
Msg.warn(SleighCompile.class, noplist.size() + " NOP constructors found");
|
||||
if (!warnallnops) {
|
||||
Msg.warn(SleighCompile.class, "Use -n switch to list each individually");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCaseSensitivity() {
|
||||
if (!failinsensitivedups) {
|
||||
return; // Case insensitive duplicates don't cause error
|
||||
}
|
||||
HashMap<String, SleighSymbol> registerMap = new HashMap<>();
|
||||
SymbolScope scope = symtab.getGlobalScope();
|
||||
IteratorSTL<SleighSymbol> iter;
|
||||
for (iter = scope.begin(); !iter.isEnd(); iter.increment()) {
|
||||
SleighSymbol sym = iter.get();
|
||||
if (!(sym instanceof VarnodeSymbol)) {
|
||||
continue;
|
||||
}
|
||||
VarnodeSymbol vsym = (VarnodeSymbol) sym;
|
||||
AddrSpace space = vsym.getFixedVarnode().space;
|
||||
if (space.getType() != spacetype.IPTR_PROCESSOR) {
|
||||
continue;
|
||||
}
|
||||
String nm = sym.getName().toUpperCase();
|
||||
SleighSymbol oldsym = registerMap.putIfAbsent(nm, sym);
|
||||
if (oldsym != null) { // Name already existed
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("Name collision: ").append(sym.getName()).append(" --- ");
|
||||
Location oldLocation = oldsym.getLocation();
|
||||
buffer.append("Duplicate symbol ").append(oldsym.getName()).append(" defined at ");
|
||||
buffer.append(oldLocation);
|
||||
reportError(sym.getLocation(), buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure label symbols are used properly
|
||||
String checkSymbols(SymbolScope scope) {
|
||||
private String checkSymbols(SymbolScope scope) {
|
||||
entry("checkSymbols", scope);
|
||||
List<String> symbolErrors = new ArrayList<>();
|
||||
IteratorSTL<SleighSymbol> iter;
|
||||
|
@ -628,7 +675,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
|
||||
// Make sure symbol table errors are caught
|
||||
int addSymbol(SleighSymbol sym) {
|
||||
protected int addSymbol(SleighSymbol sym) {
|
||||
entry("addSymbol", sym);
|
||||
int id = -1;
|
||||
try {
|
||||
|
@ -648,7 +695,9 @@ public class SleighCompile extends SleighBase {
|
|||
errors = 0;
|
||||
warnunnecessarypcode = false;
|
||||
lenientconflicterrors = true;
|
||||
largetemporarywarning = false;
|
||||
warnallnops = false;
|
||||
failinsensitivedups = true;
|
||||
root = null;
|
||||
pcode.resetLabelCount();
|
||||
}
|
||||
|
@ -689,63 +738,69 @@ public class SleighCompile extends SleighBase {
|
|||
return warnings;
|
||||
}
|
||||
|
||||
long getUniqueAddr() {
|
||||
protected long getUniqueAddr() {
|
||||
entry("getUniqueAddr");
|
||||
long base = getUniqueBase();
|
||||
setUniqueBase(base + MAX_UNIQUE_SIZE);
|
||||
setUniqueBase(base + MAX_UNIQUE_SIZE);
|
||||
return base;
|
||||
}
|
||||
|
||||
void setUnnecessaryPcodeWarning(boolean val) {
|
||||
public void setUnnecessaryPcodeWarning(boolean val) {
|
||||
entry("setUnecessaryPcodeWarning", val);
|
||||
warnunnecessarypcode = val;
|
||||
}
|
||||
|
||||
void setDeadTempWarning(boolean val) {
|
||||
public void setDeadTempWarning(boolean val) {
|
||||
entry("setDeadTempWarning", val);
|
||||
warndeadtemps = val;
|
||||
}
|
||||
|
||||
void setUnusedFieldWarning(boolean val) {
|
||||
public void setUnusedFieldWarning(boolean val) {
|
||||
entry("setUnusedFieldWarning", val);
|
||||
warnunusedfields = val;
|
||||
}
|
||||
|
||||
void setEnforceLocalKeyWord(boolean val) {
|
||||
public void setEnforceLocalKeyWord(boolean val) {
|
||||
entry("setEnforceLocalKeyWord", val);
|
||||
enforcelocalkeyword = val;
|
||||
pcode.setEnforceLocalKey(val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether or not to print out warning info about
|
||||
* {@link Constructor}s which reference varnodes in the
|
||||
* unique space larger than {@link SleighBase#MAX_UNIQUE_SIZE}.
|
||||
* @param val whether to print info about contructors using large varnodes
|
||||
*/
|
||||
void setLargeTemporaryWarning(boolean val) {
|
||||
entry("setLargeTemporaryWarning",val);
|
||||
public void setLargeTemporaryWarning(boolean val) {
|
||||
entry("setLargeTemporaryWarning", val);
|
||||
largetemporarywarning = val;
|
||||
}
|
||||
|
||||
void setLenientConflict(boolean val) {
|
||||
public void setLenientConflict(boolean val) {
|
||||
entry("setLenientConflict", val);
|
||||
lenientconflicterrors = val;
|
||||
}
|
||||
|
||||
void setLocalCollisionWarning(boolean val) {
|
||||
public void setLocalCollisionWarning(boolean val) {
|
||||
entry("setLocalCollisionWarning", val);
|
||||
warnalllocalcollisions = val;
|
||||
}
|
||||
|
||||
void setAllNopWarning(boolean val) {
|
||||
public void setAllNopWarning(boolean val) {
|
||||
entry("setAllNopWarning", val);
|
||||
warnallnops = val;
|
||||
}
|
||||
|
||||
public void setInsensitiveDuplicateError(boolean val) {
|
||||
entry("setInsensitiveDuplicateError", val);
|
||||
failinsensitivedups = val;
|
||||
}
|
||||
|
||||
// Do all post processing on the parsed data structures
|
||||
public void process() {
|
||||
private void process() {
|
||||
entry("process");
|
||||
checkNops();
|
||||
checkCaseSensitivity();
|
||||
if (getDefaultSpace() == null) {
|
||||
reportError(null, "No default space specified");
|
||||
}
|
||||
|
@ -768,7 +823,7 @@ public class SleighCompile extends SleighBase {
|
|||
if (errors > 0) {
|
||||
return;
|
||||
}
|
||||
ArrayList<SleighSymbol> errorPairs = new ArrayList<SleighSymbol>();
|
||||
ArrayList<SleighSymbol> errorPairs = new ArrayList<>();
|
||||
buildXrefs(errorPairs); // Make sure we can build crossrefs properly
|
||||
if (!errorPairs.isEmpty()) {
|
||||
for (int i = 0; i < errorPairs.size(); i += 2) {
|
||||
|
@ -816,25 +871,7 @@ public class SleighCompile extends SleighBase {
|
|||
contexttable.clear();
|
||||
}
|
||||
|
||||
private static final Pattern PREPROCPOS = Pattern.compile("%%%(.*)\b(\\d+)%%%");
|
||||
|
||||
public void setPosition(String pos, int presumedLineno) {
|
||||
Matcher m;
|
||||
if ((m = PREPROCPOS.matcher(pos)).matches()) {
|
||||
filename = m.group(1);
|
||||
lineno = Integer.parseInt(m.group(2));
|
||||
this.linenoDifferential = lineno - presumedLineno;
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("couldn't parse position '" + pos + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public void setLineno(int presumedLineno) {
|
||||
lineno = presumedLineno + linenoDifferential;
|
||||
}
|
||||
|
||||
Pair<Boolean, String> getPreprocValue(String nm) {
|
||||
public Pair<Boolean, String> getPreprocValue(String nm) {
|
||||
IteratorSTL<Pair<String, String>> iter = preproc_defines.find(nm);
|
||||
if (iter.isEnd()) {
|
||||
return new Pair<>(false, null);
|
||||
|
@ -842,11 +879,11 @@ public class SleighCompile extends SleighBase {
|
|||
return new Pair<>(true, iter.get().second);
|
||||
}
|
||||
|
||||
void setPreprocValue(String nm, String value) {
|
||||
public void setPreprocValue(String nm, String value) {
|
||||
preproc_defines.put(nm, value);
|
||||
}
|
||||
|
||||
boolean undefinePreprocValue(String nm) {
|
||||
public boolean undefinePreprocValue(String nm) {
|
||||
IteratorSTL<Pair<String, String>> iter = preproc_defines.find(nm);
|
||||
if (iter.isEnd()) {
|
||||
return false;
|
||||
|
@ -1281,7 +1318,7 @@ public class SleighCompile extends SleighBase {
|
|||
|
||||
// Match up any qualities of the macro's OperandSymbols with
|
||||
// any OperandSymbol passed into the macro
|
||||
void compareMacroParams(MacroSymbol sym, VectorSTL<ExprTree> param) {
|
||||
public void compareMacroParams(MacroSymbol sym, VectorSTL<ExprTree> param) {
|
||||
entry("compareMacroParams", sym, param);
|
||||
for (int i = 0; i < param.size(); ++i) {
|
||||
VarnodeTpl outvn = param.get(i).outvn;
|
||||
|
@ -1352,7 +1389,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
|
||||
// Reset set state after a an error in previous constructor
|
||||
void resetConstructors() {
|
||||
protected void resetConstructors() {
|
||||
entry("resetConstructors");
|
||||
symtab.setCurrentScope(symtab.getGlobalScope()); // Purge any
|
||||
// dangling local
|
||||
|
@ -1361,7 +1398,7 @@ public class SleighCompile extends SleighBase {
|
|||
|
||||
// Find a defining instance of the local variable
|
||||
// with given -offset-
|
||||
private static VarnodeTpl find_size(ConstTpl offset, ConstructTpl ct) {
|
||||
private static VarnodeTpl findSize(ConstTpl offset, ConstructTpl ct) {
|
||||
entry("find_size", offset, ct);
|
||||
VectorSTL<OpTpl> ops = ct.getOpvec();
|
||||
VarnodeTpl vn;
|
||||
|
@ -1386,7 +1423,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
|
||||
// Look for zero size temps in export statement
|
||||
private static boolean force_exportsize(ConstructTpl ct) {
|
||||
private static boolean forceExportSize(ConstructTpl ct) {
|
||||
entry("force_exportsize", ct);
|
||||
HandleTpl result = ct.getResult();
|
||||
if (result == null) {
|
||||
|
@ -1396,14 +1433,14 @@ public class SleighCompile extends SleighBase {
|
|||
VarnodeTpl vt;
|
||||
|
||||
if (result.getPtrSpace().isUniqueSpace() && result.getPtrSize().isZero()) {
|
||||
vt = find_size(result.getPtrOffset(), ct);
|
||||
vt = findSize(result.getPtrOffset(), ct);
|
||||
if (vt == null) {
|
||||
return false;
|
||||
}
|
||||
result.setPtrSize(vt.getSize());
|
||||
}
|
||||
else if (result.getSpace().isUniqueSpace() && result.getSize().isZero()) {
|
||||
vt = find_size(result.getPtrOffset(), ct);
|
||||
vt = findSize(result.getPtrOffset(), ct);
|
||||
if (vt == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1412,7 +1449,7 @@ public class SleighCompile extends SleighBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean expandMacros(ConstructTpl ctpl) {
|
||||
private boolean expandMacros(ConstructTpl ctpl) {
|
||||
VectorSTL<OpTpl> vec = ctpl.getOpvec();
|
||||
VectorSTL<OpTpl> newvec = new VectorSTL<>();
|
||||
IteratorSTL<OpTpl> iter;
|
||||
|
@ -1442,7 +1479,7 @@ public class SleighCompile extends SleighBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean finalizeSections(Constructor big, SectionVector vec) {
|
||||
private boolean finalizeSections(Constructor big, SectionVector vec) {
|
||||
entry("finalizeSections", big, vec);
|
||||
// Do all final checks, expansions, and linking for p-code sections
|
||||
VectorSTL<String> myErrors = new VectorSTL<>();
|
||||
|
@ -1485,7 +1522,7 @@ public class SleighCompile extends SleighBase {
|
|||
if (big.getParent() == root) {
|
||||
myErrors.push_back(" Cannot have export statement in root constructor");
|
||||
}
|
||||
else if (!force_exportsize(cur.section)) {
|
||||
else if (!forceExportSize(cur.section)) {
|
||||
myErrors.push_back(" Size of export is unknown");
|
||||
}
|
||||
}
|
||||
|
@ -1523,7 +1560,7 @@ public class SleighCompile extends SleighBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
void shiftUniqueVn(VarnodeTpl vn, int sa) {
|
||||
private static void shiftUniqueVn(VarnodeTpl vn, int sa) {
|
||||
entry("shiftUniqueVn", vn, sa);
|
||||
// If the varnode is in the unique space, shift its offset up by -sa- bits
|
||||
if (vn.getSpace().isUniqueSpace() &&
|
||||
|
@ -1534,7 +1571,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void shiftUniqueOp(OpTpl op, int sa) {
|
||||
private static void shiftUniqueOp(OpTpl op, int sa) {
|
||||
entry("shiftUniqueOp", op, sa);
|
||||
// Shift the offset up by -sa- bits for any varnode used by this -op- in the unique space
|
||||
VarnodeTpl outvn = op.getOut();
|
||||
|
@ -1546,7 +1583,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void shiftUniqueHandle(HandleTpl hand, int sa) {
|
||||
private static void shiftUniqueHandle(HandleTpl hand, int sa) {
|
||||
entry("shiftUniqueHandle", hand, sa);
|
||||
// Shift the offset up by -sa- bits, for either the dynamic or static varnode aspects that are in the unique space
|
||||
if (hand.getSpace().isUniqueSpace() &&
|
||||
|
@ -1571,7 +1608,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void shiftUniqueConstruct(ConstructTpl tpl, int sa) {
|
||||
private static void shiftUniqueConstruct(ConstructTpl tpl, int sa) {
|
||||
entry("shiftUniqueConstruct", tpl, sa);
|
||||
// Shift the offset up by -sa- bits, for any varnode in the unique space associated with this template
|
||||
HandleTpl result = tpl.getResult();
|
||||
|
@ -1584,7 +1621,7 @@ public class SleighCompile extends SleighBase {
|
|||
}
|
||||
}
|
||||
|
||||
void checkUniqueAllocation() {
|
||||
private void checkUniqueAllocation() {
|
||||
// With crossbuilds, temporaries may need to survive across instructions in a packet, so here we
|
||||
// provide space in the offset of the temporary (within the unique space) so that the run-time sleigh
|
||||
// engine can alter the value to prevent collisions with other nearby instructions
|
||||
|
@ -1623,7 +1660,7 @@ public class SleighCompile extends SleighBase {
|
|||
setUniqueBase(ubase);
|
||||
}
|
||||
|
||||
void checkFieldUsage() {
|
||||
private void checkFieldUsage() {
|
||||
if (warnunusedfields) {
|
||||
VectorSTL<SleighSymbol> unsoughtSymbols = symtab.getUnsoughtSymbols();
|
||||
IteratorSTL<SleighSymbol> siter;
|
||||
|
@ -1718,6 +1755,93 @@ public class SleighCompile extends SleighBase {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public void setAllOptions(Map<String, String> preprocs, boolean unnecessaryPcodeWarning,
|
||||
boolean lenientConflict, boolean allCollisionWarning, boolean allNopWarning,
|
||||
boolean deadTempWarning, boolean unusedFieldWarning, boolean enforceLocalKeyWord,
|
||||
boolean largeTemporaryWarning, boolean caseSensitiveRegisterNames) {
|
||||
Set<Entry<String, String>> entrySet = preprocs.entrySet();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
setPreprocValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
setUnnecessaryPcodeWarning(unnecessaryPcodeWarning);
|
||||
setLenientConflict(lenientConflict);
|
||||
setLocalCollisionWarning(allCollisionWarning);
|
||||
setAllNopWarning(allNopWarning);
|
||||
setDeadTempWarning(deadTempWarning);
|
||||
setUnusedFieldWarning(unusedFieldWarning);
|
||||
setEnforceLocalKeyWord(enforceLocalKeyWord);
|
||||
setLargeTemporaryWarning(largeTemporaryWarning);
|
||||
setInsensitiveDuplicateError(!caseSensitiveRegisterNames);
|
||||
}
|
||||
|
||||
public int run_compilation(String filein, String fileout)
|
||||
throws IOException, RecognitionException {
|
||||
LineArrayListWriter writer = new LineArrayListWriter();
|
||||
ParsingEnvironment env = new ParsingEnvironment(writer);
|
||||
try {
|
||||
final SleighCompilePreprocessorDefinitionsAdapater definitionsAdapter =
|
||||
new SleighCompilePreprocessorDefinitionsAdapater(this);
|
||||
final File inputFile = new File(filein);
|
||||
FileResolutionResult result = FileUtilities.existsAndIsCaseDependent(inputFile);
|
||||
if (!result.isOk()) {
|
||||
throw new BailoutException("input file \"" + inputFile +
|
||||
"\" is not properly case dependent: " + result.getMessage());
|
||||
}
|
||||
SleighPreprocessor sp = new SleighPreprocessor(definitionsAdapter, inputFile);
|
||||
sp.process(writer);
|
||||
|
||||
CharStream input = new ANTLRStringStream(writer.toString());
|
||||
SleighLexer lex = new SleighLexer(input);
|
||||
lex.setEnv(env);
|
||||
UnbufferedTokenStream tokens = new UnbufferedTokenStream(lex);
|
||||
SleighParser parser = new SleighParser(tokens);
|
||||
parser.setEnv(env);
|
||||
parser.setLexer(lex);
|
||||
SleighParser.spec_return parserRoot = parser.spec();
|
||||
/*ANTLRUtil.debugTree(root.getTree(),
|
||||
new PrintStream(new FileOutputStream("blargh.tree")));*/
|
||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(parserRoot.getTree());
|
||||
nodes.setTokenStream(tokens);
|
||||
// ANTLRUtil.debugNodeStream(nodes, System.out);
|
||||
SleighCompiler walker = new SleighCompiler(nodes);
|
||||
|
||||
int parseres = -1;
|
||||
try {
|
||||
parseres = walker.root(env, this); // Try to parse
|
||||
}
|
||||
catch (SleighError e) {
|
||||
reportError(e.location, e.getMessage());
|
||||
}
|
||||
if (parseres == 0) {
|
||||
process(); // Do all the post-processing
|
||||
}
|
||||
if ((parseres == 0) && (numErrors() == 0)) {
|
||||
// If no errors
|
||||
PrintStream s = new PrintStream(new FileOutputStream(new File(fileout)));
|
||||
saveXml(s); // Dump output xml
|
||||
s.close();
|
||||
}
|
||||
else {
|
||||
Msg.error(SleighCompile.class, "No output produced");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
catch (BailoutException e) {
|
||||
Msg.error(SleighCompile.class, "Unrecoverable error(s), halting compilation", e);
|
||||
return 3;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
Msg.error(SleighCompile.class, "Unrecoverable error(s), halting compilation", e);
|
||||
return 4;
|
||||
}
|
||||
catch (PreprocessorException e) {
|
||||
Msg.error(SleighCompile.class, e.getMessage());
|
||||
Msg.error(SleighCompile.class, "Errors during preprocessing, halting compilation");
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the sleigh compiler. This provides a direct means of invoking the
|
||||
* compiler without using the launcher. The full SoftwareModeling classpath
|
||||
|
|
|
@ -17,24 +17,17 @@ package ghidra.pcodeCPort.slgh_compile;
|
|||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.jdom.JDOMException;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.stl.IteratorSTL;
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
import ghidra.GhidraLaunchable;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.ApplicationConfiguration;
|
||||
import ghidra.pcodeCPort.context.SleighError;
|
||||
import ghidra.sleigh.grammar.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import utilities.util.FileResolutionResult;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
/**
|
||||
* <code>SleighCompileLauncher</code> Sleigh compiler launch provider
|
||||
|
@ -46,24 +39,6 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
private static final FileFilter SLASPEC_FILTER =
|
||||
pathname -> pathname.getName().endsWith(".slaspec");
|
||||
|
||||
private static void initCompiler(SleighCompile compiler, Map<String, String> preprocs,
|
||||
boolean unnecessaryPcodeWarning, boolean lenientConflict, boolean allCollisionWarning,
|
||||
boolean allNopWarning, boolean deadTempWarning, boolean unusedFieldWarning,
|
||||
boolean enforceLocalKeyWord, boolean largeTemporaryWarning) {
|
||||
Set<Entry<String, String>> entrySet = preprocs.entrySet();
|
||||
for (Entry<String, String> entry : entrySet) {
|
||||
compiler.setPreprocValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
compiler.setUnnecessaryPcodeWarning(unnecessaryPcodeWarning);
|
||||
compiler.setLenientConflict(lenientConflict);
|
||||
compiler.setLocalCollisionWarning(allCollisionWarning);
|
||||
compiler.setAllNopWarning(allNopWarning);
|
||||
compiler.setDeadTempWarning(deadTempWarning);
|
||||
compiler.setUnusedFieldWarning(unusedFieldWarning);
|
||||
compiler.setEnforceLocalKeyWord(enforceLocalKeyWord);
|
||||
compiler.setLargeTemporaryWarning(largeTemporaryWarning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(GhidraApplicationLayout layout, String[] args)
|
||||
throws JDOMException, IOException, RecognitionException {
|
||||
|
@ -80,9 +55,9 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
*
|
||||
* @param args sleigh compiler command line arguments
|
||||
* @return exit code (TODO: exit codes are not well defined)
|
||||
* @throws JDOMException
|
||||
* @throws IOException
|
||||
* @throws RecognitionException
|
||||
* @throws JDOMException for XML errors
|
||||
* @throws IOException for file access errors
|
||||
* @throws RecognitionException for parse errors
|
||||
*/
|
||||
public static int runMain(String[] args)
|
||||
throws JDOMException, IOException, RecognitionException {
|
||||
|
@ -113,6 +88,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
Msg.info(SleighCompile.class, " -c print warnings for all constructors with colliding operands");
|
||||
Msg.info(SleighCompile.class, " -f print warnings for unused token fields");
|
||||
Msg.info(SleighCompile.class, " -o print warnings for temporaries which are too large");
|
||||
Msg.info(SleighCompile.class, " -s treat register names as case sensitive");
|
||||
Msg.info(SleighCompile.class, " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE (option may be repeated)");
|
||||
Msg.info(SleighCompile.class, " -dMODULE defines a preprocessor macro MODULE with a value of its module path (option may be repeated)");
|
||||
Msg.info(SleighCompile.class, " -i <options-file> inject options from specified file");
|
||||
|
@ -128,6 +104,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
boolean enforceLocalKeyWord = false;
|
||||
boolean unusedFieldWarning = false;
|
||||
boolean largeTemporaryWarning = false;
|
||||
boolean caseSensitiveRegisterNames = false;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < args.length; ++i) {
|
||||
|
@ -191,6 +168,9 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
else if (args[i].charAt(1) == 'o') {
|
||||
largeTemporaryWarning = true;
|
||||
}
|
||||
else if (args[i].charAt(1) == 's') {
|
||||
caseSensitiveRegisterNames = true;
|
||||
}
|
||||
else if (args[i].charAt(1) == 'x') {
|
||||
SleighCompile.yydebug = true; // Debug option
|
||||
}
|
||||
|
@ -223,14 +203,14 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
for (File input : visitor) {
|
||||
System.out.println("Compiling " + input + ":");
|
||||
SleighCompile compiler = new SleighCompile();
|
||||
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||
compiler.setAllOptions(preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||
allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning,
|
||||
enforceLocalKeyWord, largeTemporaryWarning);
|
||||
enforceLocalKeyWord, largeTemporaryWarning, caseSensitiveRegisterNames);
|
||||
|
||||
String outname = input.getName().replace(".slaspec", ".sla");
|
||||
File output = new File(input.getParent(), outname);
|
||||
retval =
|
||||
run_compilation(input.getAbsolutePath(), output.getAbsolutePath(), compiler);
|
||||
compiler.run_compilation(input.getAbsolutePath(), output.getAbsolutePath());
|
||||
System.out.println();
|
||||
if (retval != 0) {
|
||||
++totalFailures;
|
||||
|
@ -252,9 +232,9 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
|
||||
// single file compile
|
||||
SleighCompile compiler = new SleighCompile();
|
||||
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||
compiler.setAllOptions(preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||
allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning,
|
||||
enforceLocalKeyWord, largeTemporaryWarning);
|
||||
enforceLocalKeyWord, largeTemporaryWarning, caseSensitiveRegisterNames);
|
||||
if (i == args.length) {
|
||||
Msg.error(SleighCompile.class, "Missing input file name");
|
||||
return 1;
|
||||
|
@ -280,7 +260,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
}
|
||||
fileout = baseOutName + FILE_OUT_DEFAULT_EXT;
|
||||
|
||||
return run_compilation(filein, fileout, compiler);
|
||||
return compiler.run_compilation(filein, fileout);
|
||||
}
|
||||
|
||||
private static String[] injectOptionsFromFile(String[] args, int index) {
|
||||
|
@ -326,131 +306,4 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
|||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
private static int run_compilation(String filein, String fileout, SleighCompile compiler)
|
||||
throws IOException, RecognitionException {
|
||||
// try {
|
||||
// compiler.parseFromNewFile(filein);
|
||||
//FileInputStream yyin = new FileInputStream(new File(filein));
|
||||
// StringWriter output = new StringWriter();
|
||||
|
||||
// System.out.println(output.toString());
|
||||
// UGLY_STATIC_GLOBAL_COMPILER = null; // Set global pointer up for parser
|
||||
|
||||
// SleighCompiler realCompiler = new SleighCompiler(new StringReader(output.toString()));
|
||||
|
||||
// too late for this because we snarf a token or two on constructor time?
|
||||
// if (yydebug) {
|
||||
// realCompiler.enable_tracing();
|
||||
// } else {
|
||||
// realCompiler.disable_tracing();
|
||||
// }
|
||||
|
||||
LineArrayListWriter writer = new LineArrayListWriter();
|
||||
ParsingEnvironment env = new ParsingEnvironment(writer);
|
||||
try {
|
||||
final SleighCompilePreprocessorDefinitionsAdapater definitionsAdapter =
|
||||
new SleighCompilePreprocessorDefinitionsAdapater(compiler);
|
||||
final File inputFile = new File(filein);
|
||||
FileResolutionResult result = FileUtilities.existsAndIsCaseDependent(inputFile);
|
||||
if (!result.isOk()) {
|
||||
throw new BailoutException("input file \"" + inputFile +
|
||||
"\" is not properly case dependent: " + result.getMessage());
|
||||
}
|
||||
SleighPreprocessor sp = new SleighPreprocessor(definitionsAdapter, inputFile);
|
||||
sp.process(writer);
|
||||
|
||||
CharStream input = new ANTLRStringStream(writer.toString());
|
||||
SleighLexer lex = new SleighLexer(input);
|
||||
lex.setEnv(env);
|
||||
UnbufferedTokenStream tokens = new UnbufferedTokenStream(lex);
|
||||
SleighParser parser = new SleighParser(tokens);
|
||||
parser.setEnv(env);
|
||||
parser.setLexer(lex);
|
||||
SleighParser.spec_return root = parser.spec();
|
||||
/*ANTLRUtil.debugTree(root.getTree(),
|
||||
new PrintStream(new FileOutputStream("blargh.tree")));*/
|
||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(root.getTree());
|
||||
nodes.setTokenStream(tokens);
|
||||
// ANTLRUtil.debugNodeStream(nodes, System.out);
|
||||
SleighCompiler walker = new SleighCompiler(nodes);
|
||||
|
||||
int parseres = -1;
|
||||
try {
|
||||
parseres = walker.root(env, compiler); // Try to parse
|
||||
}
|
||||
catch (SleighError e) {
|
||||
compiler.reportError(e.location, e.getMessage());
|
||||
}
|
||||
// yyin.close();
|
||||
if (parseres == 0) {
|
||||
if (compiler.noplist.size() > 0) {
|
||||
if (compiler.warnallnops) {
|
||||
IteratorSTL<String> iter;
|
||||
for (iter = compiler.noplist.begin(); !iter.isEnd(); iter.increment()) {
|
||||
Msg.warn(SleighCompile.class, iter.get());
|
||||
}
|
||||
}
|
||||
Msg.warn(SleighCompile.class,
|
||||
compiler.noplist.size() + " NOP constructors found");
|
||||
if (!compiler.warnallnops) {
|
||||
Msg.warn(SleighCompile.class, "Use -n switch to list each individually");
|
||||
}
|
||||
}
|
||||
compiler.process(); // Do all the post-processing
|
||||
}
|
||||
if ((parseres == 0) && (compiler.numErrors() == 0)) {
|
||||
// If no errors
|
||||
// try {
|
||||
PrintStream s = new PrintStream(new FileOutputStream(new File(fileout)));
|
||||
compiler.saveXml(s); // Dump output xml
|
||||
s.close();
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// throw new SleighError("Unable to open output file: "
|
||||
// + fileout);
|
||||
// }
|
||||
}
|
||||
else {
|
||||
Msg.error(SleighCompile.class, "No output produced");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
catch (BailoutException e) {
|
||||
Msg.error(SleighCompile.class, "Unrecoverable error(s), halting compilation", e);
|
||||
return 3;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
Msg.error(SleighCompile.class, "Unrecoverable error(s), halting compilation", e);
|
||||
return 4;
|
||||
}
|
||||
catch (PreprocessorException e) {
|
||||
Msg.error(SleighCompile.class, e.getMessage());
|
||||
Msg.error(SleighCompile.class, "Errors during preprocessing, halting compilation");
|
||||
return 5;
|
||||
}
|
||||
// catch (LowlevelError err) {
|
||||
// Msg.info(this, "Unrecoverable error: " + err.getMessage());
|
||||
// err.printStackTrace();
|
||||
// return 2;
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// Msg.info(this, "Couldn't close file: " + e.getMessage());
|
||||
// return 1;
|
||||
// }
|
||||
// }
|
||||
// catch (FileNotFoundException e) {
|
||||
// Msg.info(this, "Unable to open specfile: " + filein);
|
||||
// return 2;
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// catch (ParseException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -220,8 +220,6 @@ public abstract class Translate implements BasicSpaceProvider {
|
|||
public void setContextDefault(String name, int val) {
|
||||
}
|
||||
|
||||
public abstract void addRegister(String nm, AddrSpace base, long offset, int size);
|
||||
|
||||
public abstract VarnodeData getRegister(String nm);
|
||||
|
||||
public abstract String getRegisterName(AddrSpace base, long off, int size);
|
||||
|
@ -293,15 +291,6 @@ public abstract class Translate implements BasicSpaceProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
void addRegisterList(String[] nms, int num, AddrSpace base, long offset, int size, int skip) { // Add names assigning indices in order
|
||||
// allocating -size- space for each starting at -offset-
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
addRegister(nms[i], base, offset + skip * i, size);
|
||||
}
|
||||
}
|
||||
|
||||
// Associate a particular register or memory location with an address space
|
||||
// The canonical example is the \b stack \b pointer and the stack space.
|
||||
// The \b basespace is the so-called stack space, which is really a
|
||||
|
@ -542,8 +531,8 @@ public abstract class Translate implements BasicSpaceProvider {
|
|||
|
||||
public AddrSpace getSpaceBySpacebase(Address loc, int size) { // Get space associated with spacebase register
|
||||
AddrSpace id;
|
||||
for (int i = 0; i < baselist.size(); ++i) {
|
||||
id = baselist.get(i);
|
||||
for (AddrSpace element : baselist) {
|
||||
id = element;
|
||||
int numspace = numSpacebase(id);
|
||||
for (int j = 0; j < numspace; ++j) {
|
||||
VarnodeData point = getSpacebase(id, j);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue