Ghidra Decompiler Analysis Engine
|
A high-level variable modeled as a list of low-level variables, each written once. More...
#include <variable.hh>
Public Types | |
enum | { flagsdirty = 1, namerepdirty = 2, typedirty = 4, coverdirty = 8, symboldirty = 0x10, copy_in1 = 0x20, copy_in2 = 0x40, type_finalized = 0x80, unmerged = 0x100 } |
Dirtiness flags for a HighVariable. More... | |
Public Member Functions | |
HighVariable (Varnode *vn) | |
Construct a HighVariable with a single member Varnode. More... | |
SymbolEntry * | getSymbolEntry (void) const |
void | finalizeDatatype (Datatype *tp) |
Set a final datatype for this variable. More... | |
void | printCover (ostream &s) const |
Print details of the cover for this (for debug purposes) More... | |
void | printInfo (ostream &s) const |
Print information about this HighVariable to stream. More... | |
bool | hasName (void) const |
Check if this HighVariable can be named. More... | |
Varnode * | getTiedVarnode (void) const |
Find the first address tied member Varnode. More... | |
Varnode * | getInputVarnode (void) const |
Find (the) input member Varnode. More... | |
Varnode * | getTypeRepresentative (void) const |
Get a member Varnode with the strongest data-type. More... | |
Varnode * | getNameRepresentative (void) const |
Get a member Varnode that dictates the naming of this HighVariable. More... | |
bool | hasCover (void) const |
Determine if this HighVariable has an associated cover. More... | |
void | saveXml (ostream &s) const |
Save the variable to stream as an XML <high> tag. More... | |
Static Public Member Functions | |
static bool | compareName (Varnode *vn1, Varnode *vn2) |
Determine which given Varnode is most nameable. More... | |
static bool | compareJustLoc (const Varnode *a, const Varnode *b) |
Compare based on storage location. More... | |
static int4 | markExpression (Varnode *vn, vector< HighVariable * > &highList) |
Mark and collect variables in expression. More... | |
Friends | |
class | Varnode |
class | Merge |
A high-level variable modeled as a list of low-level variables, each written once.
In the Static Single Assignment (SSA) representation of a function's data-flow, the Varnode object represents a variable node. This is a low-level variable: it is written to at most once, and there is 1 or more reads. A high-level variable, in the source language may be written to multiple times. We model this idea as a list of Varnode objects, where a different Varnode holds the value of the variable for different parts of the code. The range(s) of code for which a single Varnode holds the high-level variable's value is the cover or range of that Varnode and is modeled by the class Cover. Within a high-level variable, HighVariable, the covers of member Varnode objects should not intersect, as that represents the variable holding two or more different values at the same place in the code. The HighVariable inherits a cover which is the union of the covers of its Varnodes.
anonymous enum |
Dirtiness flags for a HighVariable.
The HighVariable inherits its Cover, its data-type, and other boolean properties from its Varnodes. The object holds these explicitly, but the values may become stale as the data-flow transforms. So we keep track of when these inherited values are dirty
Enumerator | |
---|---|
flagsdirty | Boolean properties for the HighVariable are dirty. |
namerepdirty | The name representative for the HighVariable is dirty. |
typedirty | The data-type for the HighVariable is dirty. |
coverdirty | The cover for the HighVariable is dirty. |
symboldirty | The symbol attachment is dirty. |
copy_in1 | There exists at least 1 COPY into this HighVariable from other HighVariables. |
copy_in2 | There exists at least 2 COPYs into this HighVariable from other HighVariables. |
type_finalized | Set if a final data-type is locked in and dirtying is disabled. |
unmerged | Set if part of a multi-entry Symbol but did not get merged with other SymbolEntrys. |
HighVariable::HighVariable | ( | Varnode * | vn | ) |
Construct a HighVariable with a single member Varnode.
The new instance starts off with no associate Symbol and all properties marked as dirty.
vn | is the single Varnode member |
Determine which given Varnode is most nameable.
Given two Varnode (members), sort them based on naming properties:
void HighVariable::finalizeDatatype | ( | Datatype * | tp | ) |
Set a final datatype for this variable.
The data-type its dirtying mechanism is disabled. The data-type will not change, unless this method is called again.
tp | is the data-type to set |
Varnode * HighVariable::getInputVarnode | ( | void | ) | const |
Varnode * HighVariable::getNameRepresentative | ( | void | ) | const |
Get a member Varnode that dictates the naming of this HighVariable.
Members are scored based the properties that are most dominating in choosing a name.
SymbolEntry * HighVariable::getSymbolEntry | ( | void | ) | const |
Assuming there is a Symbol attached to this, run through the Varnode members until we find one with a SymbolEntry corresponding to the Symbol and return it.
Varnode * HighVariable::getTiedVarnode | ( | void | ) | const |
Find the first address tied member Varnode.
This should only be called if isAddrTied() returns true. If there is no address tied member, this will throw an exception.
Varnode * HighVariable::getTypeRepresentative | ( | void | ) | const |
Get a member Varnode with the strongest data-type.
Find the member Varnode with the most specialized data-type, handling bool specially. Boolean data-types are specialized in the data-type lattice, but not all byte values are boolean values. Within the Varnode/PcodeOp tree, the bool data-type can only propagate to a Varnode if it is verified to only take the boolean values 0 and 1. Since the data-type representative represents the type of all instances, if any instance is not boolean, then the HighVariable cannot be boolean, even though bool is more specialized. This method uses Datatype::typeOrderBool() to implement the special handling.
|
inline |
Determine if this HighVariable has an associated cover.
Constant and annotation variables do not have a cover
bool HighVariable::hasName | ( | void | ) | const |
Check if this HighVariable can be named.
All Varnode objects are assigned a HighVariable, including those that don't get names like indirect variables, constants, and annotations. Determine if this, as inherited from its member Varnodes, can have a name.
|
static |
Mark and collect variables in expression.
Given a Varnode at the root of an expression, we collect all the explicit HighVariables involved in the expression. This should only be run after explicit and implicit properties have been computed on Varnodes. The expression is traced back from the root until explicit Varnodes are encountered; then their HighVariable is marked and added to the list. The routine returns a value based on PcodeOps encountered in the expression:
vn | is the given root Varnode of the expression |
highList | will hold the collected HighVariables |
|
inline |
Print details of the cover for this (for debug purposes)
s | is the output stream |
void HighVariable::printInfo | ( | ostream & | s | ) | const |
Print information about this HighVariable to stream.
This is generally used for debug purposes.
s | is the output stream |
void HighVariable::saveXml | ( | ostream & | s | ) | const |
Save the variable to stream as an XML <high> tag.
s | is the output stream to write XML to |