populate HighFunctionShellSymbol in GlobalSymbolMap

This commit is contained in:
caheckman 2019-12-20 16:00:54 -05:00
parent 97b43b9470
commit 7b407f1965
11 changed files with 104 additions and 42 deletions

View file

@ -19,6 +19,7 @@ import java.util.HashMap;
import java.util.Iterator;
import ghidra.program.database.symbol.CodeSymbol;
import ghidra.program.database.symbol.FunctionSymbol;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Data;
@ -38,8 +39,8 @@ public class GlobalSymbolMap {
private Program program;
private HighFunction func; // Is the full decompiler model of the function to which this belongs
private SymbolTable symbolTable; // Used for cross-referencing with Ghidra's database backed Symbols
private HashMap<Address, HighCodeSymbol> addrMappedSymbols; // Look up symbols by address
private HashMap<Long, HighCodeSymbol> symbolMap; // Look up symbol by id
private HashMap<Address, HighSymbol> addrMappedSymbols; // Look up symbols by address
private HashMap<Long, HighSymbol> symbolMap; // Look up symbol by id
private long uniqueSymbolId; // Next available symbol id
/**
@ -50,12 +51,12 @@ public class GlobalSymbolMap {
program = f.getFunction().getProgram();
func = f;
symbolTable = program.getSymbolTable();
addrMappedSymbols = new HashMap<Address, HighCodeSymbol>();
symbolMap = new HashMap<Long, HighCodeSymbol>();
addrMappedSymbols = new HashMap<Address, HighSymbol>();
symbolMap = new HashMap<Long, HighSymbol>();
uniqueSymbolId = 0;
}
private void insertSymbol(HighCodeSymbol sym, Address addr) {
private void insertSymbol(HighSymbol sym, Address addr) {
long uniqueId = sym.getId();
if ((uniqueId >> 56) == (HighSymbol.ID_BASE >> 56)) {
long val = uniqueId & 0x7fffffff;
@ -68,34 +69,44 @@ public class GlobalSymbolMap {
}
/**
* Create a HighCodeSymbol based on the id of the underlying CodeSymbol. The CodeSymbol
* Create a HighSymbol based on the id of the underlying Ghidra Symbol. The Symbol
* is looked up in the SymbolTable and then a HighSymbol is created with the name and
* dataType associated with the CodeSymbol. If a CodeSymbol cannot be found, null is returned.
* dataType associated with the Symbol. If a Symbol cannot be found, null is returned.
* @param id is the database id of the CodeSymbol
* @param dataType is the recovered data-type of the symbol
* @param sz is the size in bytes of the desired symbol
* @return the CodeSymbol wrapped as a HighSymbol or null
*/
public HighCodeSymbol populateSymbol(long id, DataType dataType, int sz) {
public HighSymbol populateSymbol(long id, DataType dataType, int sz) {
if ((id >> 56) == (HighSymbol.ID_BASE >> 56)) {
return null; // This is an internal id, not a database key
}
Symbol symbol = symbolTable.getSymbol(id);
if (symbol == null || !(symbol instanceof CodeSymbol)) {
if (symbol == null) {
return null;
}
if (dataType == null) {
Object dataObj = symbol.getObject();
if (dataObj instanceof Data) {
dataType = ((Data) dataObj).getDataType();
sz = dataType.getLength();
}
else {
dataType = DataType.DEFAULT;
sz = 1;
HighSymbol highSym = null;
if (symbol instanceof CodeSymbol) {
if (dataType == null) {
Object dataObj = symbol.getObject();
if (dataObj instanceof Data) {
dataType = ((Data) dataObj).getDataType();
sz = dataType.getLength();
}
else {
dataType = DataType.DEFAULT;
sz = 1;
}
}
highSym = new HighCodeSymbol((CodeSymbol) symbol, dataType, sz, func);
}
else if (symbol instanceof FunctionSymbol) {
highSym = new HighFunctionShellSymbol(id, symbol.getName(), symbol.getAddress(),
func.getDataTypeManager());
}
else {
return null;
}
HighCodeSymbol highSym = new HighCodeSymbol((CodeSymbol) symbol, dataType, sz, func);
insertSymbol(highSym, symbol.getAddress());
return highSym;
}
@ -125,7 +136,7 @@ public class GlobalSymbolMap {
* @param id is the id
* @return the matching HighSymbol or null
*/
public HighCodeSymbol getSymbol(long id) {
public HighSymbol getSymbol(long id) {
return symbolMap.get(id);
}
@ -134,7 +145,7 @@ public class GlobalSymbolMap {
* @param addr is the given Address
* @return the matching HighSymbol or null
*/
public HighCodeSymbol getSymbol(Address addr) {
public HighSymbol getSymbol(Address addr) {
return addrMappedSymbols.get(addr);
}
@ -142,7 +153,7 @@ public class GlobalSymbolMap {
* Get an iterator over all HighSymbols in this container
* @return the iterator
*/
public Iterator<HighCodeSymbol> getSymbols() {
public Iterator<HighSymbol> getSymbols() {
return symbolMap.values().iterator();
}
}

View file

@ -21,6 +21,7 @@ import java.util.List;
import org.xml.sax.*;
import ghidra.program.database.function.FunctionDB;
import ghidra.program.database.symbol.CodeSymbol;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
@ -80,6 +81,17 @@ public class HighFunction extends PcodeSyntaxTree {
return func;
}
/**
* Get the id with the associated function symbol, if it exists
* @return the id or 0 otherwise
*/
public long getID() {
if (func instanceof FunctionDB) {
return func.getSymbol().getID();
}
return 0;
}
/**
* @return get the language parser used to disassemble
*/
@ -423,15 +435,19 @@ public class HighFunction extends PcodeSyntaxTree {
* this doesn't need to be strictly accurate as it is only used to associate the function with
* addresses near its entry point.
*
* @param id is the id associated with the function symbol
* @param entryPoint pass null to use the function entryPoint, pass an address to force an entry point
* @param size describes how many bytes the function occupies as code
* @return the XML string
*/
public String buildFunctionXML(Address entryPoint, int size) {
public String buildFunctionXML(long id, Address entryPoint, int size) {
// Functions aren't necessarily contiguous with the smallest address being the entry point
// So size needs to be smaller than size of the contiguous chunk containing the entry point
StringBuilder resBuf = new StringBuilder();
resBuf.append("<function");
if (id != 0) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", id);
}
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", func.getName(showNamespace));
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
if (func.isInline()) {

View file

@ -29,12 +29,13 @@ public class HighFunctionShellSymbol extends HighSymbol {
/**
* Construct the function shell given a name and address
* @param id is an id to associate with the new symbol
* @param nm is the given name
* @param addr is the given address
* @param manage is PcodeDataTypeManager to facilitate XML marshaling
*/
public HighFunctionShellSymbol(String nm, Address addr, PcodeDataTypeManager manage) {
super(0, nm, DataType.DEFAULT, true, true, manage);
public HighFunctionShellSymbol(long id, String nm, Address addr, PcodeDataTypeManager manage) {
super(id, nm, DataType.DEFAULT, true, true, manage);
VariableStorage store;
try {
store = new VariableStorage(getProgram(), addr, 1);
@ -46,6 +47,11 @@ public class HighFunctionShellSymbol extends HighSymbol {
addMapEntry(entry);
}
@Override
public boolean isGlobal() {
return true;
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<function");

View file

@ -37,7 +37,7 @@ public class HighFunctionSymbol extends HighSymbol {
* @param function is the decompiler model of the function
*/
public HighFunctionSymbol(Address addr, int size, HighFunction function) {
super(0, "", DataType.DEFAULT, function);
super(function.getID(), "", DataType.DEFAULT, function);
VariableStorage store;
try {
store = new VariableStorage(getProgram(), addr, size);
@ -49,11 +49,16 @@ public class HighFunctionSymbol extends HighSymbol {
addMapEntry(entry);
}
@Override
public boolean isGlobal() {
return true;
}
@Override
public void saveXML(StringBuilder buf) {
MappedEntry entry = (MappedEntry) getFirstWholeMap();
String funcString =
function.buildFunctionXML(entry.getStorage().getMinAddress(), entry.getSize());
function.buildFunctionXML(getId(), entry.getStorage().getMinAddress(), entry.getSize());
buf.append(funcString);
}
}

View file

@ -28,7 +28,7 @@ import ghidra.xml.XmlPullParser;
*/
public class HighGlobal extends HighVariable {
private HighCodeSymbol symbol;
private HighSymbol symbol;
/**
* Constructor for use with restoreXml
@ -38,7 +38,7 @@ public class HighGlobal extends HighVariable {
super(high);
}
public HighGlobal(HighCodeSymbol sym, Varnode vn, Varnode[] inst) {
public HighGlobal(HighSymbol sym, Varnode vn, Varnode[] inst) {
super(sym.getName(), sym.getDataType(), vn, inst, sym.getHighFunction());
symbol = sym;
}