mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
A bunch of doxygen fixes
This commit is contained in:
parent
8d2b737a72
commit
5d7a7c5291
27 changed files with 514 additions and 195 deletions
|
@ -32,10 +32,13 @@ PcodeCacher::~PcodeCacher(void)
|
|||
delete [] poolstart;
|
||||
}
|
||||
|
||||
/// Expand the VarnodeData pool so that \e size more elements fit, and return
|
||||
/// a pointer to first available element.
|
||||
/// \param size is the number of elements to expand the pool by
|
||||
/// \return the first available VarnodeData
|
||||
VarnodeData *PcodeCacher::expandPool(uint4 size)
|
||||
|
||||
{ // Expand the pool so that -size- more elements fit
|
||||
// Return pointer to first available element
|
||||
{
|
||||
uint4 curmax = endpool - poolstart;
|
||||
uint4 cursize = curpool - poolstart;
|
||||
if (cursize + size <= curmax)
|
||||
|
@ -75,18 +78,26 @@ VarnodeData *PcodeCacher::expandPool(uint4 size)
|
|||
return newpool + cursize;
|
||||
}
|
||||
|
||||
/// Store off a reference to the Varnode and the absolute index of the next
|
||||
/// instruction. The Varnode must be an operand of the current instruction.
|
||||
/// \param ptr is the Varnode reference
|
||||
void PcodeCacher::addLabelRef(VarnodeData *ptr)
|
||||
|
||||
{ // Store off a reference to a label and the next instruction
|
||||
// address
|
||||
{
|
||||
label_refs.emplace_back();
|
||||
label_refs.back().dataptr = ptr;
|
||||
label_refs.back().calling_index = issued.size();
|
||||
}
|
||||
|
||||
/// The label has an id that is referred to by Varnodes holding
|
||||
/// intra-instruction branch targets, prior to converting
|
||||
/// them to a \e relative \e branch offset. The label is associated with
|
||||
/// the absolute index of the next PcodeData object to be issued,
|
||||
/// facilitating this conversion.
|
||||
/// \param id is the given id of the label
|
||||
void PcodeCacher::addLabel(uint4 id)
|
||||
|
||||
{ // Attach a label to the address of the next instruction
|
||||
{
|
||||
while(labels.size() <= id)
|
||||
labels.push_back(0xbadbeef);
|
||||
labels[ id ] = issued.size();
|
||||
|
@ -101,11 +112,12 @@ void PcodeCacher::clear(void)
|
|||
labels.clear();
|
||||
}
|
||||
|
||||
/// Assuming all the PcodeData has been generated for an
|
||||
/// instruction, go resolve any relative offsets and back
|
||||
/// patch their value(s) into the PcodeData
|
||||
void PcodeCacher::resolveRelatives(void)
|
||||
|
||||
{ // Assuming all the PcodeData has been generated for an
|
||||
// instruction, go resolve any relative offsets and back
|
||||
// patch their value(s) into the PcodeData
|
||||
{
|
||||
list<RelativeRecord>::const_iterator iter;
|
||||
for(iter=label_refs.begin();iter!=label_refs.end();++iter) {
|
||||
VarnodeData *ptr = (*iter).dataptr;
|
||||
|
@ -119,18 +131,25 @@ void PcodeCacher::resolveRelatives(void)
|
|||
}
|
||||
}
|
||||
|
||||
/// Each p-code operation is presented to the emitter via its dump() method.
|
||||
/// \param addr is the Address associated with the p-code operation
|
||||
/// \param emt is the emitter
|
||||
void PcodeCacher::emit(const Address &addr,PcodeEmit *emt) const
|
||||
|
||||
{ // Emit any cached pcode
|
||||
{
|
||||
vector<PcodeData>::const_iterator iter;
|
||||
|
||||
for(iter=issued.begin();iter!=issued.end();++iter)
|
||||
emt->dump(addr,(*iter).opc,(*iter).outvar,(*iter).invar,(*iter).isize);
|
||||
}
|
||||
|
||||
/// \brief Generate a concrete VarnodeData object from the given template (VarnodeTpl)
|
||||
///
|
||||
/// \param vntpl is the template to reference
|
||||
/// \param vn is the object to fill in with concrete values
|
||||
void SleighBuilder::generateLocation(const VarnodeTpl *vntpl,VarnodeData &vn)
|
||||
|
||||
{ // Generate a concrete varnode -vn- from the template -vntpl-
|
||||
{
|
||||
vn.space = vntpl->getSpace().fixSpace(*walker);
|
||||
vn.size = vntpl->getSize().fix(*walker);
|
||||
if (vn.space == const_space)
|
||||
|
@ -143,9 +162,18 @@ void SleighBuilder::generateLocation(const VarnodeTpl *vntpl,VarnodeData &vn)
|
|||
vn.offset = vn.space->wrapOffset(vntpl->getOffset().fix(*walker));
|
||||
}
|
||||
|
||||
/// \brief Generate a pointer VarnodeData from a dynamic template (VarnodeTpl)
|
||||
///
|
||||
/// The symbol represents a value referenced through a dynamic pointer.
|
||||
/// This method generates the varnode representing the pointer itself and also
|
||||
/// returns the address space in anticipation of generating the LOAD or STORE
|
||||
/// that actually manipulates the value.
|
||||
/// \param vntpl is the dynamic template to reference
|
||||
/// \param vn is the object to fill with concrete values
|
||||
/// \return the address space being pointed to
|
||||
AddrSpace *SleighBuilder::generatePointer(const VarnodeTpl *vntpl,VarnodeData &vn)
|
||||
|
||||
{ // Generate the pointer varnode -vn- from a dynamic template -vntpl-
|
||||
{
|
||||
const FixedHandle &hand(walker->getFixedHandle(vntpl->getOffset().getHandleIndex()));
|
||||
vn.space = hand.offset_space;
|
||||
vn.size = hand.offset_size;
|
||||
|
@ -218,9 +246,17 @@ void SleighBuilder::dump(OpTpl *op)
|
|||
}
|
||||
}
|
||||
|
||||
/// \brief Build a named p-code section of a constructor that contains only implied BUILD directives
|
||||
///
|
||||
/// If a named section of a constructor is empty, we still need to walk
|
||||
/// through any subtables that might contain p-code in their named sections.
|
||||
/// This method treats each subtable operand as an implied \e build directive,
|
||||
/// in the otherwise empty section.
|
||||
/// \param ct is the matching currently Constructor being built
|
||||
/// \param secnum is the particular \e named section number to build
|
||||
void SleighBuilder::buildEmpty(Constructor *ct,int4 secnum)
|
||||
|
||||
{ // Build a named p-code section of a constructor that contains only implied BUILD directives
|
||||
{
|
||||
int4 numops = ct->getNumOperands();
|
||||
|
||||
for(int4 i=0;i<numops;++i) {
|
||||
|
@ -238,12 +274,23 @@ void SleighBuilder::buildEmpty(Constructor *ct,int4 secnum)
|
|||
}
|
||||
}
|
||||
|
||||
/// Bits used to make temporary registers unique across multiple instructions
|
||||
/// are generated based on the given address.
|
||||
/// \param addr is the given Address
|
||||
void SleighBuilder::setUniqueOffset(const Address &addr)
|
||||
|
||||
{
|
||||
uniqueoffset = (addr.getOffset() & uniquemask)<<4;
|
||||
}
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// \param w is the parsed instruction
|
||||
/// \param dcache is a cache of nearby instruction parses
|
||||
/// \param pc will hold the PcodeData and VarnodeData objects produced by \b this builder
|
||||
/// \param cspc is the constant address space
|
||||
/// \param uspc is the unique address space
|
||||
/// \param umask is the mask to use to find unique bits within an Address
|
||||
SleighBuilder::SleighBuilder(ParserWalker *w,DisassemblyCache *dcache,PcodeCacher *pc,AddrSpace *cspc,
|
||||
AddrSpace *uspc,uint4 umask)
|
||||
: PcodeBuilder(0)
|
||||
|
@ -259,7 +306,8 @@ SleighBuilder::SleighBuilder(ParserWalker *w,DisassemblyCache *dcache,PcodeCache
|
|||
|
||||
void SleighBuilder::appendBuild(OpTpl *bld,int4 secnum)
|
||||
|
||||
{ // Append pcode for a particular build statement
|
||||
{
|
||||
// Append p-code for a particular build statement
|
||||
int4 index = bld->getIn(0)->getOffset().getReal(); // Recover operand index from build statement
|
||||
// Check if operand is a subtable
|
||||
SubtableSymbol *sym = (SubtableSymbol *)walker->getConstructor()->getOperand(index)->getDefiningSymbol();
|
||||
|
@ -283,8 +331,9 @@ void SleighBuilder::appendBuild(OpTpl *bld,int4 secnum)
|
|||
|
||||
void SleighBuilder::delaySlot(OpTpl *op)
|
||||
|
||||
{ // Append pcode for an entire instruction (delay slot)
|
||||
// in the middle of the current instruction
|
||||
{
|
||||
// Append pcode for an entire instruction (delay slot)
|
||||
// in the middle of the current instruction
|
||||
ParserWalker *tmp = walker;
|
||||
uintb olduniqueoffset = uniqueoffset;
|
||||
|
||||
|
@ -319,7 +368,8 @@ void SleighBuilder::setLabel(OpTpl *op)
|
|||
|
||||
void SleighBuilder::appendCrossBuild(OpTpl *bld,int4 secnum)
|
||||
|
||||
{ // Weave in the p-code section from an instruction at another address
|
||||
{
|
||||
// Weave in the p-code section from an instruction at another address
|
||||
// bld-param(0) contains the address of the instruction
|
||||
// bld-param(1) contains the section number
|
||||
if (secnum>=0)
|
||||
|
@ -352,6 +402,8 @@ void SleighBuilder::appendCrossBuild(OpTpl *bld,int4 secnum)
|
|||
uniqueoffset = olduniqueoffset;
|
||||
}
|
||||
|
||||
/// \param min is the minimum number of allocations before a reuse is expected
|
||||
/// \param hashsize is the number of elements in the hash-table
|
||||
void DisassemblyCache::initialize(int4 min,int4 hashsize)
|
||||
|
||||
{
|
||||
|
@ -382,6 +434,10 @@ void DisassemblyCache::free(void)
|
|||
delete [] hashtable;
|
||||
}
|
||||
|
||||
/// \param ccache is the ContextCache front-end shared across all the parser contexts
|
||||
/// \param cspace is the constant address space used for minting constant Varnodes
|
||||
/// \param cachesize is the number of distinct ParserContext objects in this cache
|
||||
/// \param windowsize is the size of the ParserContext hash-table
|
||||
DisassemblyCache::DisassemblyCache(ContextCache *ccache,AddrSpace *cspace,int4 cachesize,int4 windowsize)
|
||||
|
||||
{
|
||||
|
@ -390,13 +446,17 @@ DisassemblyCache::DisassemblyCache(ContextCache *ccache,AddrSpace *cspace,int4 c
|
|||
initialize(cachesize,windowsize); // Set default settings for the cache
|
||||
}
|
||||
|
||||
/// Return a (possibly cached) ParserContext that is associated with \e addr
|
||||
/// If n different calls to this interface are made with n different Addresses, if
|
||||
/// - n <= minimumreuse AND
|
||||
/// - all the addresses are within the windowsize (=mask+1)
|
||||
///
|
||||
/// then the cacher guarantees that you get all different ParserContext objects
|
||||
/// \param addr is the Address to disassemble at
|
||||
/// \return the ParserContext associated with the address
|
||||
ParserContext *DisassemblyCache::getParserContext(const Address &addr)
|
||||
|
||||
{ // Return a (possibly cached) ParserContext that is associated with -addr-
|
||||
// If n different calls to this interface are made with n different Addresses, if
|
||||
// n <= minimumreuse AND
|
||||
// all the addresses are within the windowsize (=mask+1)
|
||||
// then the cacher guarantees that you get all different ParserContext objects
|
||||
{
|
||||
int4 hashindex = ((int4) addr.getOffset()) & mask;
|
||||
ParserContext *res = hashtable[ hashindex ];
|
||||
if (res->getAddr() == addr)
|
||||
|
@ -411,6 +471,8 @@ ParserContext *DisassemblyCache::getParserContext(const Address &addr)
|
|||
return res;
|
||||
}
|
||||
|
||||
/// \param ld is the LoadImage to draw program bytes from
|
||||
/// \param c_db is the context database
|
||||
Sleigh::Sleigh(LoadImage *ld,ContextDatabase *c_db)
|
||||
: SleighBase()
|
||||
|
||||
|
@ -435,10 +497,13 @@ Sleigh::~Sleigh(void)
|
|||
clearForDelete();
|
||||
}
|
||||
|
||||
/// Completely clear everything except the base and reconstruct
|
||||
/// with a new LoadImage and ContextDatabase
|
||||
/// \param ld is the new LoadImage
|
||||
/// \param c_db is the new ContextDatabase
|
||||
void Sleigh::reset(LoadImage *ld,ContextDatabase *c_db)
|
||||
|
||||
{ // Completely clear everything except the base and reconstruct
|
||||
// with a new loader and context
|
||||
{
|
||||
clearForDelete();
|
||||
pcode_cache.clear();
|
||||
loader = ld;
|
||||
|
@ -447,6 +512,8 @@ void Sleigh::reset(LoadImage *ld,ContextDatabase *c_db)
|
|||
discache = (DisassemblyCache *)0;
|
||||
}
|
||||
|
||||
/// The .sla file from the document store is loaded and cache objects are prepared
|
||||
/// \param store is the document store containing the main \<sleigh> tag.
|
||||
void Sleigh::initialize(DocumentStorage &store)
|
||||
|
||||
{
|
||||
|
@ -467,10 +534,18 @@ void Sleigh::initialize(DocumentStorage &store)
|
|||
discache = new DisassemblyCache(cache,getConstantSpace(),parser_cachesize,parser_windowsize);
|
||||
}
|
||||
|
||||
/// \brief Obtain a parse tree for the instruction at the given address
|
||||
///
|
||||
/// The tree may be cached from a previous access. If the address
|
||||
/// has not been parsed, disassembly is performed, and a new parse tree
|
||||
/// is prepared. Depending on the desired \e state, the parse tree
|
||||
/// can be prepared either for disassembly or for p-code generation.
|
||||
/// \param addr is the given address of the instruction
|
||||
/// \param state is the desired parse state.
|
||||
/// \return the parse tree object (ParseContext)
|
||||
ParserContext *Sleigh::obtainContext(const Address &addr,int4 state) const
|
||||
|
||||
{ // Obtain a ParserContext for the instruction at the given -addr-. This may be cached.
|
||||
// Make sure parsing has proceeded to at least the given -state.
|
||||
{
|
||||
ParserContext *pos = discache->getParserContext(addr);
|
||||
int4 curstate = pos->getParserState();
|
||||
if (curstate >= state)
|
||||
|
@ -485,10 +560,11 @@ ParserContext *Sleigh::obtainContext(const Address &addr,int4 state) const
|
|||
return pos;
|
||||
}
|
||||
|
||||
/// Resolve \e all the constructors involved in the instruction at the indicated address
|
||||
/// \param pos is the parse object that will hold the resulting tree
|
||||
void Sleigh::resolve(ParserContext &pos) const
|
||||
|
||||
{ // Resolve ALL the constructors involved in the
|
||||
// instruction at this address
|
||||
{
|
||||
loader->loadFill(pos.getBuffer(),16,pos.getAddr());
|
||||
ParserWalkerChange walker(&pos);
|
||||
pos.deallocateState(walker); // Clear the previous resolve and initialize the walker
|
||||
|
@ -538,9 +614,12 @@ void Sleigh::resolve(ParserContext &pos) const
|
|||
pos.setParserState(ParserContext::disassembly);
|
||||
}
|
||||
|
||||
/// Resolve handle templates for the given parse tree, assuming Constructors
|
||||
/// are already resolved.
|
||||
/// \param pos is the given parse tree
|
||||
void Sleigh::resolveHandles(ParserContext &pos) const
|
||||
|
||||
{ // Resolve handles (assuming Constructors already resolved)
|
||||
{
|
||||
TripleSymbol *triple;
|
||||
Constructor *ct;
|
||||
int4 oper,numoper;
|
||||
|
@ -671,7 +750,7 @@ int4 Sleigh::oneInstruction(PcodeEmit &emit,const Address &baseaddr) const
|
|||
|
||||
void Sleigh::registerContext(const string &name,int4 sbit,int4 ebit)
|
||||
|
||||
{ // Inform translator of existence of context variable
|
||||
{
|
||||
context_db->registerVariable(name,sbit,ebit);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue