New Symbol id strategy

This commit is contained in:
caheckman 2019-12-03 10:16:24 -05:00
parent 4560f78833
commit a5ae6e21b0
13 changed files with 302 additions and 163 deletions

View file

@ -44,8 +44,9 @@ public class DynamicSymbol extends HighSymbol {
refs = new Entry[0];
}
public DynamicSymbol(String nm,DataType tp,int size,HighFunction func,Address addr,long hash,int format) {
super(nm,tp,size,addr,func);
public DynamicSymbol(long uniqueId, String nm, DataType tp, int size, HighFunction func,
Address addr, long hash, int format) {
super(uniqueId, nm, tp, size, addr, func);
refs = new Entry[1];
refs[0] = new Entry(addr,hash,format);
}
@ -56,18 +57,21 @@ public class DynamicSymbol extends HighSymbol {
public void addReference(Address addr,long hash,int format) {
Entry[] newrefs = new Entry[refs.length + 1];
for(int i=0;i<refs.length;++i)
for(int i=0;i<refs.length;++i) {
newrefs[i] = refs[i];
}
newrefs[refs.length] = new Entry(addr,hash,format);
refs = newrefs;
if (refs.length == 1)
{
pcaddr = addr; // Store first address as official pcaddr for symbol
}
}
protected void buildHashXML(StringBuilder buf) {
for(int i=0;i<refs.length;++i) {
buf.append("<hash val=\"0x").append(Long.toHexString(refs[i].hash)).append("\"/>");
buildRangelistXML(buf, refs[i].pcaddr);
for (Entry ref : refs) {
buf.append("<hash val=\"0x").append(Long.toHexString(ref.hash)).append("\"/>");
buildRangelistXML(buf, ref.pcaddr);
}
}
@ -84,15 +88,16 @@ public class DynamicSymbol extends HighSymbol {
}
@Override
public int restoreXML(XmlPullParser parser, HighFunction func) throws PcodeXMLException {
public void restoreXML(XmlPullParser parser, HighFunction func) throws PcodeXMLException {
XmlElement symel = parser.start("symbol");
int symbolId = restoreSymbolXML(symel, func);
restoreSymbolXML(symel, func);
type = func.getDataTypeManager().readXMLDataType(parser);
size = type.getLength();
parser.end(symel);
if (size == 0)
if (size == 0) {
throw new PcodeXMLException("Invalid symbol 0-sized data-type: " + type.getName());
}
while(parser.peek().isStart()) {
long hash = 0;
int format = 0;
@ -103,7 +108,6 @@ public class DynamicSymbol extends HighSymbol {
Address addr = parseRangeList(parser);
addReference(addr,hash,format);
}
return symbolId;
}
public static String buildSymbolXML(PcodeDataTypeManager dtmanage, String nm,
@ -117,8 +121,9 @@ public class DynamicSymbol extends HighSymbol {
SpecXmlUtils.encodeBooleanAttribute(res, "typelock", tl);
SpecXmlUtils.encodeBooleanAttribute(res, "namelock", nl);
SpecXmlUtils.encodeBooleanAttribute(res, "readonly", ro);
if (isVolatile)
if (isVolatile) {
SpecXmlUtils.encodeBooleanAttribute(res, "volatile", true);
}
res.append(">\n");
res.append(dtmanage.buildTypeRef(dt, length));
res.append("</symbol>\n");

View file

@ -36,14 +36,16 @@ public class EquateSymbol extends DynamicSymbol {
public EquateSymbol() {
}
public EquateSymbol(String nm,long val,HighFunction func,Address addr,long hash,int format) {
super(nm, DataType.DEFAULT, 1, func, addr, hash, format);
public EquateSymbol(long uniqueId, String nm, long val, HighFunction func, Address addr,
long hash, int format) {
super(uniqueId, nm, DataType.DEFAULT, 1, func, addr, hash, format);
value = val;
convert = FORMAT_DEFAULT;
}
public EquateSymbol(int conv,long val,HighFunction func,Address addr,long hash,int format) {
super("", DataType.DEFAULT, 1, func, addr, hash, format);
public EquateSymbol(long uniqueId, int conv, long val, HighFunction func, Address addr,
long hash, int format) {
super(uniqueId, "", DataType.DEFAULT, 1, func, addr, hash, format);
value = val;
convert = conv;
}
@ -51,9 +53,9 @@ public class EquateSymbol extends DynamicSymbol {
public long getValue() { return value; }
@Override
public int restoreXML(XmlPullParser parser, HighFunction func) throws PcodeXMLException {
public void restoreXML(XmlPullParser parser, HighFunction func) throws PcodeXMLException {
XmlElement symel = parser.start("equatesymbol");
int symbolId = restoreSymbolXML(symel, func);
restoreSymbolXML(symel, func);
type = DataType.DEFAULT;
size = 1;
convert = FORMAT_DEFAULT;
@ -92,7 +94,6 @@ public class EquateSymbol extends DynamicSymbol {
Address addr = parseRangeList(parser);
addReference(addr,hash,format);
}
return symbolId;
}
@Override

View file

@ -120,7 +120,7 @@ public class HighFunction extends PcodeSyntaxTree {
}
@Override
public HighSymbol getSymbol(int symbolId) {
public HighSymbol getSymbol(long symbolId) {
return localSymbols.getSymbol(symbolId);
}
@ -469,9 +469,8 @@ public class HighFunction extends PcodeSyntaxTree {
// Note that we don't need to distinguish between unique,register,ram etc. and don't
// need to separate out first use versus mapped use. When the high local is written
// to database, these issues will be resolved at that point.
sym = localSymbols.newMappedSymbol(highloc.getName(), highloc.getDataType(),
new VariableStorage(func.getProgram(), vn), vn.getPCAddress(), -1,
vn.hashCode());
sym = localSymbols.newMappedSymbol(0, highloc.getName(), highloc.getDataType(),
new VariableStorage(func.getProgram(), vn), vn.getPCAddress(), -1);
reslocal = new HighLocal(highloc.getDataType(), vn, null, vn.getPCAddress(), sym);
resremain = highloc; // Keep remaining varnodes in old high

View file

@ -24,6 +24,7 @@ import ghidra.xml.XmlPullParser;
public abstract class HighSymbol {
public static final long ID_BASE = 0x4000000000000000L; // Put keys in the dynamic symbol portion of the key space
protected String name;
protected DataType type;
protected int size; // Size of this variable
@ -32,13 +33,15 @@ public abstract class HighSymbol {
private boolean namelock; // Is this variable's name locked
private boolean typelock; // Is this variable's datatype locked
private boolean readonly;
private long id; // Unique id of this symbol
private HighVariable highVariable;
public HighSymbol() { // For use with restoreXML
}
public HighSymbol(String nm,DataType tp,int sz,Address pc,HighFunction func) {
public HighSymbol(long uniqueId, String nm, DataType tp, int sz, Address pc,
HighFunction func) {
name = nm;
type = tp;
size = sz;
@ -46,8 +49,13 @@ public abstract class HighSymbol {
namelock = false;
typelock = false;
function = func;
id = uniqueId;
}
public long getId() {
return id;
}
public void setHighVariable(HighVariable high) {
this.highVariable = high;
}
@ -102,25 +110,26 @@ public abstract class HighSymbol {
public abstract String buildXML();
public abstract int restoreXML(XmlPullParser parser,HighFunction func) throws PcodeXMLException;
public abstract void restoreXML(XmlPullParser parser, HighFunction func)
throws PcodeXMLException;
protected int restoreSymbolXML(XmlElement symel,HighFunction func) throws PcodeXMLException {
protected void restoreSymbolXML(XmlElement symel, HighFunction func) throws PcodeXMLException {
function = func;
int symbolId = SpecXmlUtils.decodeInt(symel.getAttribute("id"));
if (symbolId == 0) {
id = SpecXmlUtils.decodeLong(symel.getAttribute("id"));
if (id == 0) {
throw new PcodeXMLException("missing unique symbol id");
}
typelock = false;
String typelockstr = symel.getAttribute("typelock");
if ((typelockstr != null) && (SpecXmlUtils.decodeBoolean(typelockstr)))
if ((typelockstr != null) && (SpecXmlUtils.decodeBoolean(typelockstr))) {
typelock = true;
}
namelock = false;
String namelockstr = symel.getAttribute("namelock");
if ((namelockstr != null) && (SpecXmlUtils.decodeBoolean(namelockstr)))
if ((namelockstr != null) && (SpecXmlUtils.decodeBoolean(namelockstr))) {
namelock = true;
}
name = symel.getAttribute("name");
return symbolId;
}
protected Address parseRangeList(XmlPullParser parser) {

View file

@ -39,8 +39,9 @@ public class LocalSymbolMap {
private HighFunction func; // Function to which these variables are local
private String spacename;
private HashMap<MappedVarKey, HighSymbol> addrMappedSymbols; // Hashed by addr and pcaddr
private HashMap<Integer, HighSymbol> symbolMap; // Hashed by unique key
private HashMap<Long, HighSymbol> symbolMap; // Hashed by unique key
private MappedSymbol[] paramSymbols;
private long uniqueSymbolId; // Next available symbol id
/**
* @param highFunc HighFunction the local variables are defined within.
@ -50,21 +51,31 @@ public class LocalSymbolMap {
func = highFunc;
spacename = spcname;
addrMappedSymbols = new HashMap<MappedVarKey, HighSymbol>();
symbolMap = new HashMap<Integer, HighSymbol>();
symbolMap = new HashMap<Long, HighSymbol>();
paramSymbols = new MappedSymbol[0];
uniqueSymbolId = 0;
}
public HighFunction getHighFunction() {
return func;
}
/**
* Assign a unique id to a new symbol being put in this container.
* @return the unique id
*/
private long getNextId() {
long key = HighSymbol.ID_BASE + uniqueSymbolId;
uniqueSymbolId += 1;
return key;
}
/**
* Populate the local variable map from information attached to the Program DB's function.
* @param includeDefaultNames is true if default symbol names should be considered locked
*/
public void grabFromFunction(boolean includeDefaultNames) {
Function dbFunction = func.getFunction();
int uniqueSymbolId = 0;
Variable locals[] = dbFunction.getLocalVariables();
for (Variable local : locals) {
Variable var = local;
@ -82,18 +93,18 @@ public class LocalSymbolMap {
String name = var.getName();
VariableStorage storage = var.getVariableStorage();
long id = getNextId();
Address defAddr = null;
if (!storage.isStackStorage()) {
defAddr = dbFunction.getEntryPoint().addWrap(var.getFirstUseOffset());
}
HighSymbol sym;
if (storage.isHashStorage()) {
sym =
newDynamicSymbol(name, dt, sz, storage.getFirstVarnode().getOffset(), defAddr,
0, ++uniqueSymbolId);
sym = newDynamicSymbol(id, name, dt, sz, storage.getFirstVarnode().getOffset(),
defAddr, 0);
}
else {
sym = newMappedSymbol(name, dt, storage, defAddr, -1, ++uniqueSymbolId);
sym = newMappedSymbol(id, name, dt, storage, defAddr, -1);
}
sym.setTypeLock(istypelock);
sym.setNameLock(isnamelock);
@ -116,8 +127,9 @@ public class LocalSymbolMap {
String name = var.getName();
VariableStorage storage = var.getVariableStorage();
Address resAddr = storage.isStackStorage() ? null : pcaddr;
long id = getNextId();
MappedSymbol paramSymbol =
newMappedSymbol(name, dt, storage, resAddr, i, ++uniqueSymbolId);
newMappedSymbol(id, name, dt, storage, resAddr, i);
paramList.add(paramSymbol);
boolean namelock = true;
if (!includeDefaultNames) {
@ -131,7 +143,7 @@ public class LocalSymbolMap {
paramList.toArray(paramSymbols);
Arrays.sort(paramSymbols, PARAM_SYMBOL_SLOT_COMPARATOR);
uniqueSymbolId = grabEquates(dbFunction, uniqueSymbolId);
grabEquates(dbFunction);
}
private boolean isUserDefinedName(String name) {
@ -164,9 +176,9 @@ public class LocalSymbolMap {
res = new EquateSymbol();
}
int symbolId = res.restoreXML(parser, func);
res.restoreXML(parser, func);
parser.end(node);
insertSymbol(res,symbolId);
insertSymbol(res);
return res;
}
@ -290,7 +302,7 @@ public class LocalSymbolMap {
* @param id symbol-id
* @return variable or null if not found
*/
public HighSymbol getSymbol(int id) {
public HighSymbol getSymbol(long id) {
return symbolMap.get(id);
}
@ -316,43 +328,60 @@ public class LocalSymbolMap {
return false;
}
public MappedSymbol newMappedSymbol(String nm, DataType dt, VariableStorage store,
Address pcaddr, int slot, int id) {
MappedSymbol sym = new MappedSymbol(nm, dt, store, pcaddr, func, slot);
insertSymbol(sym,id);
public MappedSymbol newMappedSymbol(long id, String nm, DataType dt, VariableStorage store,
Address pcaddr, int slot) {
if (id == 0) {
id = getNextId();
}
MappedSymbol sym = new MappedSymbol(id, nm, dt, store, pcaddr, func, slot);
insertSymbol(sym);
return sym;
}
public DynamicSymbol newDynamicSymbol(String nm, DataType dt, int sz, long hash,
Address pcaddr, int format, int id) {
DynamicSymbol sym = new DynamicSymbol(nm, dt, sz, func, pcaddr, hash, format);
insertSymbol(sym,id);
public DynamicSymbol newDynamicSymbol(long id, String nm, DataType dt, int sz, long hash,
Address pcaddr, int format) {
if (id == 0) {
id = getNextId();
}
DynamicSymbol sym = new DynamicSymbol(id, nm, dt, sz, func, pcaddr, hash, format);
insertSymbol(sym);
return sym;
}
private void insertSymbol(HighSymbol sym,int id) {
private void insertSymbol(HighSymbol sym) {
long uniqueId = sym.getId();
if ((uniqueId >> 56) == (HighSymbol.ID_BASE >> 56)) {
long val = uniqueId & 0x7fffffff;
if (val > uniqueSymbolId) {
uniqueSymbolId = val;
}
}
if (sym instanceof MappedSymbol) {
MappedSymbol mapSym = (MappedSymbol)sym;
MappedVarKey key = new MappedVarKey(mapSym.getStorage(),mapSym.getPCAddress());
addrMappedSymbols.put(key, sym);
}
symbolMap.put(id, sym);
symbolMap.put(uniqueId, sym);
}
private void newEquateSymbol(String nm, long val, long hash, Address addr, int format,
private void newEquateSymbol(long uniqueId, String nm, long val, long hash, Address addr,
int format,
TreeMap<String, DynamicSymbol> constantSymbolMap) {
DynamicSymbol eqSymbol = constantSymbolMap.get(nm);
if (eqSymbol != null) {
eqSymbol.addReference(addr, hash, format); // New reference to same symbol
return;
}
if (uniqueId == 0) {
uniqueId = getNextId();
}
int conv = EquateSymbol.convertName(nm, val);
if (conv < 0) {
eqSymbol = new EquateSymbol(nm, val, func, addr, hash, format);
eqSymbol = new EquateSymbol(uniqueId, nm, val, func, addr, hash, format);
eqSymbol.setNameLock(true);
}
else {
eqSymbol = new EquateSymbol(conv, val, func, addr, hash, format);
eqSymbol = new EquateSymbol(uniqueId, conv, val, func, addr, hash, format);
}
//Do NOT setTypeLock
constantSymbolMap.put(nm, eqSymbol);
@ -361,10 +390,8 @@ public class LocalSymbolMap {
/**
* Build dynamic symbols based on equates
* @param dbFunction is the function to pull equates for
* @param uniqueSymbolId is the next available symbol id
* @return the next available symbol id
*/
private int grabEquates(Function dbFunction, int uniqueSymbolId) {
private void grabEquates(Function dbFunction) {
TreeMap<String, DynamicSymbol> constantSymbolMap = null;
// Find named constants via Equates
Program program = dbFunction.getProgram();
@ -383,7 +410,7 @@ public class LocalSymbolMap {
if (constantSymbolMap == null) {
constantSymbolMap = new TreeMap<String, DynamicSymbol>();
}
newEquateSymbol(eq.getDisplayName(), eq.getValue(), element, defAddr, 0,
newEquateSymbol(0, eq.getDisplayName(), eq.getValue(), element, defAddr, 0,
constantSymbolMap);
}
}
@ -405,10 +432,10 @@ public class LocalSymbolMap {
// Add constant dynamic symbols to map
if (constantSymbolMap != null) {
for (DynamicSymbol sym : constantSymbolMap.values()) {
symbolMap.put(++uniqueSymbolId, sym);
long id = getNextId();
symbolMap.put(id, sym);
}
}
return uniqueSymbolId;
}
/**

View file

@ -33,21 +33,25 @@ public class MappedSymbol extends HighSymbol {
public MappedSymbol() { // For use with restoreXML
}
public MappedSymbol(String name, DataType dt, VariableStorage store, Address pcaddr,
public MappedSymbol(long uniqueId, String name, DataType dt, VariableStorage store,
Address pcaddr,
HighFunction func, int slot) {
super(name, dt, store.size(), pcaddr, func);
super(uniqueId, name, dt, store.size(), pcaddr, func);
if (store.size() != dt.getLength()) {
if (ParamEntry.getMetatype(dt) != ParamEntry.TYPE_FLOAT)
if (ParamEntry.getMetatype(dt) != ParamEntry.TYPE_FLOAT) {
throw new IllegalArgumentException("Specified size does not match storage size");
}
}
this.storage = store;
this.slot = slot;
Varnode rep = function.createFromStorage(null, storage, dt.getLength());
HighVariable var;
if (slot < 0)
if (slot < 0) {
var = new HighLocal(type, rep, null, pcaddr, this);
else
}
else {
var = new HighParam(type, rep, pcaddr, slot, this);
}
setHighVariable(var);
var.setHighOnInstances();
}
@ -71,26 +75,29 @@ public class MappedSymbol extends HighSymbol {
}
StringBuilder res = new StringBuilder();
int cat = isParameter() ? 0 : -1;
String sym = buildSymbolXML(function.getDataTypeManager(),name, type, size,
String sym = buildSymbolXML(function.getDataTypeManager(), getId(), name, type, size,
isTypeLocked(), isNameLocked(), false, false, cat, slot);
int logicalsize = 0; // Assume datatype size and storage size are the same
if ((type != null) && (type.getLength() != storage.size())) // If sizesdiffer
if ((type != null) && (type.getLength() != storage.size()))
{
logicalsize = type.getLength(); // Force a logicalsize
}
String addrRes = Varnode.buildXMLAddress(storage.getVarnodes(), logicalsize);
buildMapSymXML(res, addrRes, getPCAddress(), sym);
return res.toString();
}
@Override
public int restoreXML(XmlPullParser parser,HighFunction func) throws PcodeXMLException {
public void restoreXML(XmlPullParser parser, HighFunction func) throws PcodeXMLException {
XmlElement symel = parser.start("symbol");
int symbolId = restoreSymbolXML(symel, func);
restoreSymbolXML(symel, func);
slot = -1;
int cat = -1;
if (symel.hasAttribute("cat")) {
cat = SpecXmlUtils.decodeInt(symel.getAttribute("cat"));
if (cat == 0)
if (cat == 0) {
slot = SpecXmlUtils.decodeInt(symel.getAttribute("index"));
}
}
type = func.getDataTypeManager().readXMLDataType(parser);
parser.end(symel);
@ -129,26 +136,34 @@ public class MappedSymbol extends HighSymbol {
pcaddr = parseRangeList(parser);
Varnode rep = function.createFromStorage(addr, storage, sz);
HighVariable var;
if (slot < 0)
if (slot < 0) {
var = new HighLocal(type, rep, null, pcaddr, this);
else
}
else {
var = new HighParam(type, rep, pcaddr, slot, this);
}
setHighVariable(var);
var.setHighOnInstances();
return symbolId;
}
public static String buildSymbolXML(PcodeDataTypeManager dtmanage, String nm,
public static String buildSymbolXML(PcodeDataTypeManager dtmanage, long uniqueId, String nm,
DataType dt, int length, boolean tl, boolean nl, boolean ro,
boolean isVolatile, int cat, int slot) {
StringBuilder res = new StringBuilder();
res.append("<symbol");
if ((uniqueId >> 56) == (ID_BASE >> 56)) {
uniqueId = 0; // Don't send down internal ids
}
if (uniqueId != 0) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(res, "id", uniqueId);
}
SpecXmlUtils.xmlEscapeAttribute(res, "name", nm);
SpecXmlUtils.encodeBooleanAttribute(res, "typelock", tl);
SpecXmlUtils.encodeBooleanAttribute(res, "namelock", nl);
SpecXmlUtils.encodeBooleanAttribute(res, "readonly", ro);
if (isVolatile)
if (isVolatile) {
SpecXmlUtils.encodeBooleanAttribute(res, "volatile", true);
}
SpecXmlUtils.encodeSignedIntegerAttribute(res, "cat", cat);
if (slot >= 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(res, "index", slot);

View file

@ -57,7 +57,8 @@ public interface PcodeFactory {
public VariableStorage buildStorage(Varnode vn) throws InvalidInputException;
public Varnode getRef(int refid);
public PcodeOp getOpRef(int refid);
public HighSymbol getSymbol(int symbolId);
public HighSymbol getSymbol(long symbolId);
public Varnode setInput(Varnode vn,boolean val);
public void setAddrTied(Varnode vn,boolean val);
public void setPersistant(Varnode vn,boolean val);

View file

@ -142,8 +142,9 @@ public class PcodeSyntaxTree implements PcodeFactory {
// bad prototypes causing the decompiler to produce weird stuff
// TODO: We should emit some kind of warning
int sz = 0;
for (Varnode piece : pieces)
for (Varnode piece : pieces) {
sz += piece.getSize();
}
Address uniqaddr = addrFactory.getUniqueSpace().getAddress(0x20000000);
storage = new VariableStorage(datatypeManager.getProgram(),uniqaddr,sz);
}
@ -156,26 +157,30 @@ public class PcodeSyntaxTree implements PcodeFactory {
else {
offObject = new Integer((int)offset);
offset += roundsize;
if (offset > joinAllocate)
if (offset > joinAllocate) {
joinAllocate = (int)offset;
}
}
if (joinmap == null)
if (joinmap == null) {
joinmap = new HashMap<Integer,VariableStorage>();
}
joinmap.put(offObject, storage);
return storage;
}
private VariableStorage findJoinStorage(long offset) {
if (joinmap == null)
if (joinmap == null) {
return null;
}
return joinmap.get(new Integer((int)offset));
}
@Override
public VariableStorage buildStorage(Varnode vn) throws InvalidInputException {
Address addr = vn.getAddress();
if (addr.getAddressSpace().getType() == AddressSpace.TYPE_VARIABLE)
if (addr.getAddressSpace().getType() == AddressSpace.TYPE_VARIABLE) {
return findJoinStorage(addr.getOffset());
}
return new VariableStorage(datatypeManager.getProgram(),vn);
}
@ -306,10 +311,12 @@ public class PcodeSyntaxTree implements PcodeFactory {
@Override
public Varnode newVarnode(int sz, Address addr, int id) {
Varnode vn = vbank.create(sz, addr, id);
if (uniqId <= id)
if (uniqId <= id) {
uniqId = id + 1;
if (refmap != null)
}
if (refmap != null) {
refmap.put(id, vn);
}
return vn;
}
@ -342,10 +349,12 @@ public class PcodeSyntaxTree implements PcodeFactory {
@Override
public Varnode setInput(Varnode vn, boolean val) {
if ((!vn.isInput()) && val)
if ((!vn.isInput()) && val) {
return vbank.setInput(vn);
if (vn.isInput() && (!val))
}
if (vn.isInput() && (!val)) {
vbank.makeFree(vn);
}
return vn;
}
@ -360,13 +369,14 @@ public class PcodeSyntaxTree implements PcodeFactory {
@Override
public Varnode getRef(int id) {
if (refmap == null)
if (refmap == null) {
return null;
}
return refmap.get(id);
}
@Override
public HighSymbol getSymbol(int symbolId) {
public HighSymbol getSymbol(long symbolId) {
return null;
}
@ -410,8 +420,9 @@ public class PcodeSyntaxTree implements PcodeFactory {
@Override
public PcodeOp getOpRef(int id) {
if (oprefmap == null)
if (oprefmap == null) {
buildOpRefs();
}
return oprefmap.get(id);
}
@ -437,12 +448,16 @@ public class PcodeSyntaxTree implements PcodeFactory {
public void setOutput(PcodeOp op, Varnode vn) {
if (vn == op.getOutput())
{
return; // Output already set to this
if (op.getOutput() != null)
}
if (op.getOutput() != null) {
unSetOutput(op);
}
if (vn.getDef() != null) // Varnode is already an output
if (vn.getDef() != null) {
unSetOutput(vn.getDef());
}
vn = vbank.setDef(vn, op);
op.setOutput(vn);
}
@ -450,16 +465,21 @@ public class PcodeSyntaxTree implements PcodeFactory {
public void unSetOutput(PcodeOp op) {
Varnode vn = op.getOutput();
if (vn == null)
{
return; // Nothing to do
}
op.setOutput(null);
vbank.makeFree(vn);
}
public void setInput(PcodeOp op, Varnode vn, int slot) {
if (slot >= op.getNumInputs())
{
op.setInput(null, slot); // Expand number of inputs as necessary
if (op.getInput(slot) != null)
}
if (op.getInput(slot) != null) {
unSetInput(op, slot);
}
if (vn != null) {
VarnodeAST vnast = (VarnodeAST) vn;
vnast.addDescendant(op);
@ -484,29 +504,35 @@ public class PcodeSyntaxTree implements PcodeFactory {
public void unlink(PcodeOpAST op) {
unSetOutput(op);
for (int i = 0; i < op.getNumInputs(); ++i)
for (int i = 0; i < op.getNumInputs(); ++i) {
unSetInput(op, i);
if (op.getParent() != null)
}
if (op.getParent() != null) {
unInsert(op);
}
}
@Override
public PcodeOp newOp(SequenceNumber sq, int opc, ArrayList<Varnode> inputs, Varnode output)
throws UnknownInstructionException {
PcodeOp op = opbank.create(opc, inputs.size(), sq);
if (output != null)
if (output != null) {
setOutput(op, output);
for (int i = 0; i < inputs.size(); ++i)
}
for (int i = 0; i < inputs.size(); ++i) {
setInput(op, inputs.get(i), i);
if (oprefmap != null)
}
if (oprefmap != null) {
oprefmap.put(sq.getTime(), op);
}
return op;
}
private void readVarnodeXML(XmlPullParser parser) throws PcodeXMLException {
XmlElement el = parser.start("varnodes");
while (parser.peek().isStart())
while (parser.peek().isStart()) {
Varnode.readXML(parser, this);
}
parser.end(el);
}
@ -524,8 +550,9 @@ public class PcodeSyntaxTree implements PcodeFactory {
bl.insertEnd(op);
}
int index = bl.getIndex();
while (bblocks.size() <= index)
while (bblocks.size() <= index) {
bblocks.add(null);
}
bblocks.set(index, bl);
parser.end(el);
}
@ -542,17 +569,20 @@ public class PcodeSyntaxTree implements PcodeFactory {
public void readXML(XmlPullParser parser) throws PcodeXMLException {
XmlElement el = parser.start("ast");
if (!vbank.isEmpty())
if (!vbank.isEmpty()) {
clear();
}
readVarnodeXML(parser);
buildVarnodeRefs(); // Build the HashMap
BlockMap blockMap = new BlockMap(addrFactory);
while (parser.peek().isStart()) {
XmlElement subel = parser.peek();
if (subel.getName().equals("block"))
if (subel.getName().equals("block")) {
readBasicBlockXML(parser, blockMap); // Read a basic block and all its PcodeOps
else // Read block edges
}
else {
readBlockEdgeXML(parser);
}
}
parser.end(el);
}