mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Isolate property on Symbols
This commit is contained in:
parent
cdbee3fe39
commit
7fa8245f90
8 changed files with 155 additions and 23 deletions
|
@ -232,6 +232,21 @@ bool Symbol::isNameUndefined(void) const
|
||||||
return ((name.size()==15)&&(0==name.compare(0,7,"$$undef")));
|
return ((name.size()==15)&&(0==name.compare(0,7,"$$undef")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the given value is \b true, any Varnodes that map directly to \b this Symbol,
|
||||||
|
/// will not be speculatively merged with other Varnodes. (Required merges will still happen).
|
||||||
|
/// \param val is the given boolean value
|
||||||
|
void Symbol::setIsolated(bool val)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (val) {
|
||||||
|
dispflags |= isolate;
|
||||||
|
flags |= Varnode::typelock; // Isolated Symbol must be typelocked
|
||||||
|
checkSizeTypeLock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dispflags &= ~((uint4)isolate);
|
||||||
|
}
|
||||||
|
|
||||||
/// \return the first SymbolEntry
|
/// \return the first SymbolEntry
|
||||||
SymbolEntry *Symbol::getFirstWholeMap(void) const
|
SymbolEntry *Symbol::getFirstWholeMap(void) const
|
||||||
|
|
||||||
|
@ -262,6 +277,24 @@ SymbolEntry *Symbol::getMapEntry(const Address &addr) const
|
||||||
return (SymbolEntry *)0;
|
return (SymbolEntry *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Among all the SymbolEntrys that map \b this entire Symbol, calculate
|
||||||
|
/// the position of the given SymbolEntry within the list.
|
||||||
|
/// \param entry is the given SymbolEntry
|
||||||
|
/// \return its position within the list or -1 if it is not in the list
|
||||||
|
int4 Symbol::getMapEntryPosition(const SymbolEntry *entry) const
|
||||||
|
|
||||||
|
{
|
||||||
|
int4 pos = 0;
|
||||||
|
for(int4 i=0;i<mapentry.size();++i) {
|
||||||
|
const SymbolEntry *tmp = &(*mapentry[i]);
|
||||||
|
if (tmp == entry)
|
||||||
|
return pos;
|
||||||
|
if (entry->getSize() == type->getSize())
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/// A value of 0 means the base Symbol name is visible and not overridden in the given use scope.
|
/// A value of 0 means the base Symbol name is visible and not overridden in the given use scope.
|
||||||
/// A value of 1 means the base name may be overridden, but the parent scope name is not.
|
/// A value of 1 means the base name may be overridden, but the parent scope name is not.
|
||||||
/// The minimual number of names that distinguishes \b this Symbol uniquely within the
|
/// The minimual number of names that distinguishes \b this Symbol uniquely within the
|
||||||
|
@ -313,18 +346,20 @@ void Symbol::saveXmlHeader(ostream &s) const
|
||||||
a_v_b(s,"indirectstorage",true);
|
a_v_b(s,"indirectstorage",true);
|
||||||
if ((flags&Varnode::hiddenretparm)!=0)
|
if ((flags&Varnode::hiddenretparm)!=0)
|
||||||
a_v_b(s,"hiddenretparm",true);
|
a_v_b(s,"hiddenretparm",true);
|
||||||
|
if ((dispflags&isolate)!=0)
|
||||||
|
a_v_b(s,"merge",false);
|
||||||
int4 format = getDisplayFormat();
|
int4 format = getDisplayFormat();
|
||||||
if (format != 0) {
|
if (format != 0) {
|
||||||
s << " format=\"";
|
s << " format=\"";
|
||||||
if (format == Symbol::force_hex)
|
if (format == force_hex)
|
||||||
s << "hex\"";
|
s << "hex\"";
|
||||||
else if (format == Symbol::force_dec)
|
else if (format == force_dec)
|
||||||
s << "dec\"";
|
s << "dec\"";
|
||||||
else if (format == Symbol::force_char)
|
else if (format == force_char)
|
||||||
s << "char\"";
|
s << "char\"";
|
||||||
else if (format == Symbol::force_oct)
|
else if (format == force_oct)
|
||||||
s << "oct\"";
|
s << "oct\"";
|
||||||
else if (format == Symbol::force_bin)
|
else if (format == force_bin)
|
||||||
s << "bin\"";
|
s << "bin\"";
|
||||||
else
|
else
|
||||||
s << "hex\"";
|
s << "hex\"";
|
||||||
|
@ -355,15 +390,15 @@ void Symbol::restoreXmlHeader(const Element *el)
|
||||||
if (attName == "format") {
|
if (attName == "format") {
|
||||||
const string &formString(el->getAttributeValue(i));
|
const string &formString(el->getAttributeValue(i));
|
||||||
if (formString == "hex")
|
if (formString == "hex")
|
||||||
dispflags |= Symbol::force_hex;
|
dispflags |= force_hex;
|
||||||
else if (formString == "dec")
|
else if (formString == "dec")
|
||||||
dispflags |= Symbol::force_dec;
|
dispflags |= force_dec;
|
||||||
else if (formString == "char")
|
else if (formString == "char")
|
||||||
dispflags |= Symbol::force_char;
|
dispflags |= force_char;
|
||||||
else if (formString == "oct")
|
else if (formString == "oct")
|
||||||
dispflags |= Symbol::force_oct;
|
dispflags |= force_oct;
|
||||||
else if (formString == "bin")
|
else if (formString == "bin")
|
||||||
dispflags |= Symbol::force_bin;
|
dispflags |= force_bin;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
|
@ -385,6 +420,14 @@ void Symbol::restoreXmlHeader(const Element *el)
|
||||||
flags |= Varnode::indirectstorage;
|
flags |= Varnode::indirectstorage;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
if (attName == "merge") {
|
||||||
|
if (!xml_readbool(el->getAttributeValue(i))) {
|
||||||
|
dispflags |= isolate;
|
||||||
|
flags |= Varnode::typelock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
if (attName == "name")
|
if (attName == "name")
|
||||||
name = el->getAttributeValue(i);
|
name = el->getAttributeValue(i);
|
||||||
|
|
|
@ -181,7 +181,8 @@ public:
|
||||||
force_bin = 4, ///< Force binary printing of constant symbol
|
force_bin = 4, ///< Force binary printing of constant symbol
|
||||||
force_char = 5, ///< Force integer to be printed as a character constant
|
force_char = 5, ///< Force integer to be printed as a character constant
|
||||||
size_typelock = 8, ///< Only the size of the symbol is typelocked
|
size_typelock = 8, ///< Only the size of the symbol is typelocked
|
||||||
isolate = 16 ///< Symbol should not speculatively merge automatically
|
isolate = 16, ///< Symbol should not speculatively merge automatically
|
||||||
|
merge_problems = 32 ///< Set if some SymbolEntrys did not get merged
|
||||||
};
|
};
|
||||||
/// \brief Construct given a name and data-type
|
/// \brief Construct given a name and data-type
|
||||||
Symbol(Scope *sc,const string &nm,Datatype *ct)
|
Symbol(Scope *sc,const string &nm,Datatype *ct)
|
||||||
|
@ -203,11 +204,17 @@ public:
|
||||||
bool isIndirectStorage(void) const { return ((flags&Varnode::indirectstorage)!=0); } ///< Is storage really a pointer to the true Symbol
|
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 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
|
bool isNameUndefined(void) const; ///< Does \b this have an undefined name
|
||||||
|
bool isMultiEntry(void) const { return (wholeCount > 1); } ///< Does \b this have more than one \e entire mapping
|
||||||
|
bool hasMergeProblems(void) const { return ((dispflags & merge_problems)!=0); } ///< Were some SymbolEntrys not merged
|
||||||
|
void setMergeProblems(void) { dispflags |= merge_problems; } ///< Mark that some SymbolEntrys could not be merged
|
||||||
|
bool isIsolated(void) const { return ((dispflags & isolate)!=0); } ///< Return \b true if \b this is isolated from speculative merging
|
||||||
|
void setIsolated(bool val); ///< Set whether \b this Symbol should be speculatively merged
|
||||||
Scope *getScope(void) const { return scope; } ///< Get the scope owning \b this Symbol
|
Scope *getScope(void) const { return scope; } ///< Get the scope owning \b this Symbol
|
||||||
SymbolEntry *getFirstWholeMap(void) const; ///< Get the first entire mapping of the symbol
|
SymbolEntry *getFirstWholeMap(void) const; ///< Get the first entire mapping of the symbol
|
||||||
SymbolEntry *getMapEntry(const Address &addr) const; ///< Get first mapping of the symbol that contains the given Address
|
SymbolEntry *getMapEntry(const Address &addr) const; ///< Get first mapping of the symbol that contains the given Address
|
||||||
int4 numEntries(void) const { return mapentry.size(); } ///< Return the number of SymbolEntrys
|
int4 numEntries(void) const { return mapentry.size(); } ///< Return the number of SymbolEntrys
|
||||||
SymbolEntry *getMapEntry(int4 i) const { return &(*mapentry[i]); } ///< Return the i-th SymbolEntry for \b this Symbol
|
SymbolEntry *getMapEntry(int4 i) const { return &(*mapentry[i]); } ///< Return the i-th SymbolEntry for \b this Symbol
|
||||||
|
int4 getMapEntryPosition(const SymbolEntry *entry) const; ///< Position of given SymbolEntry within \b this multi-entry Symbol
|
||||||
int4 getResolutionDepth(const Scope *useScope) const; ///< Get the number of scope names to print to resolve symbol in given context
|
int4 getResolutionDepth(const Scope *useScope) const; ///< Get the number of scope names to print to resolve symbol in given context
|
||||||
void saveXmlHeader(ostream &s) const; ///< Save basic Symbol properties as XML attributes
|
void saveXmlHeader(ostream &s) const; ///< Save basic Symbol properties as XML attributes
|
||||||
void restoreXmlHeader(const Element *el); ///< Restore basic Symbol properties from XML
|
void restoreXmlHeader(const Element *el); ///< Restore basic Symbol properties from XML
|
||||||
|
|
|
@ -115,6 +115,7 @@ void IfaceDecompCapability::registerCommands(IfaceStatus *status)
|
||||||
status->registerCom(new IfcRename(),"rename");
|
status->registerCom(new IfcRename(),"rename");
|
||||||
status->registerCom(new IfcRetype(),"retype");
|
status->registerCom(new IfcRetype(),"retype");
|
||||||
status->registerCom(new IfcRemove(),"remove");
|
status->registerCom(new IfcRemove(),"remove");
|
||||||
|
status->registerCom(new IfcIsolate(),"isolate");
|
||||||
status->registerCom(new IfcLockPrototype(),"prototype","lock");
|
status->registerCom(new IfcLockPrototype(),"prototype","lock");
|
||||||
status->registerCom(new IfcUnlockPrototype(),"prototype","unlock");
|
status->registerCom(new IfcUnlockPrototype(),"prototype","unlock");
|
||||||
status->registerCom(new IfcCommentInstr(),"comment","instruction");
|
status->registerCom(new IfcCommentInstr(),"comment","instruction");
|
||||||
|
@ -1057,6 +1058,32 @@ void IfcRetype::execute(istream &s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IfcIsolate::execute(istream &s)
|
||||||
|
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
|
||||||
|
s >> ws >> name;
|
||||||
|
if (name.size()==0)
|
||||||
|
throw IfaceParseError("Must specify name of symbol");
|
||||||
|
|
||||||
|
Symbol *sym;
|
||||||
|
vector<Symbol *> symList;
|
||||||
|
if (dcp->fd != (Funcdata *)0)
|
||||||
|
dcp->fd->getScopeLocal()->queryByName(name,symList);
|
||||||
|
else
|
||||||
|
dcp->conf->symboltab->getGlobalScope()->queryByName(name,symList);
|
||||||
|
|
||||||
|
if (symList.empty())
|
||||||
|
throw IfaceExecutionError("No symbol named: "+name);
|
||||||
|
if (symList.size() > 1)
|
||||||
|
throw IfaceExecutionError("More than one symbol named : "+name);
|
||||||
|
else
|
||||||
|
sym = symList[0];
|
||||||
|
|
||||||
|
sym->setIsolated(true);
|
||||||
|
}
|
||||||
|
|
||||||
static Varnode *iface_read_varnode(IfaceDecompData *dcp,istream &s)
|
static Varnode *iface_read_varnode(IfaceDecompData *dcp,istream &s)
|
||||||
|
|
||||||
{ // Return varnode identified by input stream
|
{ // Return varnode identified by input stream
|
||||||
|
|
|
@ -304,6 +304,11 @@ public:
|
||||||
virtual void execute(istream &s);
|
virtual void execute(istream &s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IfcIsolate : public IfaceDecompCommand {
|
||||||
|
public:
|
||||||
|
virtual void execute(istream &s);
|
||||||
|
};
|
||||||
|
|
||||||
class IfcRemove : public IfaceDecompCommand {
|
class IfcRemove : public IfaceDecompCommand {
|
||||||
public:
|
public:
|
||||||
virtual void execute(istream &s);
|
virtual void execute(istream &s);
|
||||||
|
|
|
@ -102,14 +102,14 @@ bool Merge::mergeTestRequired(HighVariable *high_out,HighVariable *high_in)
|
||||||
}
|
}
|
||||||
else if (high_out->isExtraOut())
|
else if (high_out->isExtraOut())
|
||||||
return false;
|
return false;
|
||||||
if (high_in->isMapped() && high_out->isMapped()) {
|
|
||||||
Symbol *symbolIn = high_in->getSymbol();
|
Symbol *symbolIn = high_in->getSymbol();
|
||||||
Symbol *symbolOut = high_out->getSymbol();
|
Symbol *symbolOut = high_out->getSymbol();
|
||||||
if (symbolIn != (Symbol *)0 && symbolOut != (Symbol *)0) {
|
if (symbolIn != (Symbol *) 0 && symbolOut != (Symbol *) 0) {
|
||||||
if (symbolIn != symbolOut) return false; // Map to different symbols
|
if (symbolIn != symbolOut)
|
||||||
if (high_in->getSymbolOffset() != high_out->getSymbolOffset())
|
return false; // Map to different symbols
|
||||||
return false; // Map to different parts of same symbol
|
if (high_in->getSymbolOffset() != high_out->getSymbolOffset())
|
||||||
}
|
return false; // Map to different parts of same symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -145,6 +145,14 @@ bool Merge::mergeTestAdjacent(HighVariable *high_out,HighVariable *high_in)
|
||||||
Varnode *vn = high_in->getInputVarnode();
|
Varnode *vn = high_in->getInputVarnode();
|
||||||
if (vn->isIllegalInput()&&(!vn->isIndirectOnly())) return false;
|
if (vn->isIllegalInput()&&(!vn->isIndirectOnly())) return false;
|
||||||
}
|
}
|
||||||
|
Symbol *symbol = high_in->getSymbol();
|
||||||
|
if (symbol != (Symbol *)0)
|
||||||
|
if (symbol->isIsolated())
|
||||||
|
return false;
|
||||||
|
symbol = high_out->getSymbol();
|
||||||
|
if (symbol != (Symbol *)0)
|
||||||
|
if (symbol->isIsolated())
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,10 +845,14 @@ void Merge::mergeMultiEntry(void)
|
||||||
if (newHigh == high) continue; // Varnodes already merged
|
if (newHigh == high) continue; // Varnodes already merged
|
||||||
updateHigh(newHigh);
|
updateHigh(newHigh);
|
||||||
if (!mergeTestRequired(high, newHigh)) {
|
if (!mergeTestRequired(high, newHigh)) {
|
||||||
|
symbol->setMergeProblems();
|
||||||
|
newHigh->setUnmerged();
|
||||||
conflictCount += 1;
|
conflictCount += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!merge(high,newHigh,false)) { // Attempt the merge
|
if (!merge(high,newHigh,false)) { // Attempt the merge
|
||||||
|
symbol->setMergeProblems();
|
||||||
|
newHigh->setUnmerged();
|
||||||
conflictCount += 1;
|
conflictCount += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1639,6 +1639,21 @@ void PrintC::pushSymbol(const Symbol *sym,const Varnode *vn,const PcodeOp *op)
|
||||||
else
|
else
|
||||||
tokenColor = EmitXml::var_color;
|
tokenColor = EmitXml::var_color;
|
||||||
// FIXME: resolve scopes
|
// FIXME: resolve scopes
|
||||||
|
if (sym->hasMergeProblems() && vn != (Varnode *)0) {
|
||||||
|
HighVariable *high = vn->getHigh();
|
||||||
|
if (high->isUnmerged()) {
|
||||||
|
ostringstream s;
|
||||||
|
s << sym->getName();
|
||||||
|
SymbolEntry *entry = high->getSymbolEntry();
|
||||||
|
if (entry != (SymbolEntry *)0) {
|
||||||
|
s << '$' << dec << entry->getSymbol()->getMapEntryPosition(entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s << "$$";
|
||||||
|
pushAtom(Atom(s.str(),vartoken,tokenColor,op,vn));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
pushAtom(Atom(sym->getName(),vartoken,tokenColor,op,vn));
|
pushAtom(Atom(sym->getName(),vartoken,tokenColor,op,vn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2180,14 +2195,19 @@ bool PrintC::emitScopeVarDecls(const Scope *scope,int4 cat)
|
||||||
MapIterator iter = scope->begin();
|
MapIterator iter = scope->begin();
|
||||||
MapIterator enditer = scope->end();
|
MapIterator enditer = scope->end();
|
||||||
for(;iter!=enditer;++iter) {
|
for(;iter!=enditer;++iter) {
|
||||||
if ((*iter)->isPiece()) continue; // Don't do a partial entry
|
const SymbolEntry *entry = *iter;
|
||||||
Symbol *sym = (*iter)->getSymbol();
|
if (entry->isPiece()) continue; // Don't do a partial entry
|
||||||
|
Symbol *sym = entry->getSymbol();
|
||||||
if (sym->getCategory() != cat) continue;
|
if (sym->getCategory() != cat) continue;
|
||||||
if (sym->getName().size() == 0) continue;
|
if (sym->getName().size() == 0) continue;
|
||||||
if (dynamic_cast<FunctionSymbol *>(sym) != (FunctionSymbol *)0)
|
if (dynamic_cast<FunctionSymbol *>(sym) != (FunctionSymbol *)0)
|
||||||
continue;
|
continue;
|
||||||
if (dynamic_cast<LabSymbol *>(sym) != (LabSymbol *)0)
|
if (dynamic_cast<LabSymbol *>(sym) != (LabSymbol *)0)
|
||||||
continue;
|
continue;
|
||||||
|
if (sym->isMultiEntry()) {
|
||||||
|
if (sym->getFirstWholeMap() != entry)
|
||||||
|
continue; // Only emit the first SymbolEntry for declaration of multi-entry Symbol
|
||||||
|
}
|
||||||
notempty = true;
|
notempty = true;
|
||||||
emitVarDeclStatement(sym);
|
emitVarDeclStatement(sym);
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,20 @@ void HighVariable::remove(Varnode *vn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assuming there is a Symbol attached to \b this, run through the Varnode members
|
||||||
|
/// until we find one with a SymbolEntry corresponding to the Symbol and return it.
|
||||||
|
/// \return the SymbolEntry that mapped the Symbol to \b this or null if no Symbol is attached
|
||||||
|
SymbolEntry *HighVariable::getSymbolEntry(void) const
|
||||||
|
|
||||||
|
{
|
||||||
|
for(int4 i=0;i<inst.size();++i) {
|
||||||
|
SymbolEntry *entry = inst[i]->getSymbolEntry();
|
||||||
|
if (entry != (SymbolEntry *)0 && entry->getSymbol() == symbol)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return (SymbolEntry *)0;
|
||||||
|
}
|
||||||
|
|
||||||
/// The data-type its dirtying mechanism is disabled. The data-type will not change, unless
|
/// The data-type its dirtying mechanism is disabled. The data-type will not change, unless
|
||||||
/// this method is called again.
|
/// this method is called again.
|
||||||
/// \param tp is the data-type to set
|
/// \param tp is the data-type to set
|
||||||
|
|
|
@ -49,7 +49,8 @@ public:
|
||||||
symboldirty = 8, ///< The symbol attachment is dirty
|
symboldirty = 8, ///< The symbol attachment is dirty
|
||||||
copy_in1 = 8, ///< There exists at least 1 COPY into \b this HighVariable from other HighVariables
|
copy_in1 = 8, ///< There exists at least 1 COPY into \b this HighVariable from other HighVariables
|
||||||
copy_in2 = 16, ///< There exists at least 2 COPYs into \b this HighVariable from other HighVariables
|
copy_in2 = 16, ///< There exists at least 2 COPYs into \b this HighVariable from other HighVariables
|
||||||
type_finalized = 32 ///< Set if a final data-type is locked in and dirtying is disabled
|
type_finalized = 32, ///< Set if a final data-type is locked in and dirtying is disabled
|
||||||
|
unmerged = 64 ///< Set if part of a multi-entry Symbol but did not get merged with other SymbolEntrys
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
friend class Varnode;
|
friend class Varnode;
|
||||||
|
@ -79,10 +80,12 @@ private:
|
||||||
void flagsDirty(void) const { highflags |= HighVariable::flagsdirty; } ///< Mark the boolean properties as \e dirty
|
void flagsDirty(void) const { highflags |= HighVariable::flagsdirty; } ///< Mark the boolean properties as \e dirty
|
||||||
void coverDirty(void) const { highflags |= HighVariable::coverdirty; } ///< Mark the cover as \e dirty
|
void coverDirty(void) const { highflags |= HighVariable::coverdirty; } ///< Mark the cover as \e dirty
|
||||||
void typeDirty(void) const { highflags |= HighVariable::typedirty; } ///< Mark the data-type as \e dirty
|
void typeDirty(void) const { highflags |= HighVariable::typedirty; } ///< Mark the data-type as \e dirty
|
||||||
|
void setUnmerged(void) const { highflags |= unmerged; } ///< Mark \b this as having merge problems
|
||||||
public:
|
public:
|
||||||
HighVariable(Varnode *vn); ///< Construct a HighVariable with a single member Varnode
|
HighVariable(Varnode *vn); ///< Construct a HighVariable with a single member Varnode
|
||||||
Datatype *getType(void) const { updateType(); return type; } ///< Get the data-type
|
Datatype *getType(void) const { updateType(); return type; } ///< Get the data-type
|
||||||
Symbol *getSymbol(void) const { updateSymbol(); return symbol; } ///< Get the Symbol associated with \b this
|
Symbol *getSymbol(void) const { updateSymbol(); return symbol; } ///< Get the Symbol associated with \b this or null
|
||||||
|
SymbolEntry *getSymbolEntry(void) const; /// Get the SymbolEntry mapping to \b this or null
|
||||||
int4 getSymbolOffset(void) const { return symboloffset; } ///< Get the Symbol offset associated with \b this
|
int4 getSymbolOffset(void) const { return symboloffset; } ///< Get the Symbol offset associated with \b this
|
||||||
int4 numInstances(void) const { return inst.size(); } ///< Get the number of member Varnodes \b this has
|
int4 numInstances(void) const { return inst.size(); } ///< Get the number of member Varnodes \b this has
|
||||||
Varnode *getInstance(int4 i) const { return inst[i]; } ///< Get the i-th member Varnode
|
Varnode *getInstance(int4 i) const { return inst[i]; } ///< Get the i-th member Varnode
|
||||||
|
@ -111,6 +114,7 @@ public:
|
||||||
void setMark(void) const { flags |= Varnode::mark; } ///< Set the mark on this variable
|
void setMark(void) const { flags |= Varnode::mark; } ///< Set the mark on this variable
|
||||||
void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this variable
|
void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this variable
|
||||||
bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Return \b true if \b this is marked
|
bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Return \b true if \b this is marked
|
||||||
|
bool isUnmerged(void) const { return ((highflags&unmerged)!=0); } ///< Return \b true if \b this has merge problems
|
||||||
|
|
||||||
/// \brief Determine if \b this HighVariable has an associated cover.
|
/// \brief Determine if \b this HighVariable has an associated cover.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue