Ghidra Decompiler Analysis Engine
|
A map from values to control-flow targets within a function. More...
#include <jumptable.hh>
Public Member Functions | |
JumpTable (Architecture *g, Address ad=Address()) | |
Constructor. More... | |
JumpTable (const JumpTable *op2) | |
Copy constructor. More... | |
~JumpTable (void) | |
Destructor. | |
bool | isOverride (void) const |
Return true if this table was manually overridden. | |
void | setOverride (const vector< Address > &addrtable, const Address &naddr, uintb h, uintb sv) |
Force manual override information on this jump-table. More... | |
int4 | numIndicesByBlock (const FlowBlock *bl) const |
Return the number of address table entries that target the given basic-block. More... | |
int4 | getIndexByBlock (const FlowBlock *bl, int4 i) const |
Get the index of the i-th address table entry that corresponds to the given basic-block. More... | |
void | setLastAsMostCommon (void) |
Set the most common jump-table target to be the last address in the table. | |
void | addBlockToSwitch (BlockBasic *bl, uintb lab) |
Force a given basic-block to be a switch destination. More... | |
void | switchOver (const FlowInfo &flow) |
Convert absolute addresses to block indices. More... | |
void | foldInNormalization (Funcdata *fd) |
Hide the normalization code for the switch. More... | |
void | recoverAddresses (Funcdata *fd) |
Recover the raw jump-table addresses (the address table) More... | |
void | recoverMultistage (Funcdata *fd) |
Recover jump-table addresses keeping track of a possible previous stage. More... | |
bool | recoverLabels (Funcdata *fd) |
Recover the case labels for this jump-table. More... | |
bool | checkForMultistage (Funcdata *fd) |
Check if this jump-table requires an additional recovery stage. More... | |
void | clear (void) |
Clear instance specific data for this jump-table. More... | |
void | saveXml (ostream &s) const |
Save this jump-table as a <jumptable> XML tag. More... | |
void | restoreXml (const Element *el) |
Recover this jump-table from a <jumptable> XML tag. More... | |
A map from values to control-flow targets within a function.
A JumpTable is attached to a specific CPUI_BRANCHIND and encapsulates all the information necessary to model the indirect jump as a switch statement. It knows how to map from specific switch variable values to the destination case block and how to label the value.
JumpTable::JumpTable | ( | Architecture * | g, |
Address | ad = Address() |
||
) |
g | is the Architecture the table exists within |
ad | is the Address of the BRANCHIND this models |
JumpTable::JumpTable | ( | const JumpTable * | op2 | ) |
Copy constructor.
This is a partial clone of another jump-table. Objects that are specific to the particular Funcdata instance must be recalculated.
op2 | is the jump-table to clone |
void JumpTable::addBlockToSwitch | ( | BlockBasic * | bl, |
uintb | lab | ||
) |
Force a given basic-block to be a switch destination.
This is used to add address targets from guard branches if they are not already in the address table. A specific case label for the block can also be provided. The new target is appended directly to the end of the table.
bl | is the given basic-block |
lab | is the case label for the block |
bool JumpTable::checkForMultistage | ( | Funcdata * | fd | ) |
Check if this jump-table requires an additional recovery stage.
Look for the override directive that indicates we need an additional recovery stage for this jump-table.
fd | is the function containing the switch |
void JumpTable::clear | ( | void | ) |
Clear instance specific data for this jump-table.
Clear out any data that is specific to a Funcdata instance. The address table is not cleared if it was recovered, and override information is left intact. Right now this is only getting called, when the jumptable is an override in order to clear out derived data.
void JumpTable::foldInNormalization | ( | Funcdata * | fd | ) |
Hide the normalization code for the switch.
Eliminate any code involved in actually computing the destination address so it looks like the CPUI_BRANCHIND operation does it all internally.
fd | is the function containing this switch |
int4 JumpTable::getIndexByBlock | ( | const FlowBlock * | bl, |
int4 | i | ||
) | const |
Get the index of the i-th address table entry that corresponds to the given basic-block.
An exception is thrown if no address table entry targets the block.
bl | is the given basic-block |
i | requests a specific position within the duplicate entries |
int4 JumpTable::numIndicesByBlock | ( | const FlowBlock * | bl | ) | const |
Return the number of address table entries that target the given basic-block.
bl | is the given basic-block |
void JumpTable::recoverAddresses | ( | Funcdata * | fd | ) |
Recover the raw jump-table addresses (the address table)
The addresses that the raw BRANCHIND op might branch to itself are recovered, not including other targets of the final model, like guard addresses. The normalized switch variable and the guards are identified in the process however.
Generally this method is run during flow analysis when we only have partial information about the function (and possibly the switch itself). The Funcdata instance is a partial clone of the function and is different from the final instance that will hold the fully recovered jump-table. The final instance inherits the addresses recovered here, but recoverModel() will need to be run on it separately.
A sanity check is also run, which might truncate the original set of addresses.
fd | is the function containing the switch |
bool JumpTable::recoverLabels | ( | Funcdata * | fd | ) |
Recover the case labels for this jump-table.
This is run assuming the address table has already been recovered, via recoverAddresses() in another Funcdata instance. So recoverModel() needs to be rerun on the instance passed in here.
The unnormalized switch variable is recovered, and for each possible address table entry, the variable value that produces it is calculated and stored as the formal case label for the associated code block.
fd | is the (final instance of the) function containing the switch |
void JumpTable::recoverMultistage | ( | Funcdata * | fd | ) |
Recover jump-table addresses keeping track of a possible previous stage.
Do a normal recoverAddresses, but save off the old JumpModel, and if we fail recovery, put back the old model.
fd | is the function containing the switch |
void JumpTable::restoreXml | ( | const Element * | el | ) |
Recover this jump-table from a <jumptable> XML tag.
Restore the addresses, case labels, and any override information from the tag. Other parts of the model and jump-table will still need to be recovered.
el | is the root <jumptable> tag to restore from |
void JumpTable::saveXml | ( | ostream & | s | ) | const |
Save this jump-table as a <jumptable> XML tag.
The recovered addresses and case labels are saved to the XML stream. If override information is present, this is also incorporated into the tag.
s | is the stream to write to |
void JumpTable::setOverride | ( | const vector< Address > & | addrtable, |
const Address & | naddr, | ||
uintb | h, | ||
uintb | sv | ||
) |
Force manual override information on this jump-table.
The model is switched over to JumpBasicOverride, which is initialized with an externally provided list of addresses. The addresses are forced as the output addresses the BRANCHIND for this jump-table. If a non-zero hash and an address is provided, this identifies a specific Varnode to use as the normalized switch variable. A potential starting value for normalized switch variable range is provided.
addrtable | is the manually provided list of addresses to put in the address table |
naddr | is the address where the normalized switch variable is defined |
h | is a hash identifying the normalized switch variable (or 0) |
sv | is the starting value for the range of possible normalized switch variable values (usually 0) |
void JumpTable::switchOver | ( | const FlowInfo & | flow | ) |
Convert absolute addresses to block indices.
Convert addresses in this table to actual targeted basic-blocks.
This constructs a map from each out-edge from the basic-block containing the BRANCHIND to addresses in the table targetting that out-block. The most common address table entry is also calculated here.
flow | is used to resolve address targets |