Ghidra Decompiler Analysis Engine
Classes | Public Member Functions | List of all members
JumpTable Class Reference

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...
 

Detailed Description

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.

Constructor & Destructor Documentation

◆ JumpTable() [1/2]

JumpTable::JumpTable ( Architecture g,
Address  ad = Address() 
)

Constructor.

Parameters
gis the Architecture the table exists within
adis the Address of the BRANCHIND this models

◆ JumpTable() [2/2]

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.

Parameters
op2is the jump-table to clone

Member Function Documentation

◆ addBlockToSwitch()

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.

Parameters
blis the given basic-block
labis the case label for the block

◆ checkForMultistage()

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.

Parameters
fdis the function containing the switch
Returns
true if an additional recovery stage is required.

◆ clear()

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.

◆ foldInNormalization()

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.

Parameters
fdis the function containing this switch

◆ getIndexByBlock()

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.

Parameters
blis the given basic-block
irequests a specific position within the duplicate entries
Returns
the address table index

◆ numIndicesByBlock()

int4 JumpTable::numIndicesByBlock ( const FlowBlock bl) const

Return the number of address table entries that target the given basic-block.

Parameters
blis the given basic-block
Returns
the count of entries

◆ recoverAddresses()

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.

Parameters
fdis the function containing the switch

◆ recoverLabels()

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.

Parameters
fdis the (final instance of the) function containing the switch
Returns
true if it looks like a multi-stage restart is needed.

◆ recoverMultistage()

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.

Parameters
fdis the function containing the switch

◆ restoreXml()

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.

Parameters
elis the root <jumptable> tag to restore from

◆ saveXml()

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.

Parameters
sis the stream to write to

◆ setOverride()

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.

Parameters
addrtableis the manually provided list of addresses to put in the address table
naddris the address where the normalized switch variable is defined
his a hash identifying the normalized switch variable (or 0)
svis the starting value for the range of possible normalized switch variable values (usually 0)

◆ switchOver()

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.

Parameters
flowis used to resolve address targets

The documentation for this class was generated from the following files: