Ghidra Decompiler Analysis Engine
Public Types | Public Member Functions | Static Public Member Functions | Friends | List of all members
Varnode Class Reference

A low-level variable or contiguous set of bytes described by an Address and a size. More...

#include <varnode.hh>

Collaboration diagram for Varnode:
Collaboration graph
[legend]

Public Types

enum  varnode_flags {
  mark = 0x01, constant = 0x02, annotation = 0x04, input = 0x08,
  written = 0x10, insert = 0x20, implied = 0x40, explict = 0x80,
  typelock = 0x100, namelock = 0x200, nolocalalias = 0x400, volatil = 0x800,
  externref = 0x1000, readonly = 0x2000, persist = 0x4000, addrtied = 0x8000,
  unaffected = 0x10000, spacebase = 0x20000, indirectonly = 0x40000, directwrite = 0x80000,
  addrforce = 0x100000, mapped = 0x200000, indirect_creation = 0x400000, return_address = 0x800000,
  coverdirty = 0x1000000, precislo = 0x2000000, precishi = 0x4000000, indirectstorage = 0x8000000,
  hiddenretparm = 0x10000000, incidental_copy = 0x20000000, autolive_hold = 0x40000000
}
 
enum  addl_flags {
  activeheritage = 0x01, writemask = 0x02, vacconsume = 0x04, lisconsume = 0x08,
  ptrcheck = 0x10, ptrflow = 0x20, unsignedprint = 0x40, stack_store = 0x80,
  locked_input = 0x100, spacebase_placeholder = 0x200
}
 Additional boolean properties on a Varnode. More...
 

Public Member Functions

HighVariablegetHigh (void) const
 Get the high-level variable associated with this Varnode. More...
 
PcodeOploneDescend (void) const
 Return unique reading PcodeOp, or null if there are zero or more than 1. More...
 
Address getUsePoint (const Funcdata &fd) const
 Get Address when this Varnode first comes into scope. More...
 
int4 printRawNoMarkup (ostream &s) const
 Print a simple identifier for the Varnode. More...
 
void printRaw (ostream &s) const
 Print a simple identifier plus additional info identifying Varnode with SSA form. More...
 
void printCover (ostream &s) const
 Print raw coverage info about the Varnode. More...
 
void printInfo (ostream &s) const
 Print raw attribute info about the Varnode. More...
 
 Varnode (int4 s, const Address &m, Datatype *dt)
 Construct a free Varnode. More...
 
bool operator< (const Varnode &op2) const
 Comparison operator on Varnode. More...
 
bool operator== (const Varnode &op2) const
 Equality operator. More...
 
 ~Varnode (void)
 Destructor. More...
 
bool intersects (const Varnode &op) const
 Return true if the storage locations intersect. More...
 
bool intersects (const Address &op2loc, int4 op2size) const
 Check intersection against an Address range. More...
 
int4 contains (const Varnode &op) const
 Return info about the containment of op in this. More...
 
int4 characterizeOverlap (const Varnode &op) const
 Return 0, 1, or 2 for "no overlap", "partial overlap", "identical storage".
 
int4 overlap (const Varnode &op) const
 Return relative point of overlap between two Varnodes. More...
 
int4 overlap (const Address &op2loc, int4 op2size) const
 Return relative point of overlap with Address range. More...
 
int4 termOrder (const Varnode *op) const
 Compare two Varnodes based on their term order. More...
 
void printRawHeritage (ostream &s, int4 depth) const
 Print a simple SSA subtree rooted at this. More...
 
bool isAddrTied (void) const
 Are all Varnodes at this storage location components of the same high-level variable?
 
bool isIndirectZero (void) const
 Is this just a special placeholder representing INDIRECT creation?
 
bool isExtraOut (void) const
 Is this Varnode created indirectly by a CALL operation?
 
bool hasCover (void) const
 Does this have Cover information?
 
bool constantMatch (uintb val) const
 Return true if this is a constant with value val.
 
int4 isConstantExtended (uintb &val) const
 
bool isHeritageKnown (void) const
 Return true if this Varnode is linked into the SSA tree.
 
bool updateType (Datatype *ct, bool lock, bool override)
 (Possibly) set the Datatype given various restrictions More...
 
void copySymbol (const Varnode *vn)
 Copy symbol info from vn. More...
 
void copySymbolIfValid (const Varnode *vn)
 Copy symbol info from vn if constant value matches. More...
 
DatatypegetLocalType (void) const
 Calculate type of Varnode based on local information. More...
 
bool copyShadow (const Varnode *op2) const
 Are this and op2 copied from the same source? More...
 
void saveXml (ostream &s) const
 Save a description of this as an XML tag. More...
 

Static Public Member Functions

static void printRaw (ostream &s, const Varnode *vn)
 Print raw info about a Varnode to stream. More...
 

Friends

class VarnodeBank
 
class Merge
 
class Funcdata
 

Detailed Description

A low-level variable or contiguous set of bytes described by an Address and a size.

A Varnode is the fundemental variable in the p-code language model. A Varnode represents anything that holds data, including registers, stack locations, global RAM locations, and constants. It is described most simply as a storage location for some number of bytes, and is identified by

In its raw form, the Varnode is referred to as free, and this pair uniquely identifies the Varnode, as determined by its comparison operators. In terms of the Static Single Assignment (SSA) form for the decompiler analysis, the Varnode class also represents a node in the tree. In this case the Varnode is not free, and each individual write to a storage location, as per SSA form, creates a unique Varnode, which is represented by a separate instance, so there may be multiple Varnode instances with the same Address and size.

Member Enumeration Documentation

◆ addl_flags

Additional boolean properties on a Varnode.

Enumerator
activeheritage 

The varnode is actively being heritaged.

writemask 

Should not be considered a write in heritage calculation.

vacconsume 

Vacuous consume.

lisconsume 

In consume worklist.

ptrcheck 

The Varnode value is NOT a pointer.

ptrflow 

If this varnode flows to or from a pointer.

unsignedprint 

Constant that must be explicitly printed as unsigned.

stack_store 

Created by an explicit STORE.

locked_input 

Input that exists even if its unused.

spacebase_placeholder 

value at a specific point in the code

This varnode is inserted artificially to track a register

◆ varnode_flags

There are a large number of boolean attributes that can be placed on a Varnode. Some are calculated and maintained by the friend classes Funcdata and VarnodeBank, and others can be set and cleared publicly by separate subsystems.

Enumerator
mark 

Prevents infinite loops.

constant 

The varnode is constant.

annotation 

This varnode is an annotation and has no dataflow.

input 

This varnode has no ancestor.

written 

This varnode has a defining op (def is nonzero)

insert 

This varnode has been inserted in a tree This means the varnode is the output of an op or The output is a constant or the output is an input

implied 

This varnode is a temporary variable.

explict 

This varnode CANNOT be a temporary variable.

typelock 

The Dataype of the Varnode is locked.

namelock 

The Name of the Varnode is locked.

nolocalalias 

There are no aliases pointing to this varnode.

volatil 

This varnode's value is volatile.

externref 

Varnode address is specially mapped by the loader.

readonly 

Varnode is stored at a readonly location.

persist 

Persists after (and before) function.

addrtied 

High-level variable is tied to address.

unaffected 

Input which is unaffected by the function.

spacebase 

This is a base register for an address space.

indirectonly 

If all uses of illegalinput varnode are inputs to INDIRECT.

directwrite 

(could be) Directly affected by a valid input

addrforce 

Varnode is used to force variable into an address.

mapped 

Varnode has a database entry associated with it.

indirect_creation 

The value in this Varnode is created indirectly.

return_address 

Is the varnode storage for a return address.

coverdirty 

Cover is not upto date.

precislo 

Is this Varnode the low part of a double precision value.

precishi 

Is this Varnode the high part of a double precision value.

indirectstorage 

Is this Varnode storing a pointer to the actual symbol.

hiddenretparm 

Does this varnode point to the return value storage location.

incidental_copy 

Do copies of this varnode happen as a side-effect.

autolive_hold 

Temporarily block dead-code removal of this.

Constructor & Destructor Documentation

◆ Varnode()

Varnode::Varnode ( int4  s,
const Address m,
Datatype dt 
)

Construct a free Varnode.

This is the constructor for making an unmanaged Varnode It creates a free Varnode with possibly a Datatype attribute. Most applications create Varnodes through the Funcdata interface

Parameters
sis the size of the new Varnode
mis the starting storage Address
dtis the Datatype

◆ ~Varnode()

Varnode::~Varnode ( void  )

Destructor.

Delete the Varnode object. This routine assumes all other cross-references have been removed.

Member Function Documentation

◆ contains()

int4 Varnode::contains ( const Varnode op) const

Return info about the containment of op in this.

Return various values depending on the containment of another Varnode within this. Return

  • -1 if op.loc starts before -this-
  • 0 if op is contained in -this-
  • 1 if op.start is contained in -this-
  • 2 if op.loc comes after -this- or
  • 3 if op and -this- are in non-comparable spaces
    Parameters
    opis the Varnode to test for containment
    Returns
    the integer containment code

◆ copyShadow()

bool Varnode::copyShadow ( const Varnode op2) const

Are this and op2 copied from the same source?

Make a local determination if this and op2 hold the same value. We check if there is a common ancester for which both this and op2 are created from a direct sequence of COPY operations. NOTE: This is a transitive relationship

Parameters
op2is the Varnode to compare to this
Returns
true if the Varnodes are copied from a common ancestor

◆ copySymbol()

void Varnode::copySymbol ( const Varnode vn)

Copy symbol info from vn.

Copy any symbol and type information from -vn- into this

Parameters
vnis the Varnode to copy from

◆ copySymbolIfValid()

void Varnode::copySymbolIfValid ( const Varnode vn)

Copy symbol info from vn if constant value matches.

Symbol information (if present) is copied from the given constant Varnode into this, which also must be constant, but only if the two constants are close in the sense of an equate.

Parameters
vnis the given constant Varnode

◆ getHigh()

HighVariable * Varnode::getHigh ( void  ) const

Get the high-level variable associated with this Varnode.

During the course of analysis Varnodes are merged into high-level variables that are intended to be closer to the concept of variables in C source code. For a large portion of the decompiler analysis this concept hasn't been built yet, and this routine will return null. But after a certain point, every Varnode managed by the Funcdata object, with the exception of ones that are marked as annotations, is associated with some HighVariable and will return a non-null result.

Returns
the associated HighVariable

◆ getLocalType()

Datatype * Varnode::getLocalType ( void  ) const

Calculate type of Varnode based on local information.

Make an initial determination of the Datatype of this Varnode. If a Datatype is already set and locked return it. Otherwise look through all the read PcodeOps and the write PcodeOp to determine if the Varnode is getting used as an int, float, or pointer, etc. Throw an exception if no Datatype can be found at all.

Returns
the determined Datatype

◆ getUsePoint()

Address Varnode::getUsePoint ( const Funcdata fd) const

Get Address when this Varnode first comes into scope.

A Varnode can be defined as "coming into scope" at the Address of the first PcodeOp that writes to that storage location. Within SSA form this first-use address always exists and is unique if we consider inputs to come into scope at the start Address of the function they are in

Parameters
fdis the Funcdata containing the tree
Returns
the first-use Address

◆ intersects() [1/2]

bool Varnode::intersects ( const Address op2loc,
int4  op2size 
) const

Check intersection against an Address range.

Check if this intersects the given Address range

Parameters
op2locis the start of the range
op2sizeis the size of the range in bytes
Returns
true if this intersects the range

◆ intersects() [2/2]

bool Varnode::intersects ( const Varnode op) const

Return true if the storage locations intersect.

Check whether the storage locations of two varnodes intersect

Parameters
opis the Varnode to compare with this
Returns
true if the locations intersect

◆ isConstantExtended()

int4 Varnode::isConstantExtended ( uintb &  val) const

Is this an (extended) constant

If this is a constant, or is extended (INT_ZEXT,INT_SEXT) from a constant, the value of the constant is passed back and a non-negative integer is returned, either:

  • 0 for a normal constant Varnode
  • 1 for a zero extension (INT_ZEXT) of a normal constant
  • 2 for a sign extension (INT_SEXT) of a normal constant
    Parameters
    valis a reference to the constant value that is passed back
    Returns
    the extension code (or -1 if this cannot be interpreted as a constant)

◆ loneDescend()

PcodeOp * Varnode::loneDescend ( void  ) const

Return unique reading PcodeOp, or null if there are zero or more than 1.

This is a convenience method for quickly finding the unique PcodeOp that reads this Varnode

Returns
only descendant (if there is 1 and ONLY 1) or null otherwise

◆ operator<()

bool Varnode::operator< ( const Varnode op2) const

Comparison operator on Varnode.

Compare two Varnodes

  • First by storage location
  • Second by size
  • Then by defining PcodeOp SeqNum if appropriate

Input Varnodes come before written Varnodes Free Varnodes come after everything else

Parameters
op2is the Varnode to compare this to
Returns
true if this is less than op2

◆ operator==()

bool Varnode::operator== ( const Varnode op2) const

Equality operator.

Determine if two Varnodes are equivalent. They must match

  • Storage location
  • Size
  • Defining PcodeOp if it exists
Parameters
op2is the Varnode to compare this to
Returns
true if they are equivalent

◆ overlap() [1/2]

int4 Varnode::overlap ( const Address op2loc,
int4  op2size 
) const

Return relative point of overlap with Address range.

Return whether Least Signifigant Byte of this occurs in an Address range I.e. return

  • 0 if it overlaps op's lsb
  • 1 if it overlaps op's second lsb and so on
    Parameters
    op2locis the starting Address of the range
    op2sizeis the size of the range in bytes
    Returns
    the relative overlap point or -1

◆ overlap() [2/2]

int4 Varnode::overlap ( const Varnode op) const

Return relative point of overlap between two Varnodes.

Return whether Least Signifigant Byte of this occurs in op I.e. return

  • 0 if it overlaps op's lsb
  • 1 if it overlaps op's second lsb and so on
    Parameters
    opis Varnode to test for overlap
    Returns
    the relative overlap point or -1

◆ printCover()

void Varnode::printCover ( ostream &  s) const

Print raw coverage info about the Varnode.

Print, to a stream, textual information about where this Varnode is in scope within its particular Funcdata. This amounts to a list of address ranges bounding the writes and reads of the Varnode

Parameters
sis the output stream

◆ printInfo()

void Varnode::printInfo ( ostream &  s) const

Print raw attribute info about the Varnode.

Print boolean attribute information about this as keywords to a stream

Parameters
sis the output stream

◆ printRaw() [1/2]

void Varnode::printRaw ( ostream &  s) const

Print a simple identifier plus additional info identifying Varnode with SSA form.

Print textual information about this Varnode including a base identifier along with enough size and attribute information to uniquely identify the Varnode within a text SSA listing In particular, the identifiers have either "i" or defining op SeqNum information appended to them in parantheses.

Parameters
sis the output stream

◆ printRaw() [2/2]

void Varnode::printRaw ( ostream &  s,
const Varnode vn 
)
static

Print raw info about a Varnode to stream.

Invoke the printRaw method on the given Varnode pointer, but take into account that it might be null.

Parameters
sis the output stream to write to
vnis the given Varnode pointer (may be null)

◆ printRawHeritage()

void Varnode::printRawHeritage ( ostream &  s,
int4  depth 
) const

Print a simple SSA subtree rooted at this.

Recursively print a terse textual representation of the data-flow (SSA) tree rooted at this Varnode

Parameters
sis the output stream
depthis the current depth of the tree we are at

◆ printRawNoMarkup()

int4 Varnode::printRawNoMarkup ( ostream &  s) const

Print a simple identifier for the Varnode.

Print to the stream either the name of the Varnode, such as a register name, if it exists or print a shortcut character representing the AddrSpace and a hex representation of the offset. This function also computes and returns the expected size of the identifier it prints to facilitate the printing of size modifiers by other print routines

Parameters
sis the output stream
Returns
the expected size

◆ saveXml()

void Varnode::saveXml ( ostream &  s) const

Save a description of this as an XML tag.

Write an XML tag, <addr>, with at least the following attributes:

Additionally the tag will contain other optional attributes.

Parameters
sis the stream to write the tag to

◆ termOrder()

int4 Varnode::termOrder ( const Varnode op) const

Compare two Varnodes based on their term order.

Compare term order of two Varnodes. Used in Term Rewriting strategies to order operands of commutative ops

Parameters
opis the Varnode to order against this
Returns
-1 if this comes before op, 1 if op before this, or 0

◆ updateType()

bool Varnode::updateType ( Datatype ct,
bool  lock,
bool  override 
)

(Possibly) set the Datatype given various restrictions

Change the Datatype and lock state associated with this Varnode if various conditions are met

  • Don't change a previously locked Datatype (unless override flag is true)
  • Don't consider an undefined type to be locked
  • Don't change to an identical Datatype
    Parameters
    ctis the Datatype to change to
    lockis true if the new Datatype should be locked
    overrideis true if an old lock should be overridden
    Returns
    true if the Datatype or the lock setting was changed

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