mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
New Symbol id strategy
This commit is contained in:
parent
4560f78833
commit
a5ae6e21b0
13 changed files with 302 additions and 163 deletions
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue