mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-2480 Console mode inst_next2 support and documentation update
This commit is contained in:
parent
8d4a6c213e
commit
d33cd8a92e
23 changed files with 348 additions and 275 deletions
|
@ -17,11 +17,12 @@
|
|||
#include "slghsymbol.hh"
|
||||
#include "translate.hh"
|
||||
|
||||
ParserContext::ParserContext(ContextCache *ccache)
|
||||
ParserContext::ParserContext(ContextCache *ccache,Translate *trans)
|
||||
|
||||
{
|
||||
parsestate = 0;
|
||||
parsestate = uninitialized;
|
||||
contcache = ccache;
|
||||
translate = trans;
|
||||
if (ccache != (ContextCache *)0) {
|
||||
contextsize = ccache->getDatabase()->getContextSize();
|
||||
context = new uintm[ contextsize ];
|
||||
|
@ -43,6 +44,18 @@ void ParserContext::initialize(int4 maxstate,int4 maxparam,AddrSpace *spc)
|
|||
base_state = &state[0];
|
||||
}
|
||||
|
||||
const Address &ParserContext::getN2addr(void) const
|
||||
|
||||
{
|
||||
if (n2addr.isInvalid()) {
|
||||
if (translate == (Translate *)0 || parsestate == uninitialized)
|
||||
throw LowlevelError("inst_next2 not available in this context");
|
||||
int4 length = translate->instructionLength(naddr);
|
||||
n2addr = naddr + length;
|
||||
}
|
||||
return n2addr;
|
||||
}
|
||||
|
||||
uintm ParserContext::getInstructionBytes(int4 bytestart,int4 size,uint4 off) const
|
||||
|
||||
{ // Get bytes from the instruction stream into a intm
|
||||
|
|
|
@ -64,6 +64,7 @@ struct ContextSet { // Instructions for setting a global context value
|
|||
|
||||
class ParserWalker; // Forward declaration
|
||||
class ParserWalkerChange;
|
||||
class Translate;
|
||||
|
||||
class ParserContext {
|
||||
friend class ParserWalker;
|
||||
|
@ -75,6 +76,7 @@ public:
|
|||
pcode = 2 // Instruction is parsed in preparation for generating p-code
|
||||
};
|
||||
private:
|
||||
Translate *translate; // Instruction parser
|
||||
int4 parsestate;
|
||||
AddrSpace *const_space;
|
||||
uint1 buf[16]; // Buffer of bytes in the instruction stream
|
||||
|
@ -84,13 +86,14 @@ private:
|
|||
vector<ContextSet> contextcommit;
|
||||
Address addr; // Address of start of instruction
|
||||
Address naddr; // Address of next instruction
|
||||
mutable Address n2addr; // Address of instruction after the next
|
||||
Address calladdr; // For injections, this is the address of the call being overridden
|
||||
vector<ConstructState> state; // Current resolved instruction
|
||||
ConstructState *base_state;
|
||||
int4 alloc; // Number of ConstructState's allocated
|
||||
int4 delayslot; // delayslot depth
|
||||
public:
|
||||
ParserContext(ContextCache *ccache);
|
||||
ParserContext(ContextCache *ccache,Translate *trans);
|
||||
~ParserContext(void) { if (context != (uintm *)0) delete [] context; }
|
||||
uint1 *getBuffer(void) { return buf; }
|
||||
void initialize(int4 maxstate,int4 maxparam,AddrSpace *spc);
|
||||
|
@ -98,7 +101,7 @@ public:
|
|||
void setParserState(int4 st) { parsestate = st; }
|
||||
void deallocateState(ParserWalkerChange &walker);
|
||||
void allocateOperand(int4 i,ParserWalkerChange &walker);
|
||||
void setAddr(const Address &ad) { addr = ad; }
|
||||
void setAddr(const Address &ad) { addr = ad; n2addr = Address(); }
|
||||
void setNaddr(const Address &ad) { naddr = ad; }
|
||||
void setCalladdr(const Address &ad) { calladdr = ad; }
|
||||
void addCommit(TripleSymbol *sym,int4 num,uintm mask,bool flow,ConstructState *point);
|
||||
|
@ -106,7 +109,7 @@ public:
|
|||
void applyCommits(void);
|
||||
const Address &getAddr(void) const { return addr; }
|
||||
const Address &getNaddr(void) const { return naddr; }
|
||||
const Address &getN2addr(void) const { return naddr; /* inst_next2 not supported */ }
|
||||
const Address &getN2addr(void) const;
|
||||
const Address &getDestAddr(void) const { return calladdr; }
|
||||
const Address &getRefAddr(void) const { return calladdr; }
|
||||
AddrSpace *getCurSpace(void) const { return addr.getSpace(); }
|
||||
|
|
|
@ -333,7 +333,7 @@ void PcodeInjectLibrarySleigh::parseInject(InjectPayload *payload)
|
|||
throw LowlevelError("Registering pcode snippet before language is instantiated");
|
||||
}
|
||||
if (contextCache.pos == (ParserContext *)0) { // Make sure we have a context
|
||||
contextCache.pos = new ParserContext((ContextCache *)0);
|
||||
contextCache.pos = new ParserContext((ContextCache *)0,(Translate *)0);
|
||||
contextCache.pos->initialize(8,8,slgh->getConstantSpace());
|
||||
}
|
||||
PcodeSnippet compiler(slgh);
|
||||
|
|
|
@ -444,7 +444,7 @@ void DisassemblyCache::initialize(int4 min,int4 hashsize)
|
|||
nextfree = 0;
|
||||
hashtable = new ParserContext *[hashsize];
|
||||
for(int4 i=0;i<minimumreuse;++i) {
|
||||
ParserContext *pos = new ParserContext(contextcache);
|
||||
ParserContext *pos = new ParserContext(contextcache,translate);
|
||||
pos->initialize(75,20,constspace);
|
||||
list[i] = pos;
|
||||
}
|
||||
|
@ -462,13 +462,15 @@ void DisassemblyCache::free(void)
|
|||
delete [] hashtable;
|
||||
}
|
||||
|
||||
/// \param trans is the Translate object instantiating this cache (for inst_next2 callbacks)
|
||||
/// \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)
|
||||
DisassemblyCache::DisassemblyCache(Translate *trans,ContextCache *ccache,AddrSpace *cspace,int4 cachesize,int4 windowsize)
|
||||
|
||||
{
|
||||
translate = trans;
|
||||
contextcache = ccache;
|
||||
constspace = cspace;
|
||||
initialize(cachesize,windowsize); // Set default settings for the cache
|
||||
|
@ -559,7 +561,7 @@ void Sleigh::initialize(DocumentStorage &store)
|
|||
parser_cachesize = 8;
|
||||
parser_windowsize = 256;
|
||||
}
|
||||
discache = new DisassemblyCache(cache,getConstantSpace(),parser_cachesize,parser_windowsize);
|
||||
discache = new DisassemblyCache(this,cache,getConstantSpace(),parser_cachesize,parser_windowsize);
|
||||
}
|
||||
|
||||
/// \brief Obtain a parse tree for the instruction at the given address
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
/// accessing the ContextDatabase and resolving context variables from the SLEIGH spec.
|
||||
/// ParserContext objects are stored in a hash-table keyed by the address of the instruction.
|
||||
class DisassemblyCache {
|
||||
Translate *translate; ///< The Translate object that owns this cache
|
||||
ContextCache *contextcache; ///< Cached values from the ContextDatabase
|
||||
AddrSpace *constspace; ///< The constant address space
|
||||
int4 minimumreuse; ///< Can call getParserContext this many times, before a ParserContext is reused
|
||||
|
@ -113,7 +114,7 @@ class DisassemblyCache {
|
|||
void initialize(int4 min,int4 hashsize); ///< Initialize the hash-table of ParserContexts
|
||||
void free(void); ///< Free the hash-table of ParserContexts
|
||||
public:
|
||||
DisassemblyCache(ContextCache *ccache,AddrSpace *cspace,int4 cachesize,int4 windowsize); ///< Constructor
|
||||
DisassemblyCache(Translate *trans,ContextCache *ccache,AddrSpace *cspace,int4 cachesize,int4 windowsize); ///< Constructor
|
||||
~DisassemblyCache(void) { free(); } ///< Destructor
|
||||
ParserContext *getParserContext(const Address &addr); ///< Get the parser for a particular Address
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue