HighSymbol support for isThis and isHidden properties

This commit is contained in:
caheckman 2020-07-24 13:15:22 -04:00
parent db139d2b81
commit bcc0f7fe38
3 changed files with 73 additions and 3 deletions

View file

@ -362,6 +362,8 @@ void Symbol::saveXmlHeader(ostream &s) const
a_v_b(s,"hiddenretparm",true);
if ((dispflags&isolate)!=0)
a_v_b(s,"merge",false);
if ((dispflags&is_this_ptr)!=0)
a_v_b(s,"thisptr",true);
int4 format = getDisplayFormat();
if (format != 0) {
s << " format=\"";
@ -461,6 +463,10 @@ void Symbol::restoreXmlHeader(const Element *el)
if (xml_readbool(el->getAttributeValue(i)))
flags |= Varnode::typelock;
}
else if (attName == "thisptr") {
if (xml_readbool(el->getAttributeValue(i)))
dispflags |= is_this_ptr;
}
break;
case 'v':
if (attName == "volatile") {

View file

@ -183,7 +183,8 @@ public:
force_char = 5, ///< Force integer to be printed as a character constant
size_typelock = 8, ///< Only the size of the symbol is typelocked
isolate = 16, ///< Symbol should not speculatively merge automatically
merge_problems = 32 ///< Set if some SymbolEntrys did not get merged
merge_problems = 32, ///< Set if some SymbolEntrys did not get merged
is_this_ptr = 64 ///< We are the "this" symbol for a class method
};
Symbol(Scope *sc,const string &nm,Datatype *ct); ///< Construct given a name and data-type
@ -198,6 +199,7 @@ public:
bool isTypeLocked(void) const { return ((flags&Varnode::typelock)!=0); } ///< Is the Symbol type-locked
bool isNameLocked(void) const { return ((flags&Varnode::namelock)!=0); } ///< Is the Symbol name-locked
bool isSizeTypeLocked(void) const { return ((dispflags & size_typelock)!=0); } ///< Is the Symbol size type-locked
bool isThisPointer(void) const { return ((dispflags & is_this_ptr)!=0); } ///< Is \b this the "this" pointer
bool isIndirectStorage(void) const { return ((flags&Varnode::indirectstorage)!=0); } ///< Is storage really a pointer to the true Symbol
bool isHiddenReturn(void) const { return ((flags&Varnode::hiddenretparm)!=0); } ///< Is this a reference to the function return value
bool isNameUndefined(void) const; ///< Does \b this have an undefined name

View file

@ -17,10 +17,11 @@ package ghidra.program.model.pcode;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.VariableStorage;
import ghidra.program.model.lang.DynamicVariableStorage;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
@ -40,6 +41,8 @@ public class HighSymbol {
protected int categoryIndex; // Numbering within the sub-class
private boolean namelock; // Is this variable's name locked
private boolean typelock; // Is this variable's datatype locked
private boolean isThis; // True if we are "this" symbol for function method call
private boolean isHidden; // True if we are hidden symbol containing pointer to where return value is stored
private long id; // Unique id of this symbol
protected SymbolEntry[] entryList; // List of mappings for this symbol
@ -53,6 +56,8 @@ public class HighSymbol {
protected HighSymbol(HighFunction func) {
function = func;
dtmanage = function.getDataTypeManager();
isThis = false;
isHidden = false;
}
/**
@ -69,6 +74,8 @@ public class HighSymbol {
type = tp;
namelock = false;
typelock = false;
isThis = false;
isHidden = false;
id = uniqueId;
category = -1;
categoryIndex = -1;
@ -92,6 +99,8 @@ public class HighSymbol {
type = tp;
namelock = nlock;
typelock = tlock;
isThis = false;
isHidden = false;
id = uniqueId;
category = -1;
categoryIndex = -1;
@ -101,6 +110,15 @@ public class HighSymbol {
if (entryList == null) {
entryList = new SymbolEntry[1];
entryList[0] = entry;
if (entry.getStorage().isAutoStorage()) {
AutoParameterType autoType = entry.getStorage().getAutoParameterType();
if (autoType == AutoParameterType.THIS) {
isThis = true;
}
else if (autoType == AutoParameterType.RETURN_STORAGE_PTR) {
isHidden = true;
}
}
}
else {
SymbolEntry[] newList = new SymbolEntry[entryList.length + 1];
@ -316,6 +334,20 @@ public class HighSymbol {
return false;
}
/**
* @return true if symbol is a "this" pointer for a class method
*/
public boolean isThisPointer() {
return isThis;
}
/**
* @return true is symbol holds a pointer to where a function's return value should be stored
*/
public boolean isHiddenReturn() {
return isHidden;
}
/**
* @return the first mapping object attached to this symbol
*/
@ -349,6 +381,12 @@ public class HighSymbol {
if (isIsolated()) {
SpecXmlUtils.encodeBooleanAttribute(buf, "merge", false);
}
if (isThis) {
SpecXmlUtils.encodeBooleanAttribute(buf, "thisptr", true);
}
if (isHidden) {
SpecXmlUtils.encodeBooleanAttribute(buf, "hiddenretparm", true);
}
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "cat", category);
if (categoryIndex >= 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", categoryIndex);
@ -382,6 +420,16 @@ public class HighSymbol {
if ((namelockstr != null) && (SpecXmlUtils.decodeBoolean(namelockstr))) {
namelock = true;
}
isThis = false;
String thisstring = symel.getAttribute("thisptr");
if ((thisstring != null) && (SpecXmlUtils.decodeBoolean(thisstring))) {
isThis = true;
}
isHidden = false;
String hiddenstring = symel.getAttribute("hiddenretparm");
if ((hiddenstring != null) && (SpecXmlUtils.decodeBoolean(hiddenstring))) {
isHidden = true;
}
// isolate = false;
// String isolatestr = symel.getAttribute("merge");
// if ((isolatestr != null) && !SpecXmlUtils.decodeBoolean(isolatestr)) {
@ -431,6 +479,20 @@ public class HighSymbol {
entry.restoreXML(parser);
addMapEntry(entry);
}
if ((isThis || isHidden) && entryList != null) {
SymbolEntry entry = entryList[0];
VariableStorage storage = entry.getStorage();
AutoParameterType autoType =
isThis ? AutoParameterType.THIS : AutoParameterType.RETURN_STORAGE_PTR;
try {
VariableStorage newStorage = new DynamicVariableStorage(storage.getProgram(),
autoType, storage.getFirstVarnode());
entryList[0] = new MappedEntry(this, newStorage, entry.getPCAdress());
}
catch (InvalidInputException e) {
throw new PcodeXMLException("Unable to parse auto-parameter");
}
}
}
/**