mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Allow SLEIGH bitrange operator applied to dynamic varnodes
This commit is contained in:
parent
e440e3333f
commit
311a22c038
63 changed files with 1064 additions and 747 deletions
|
@ -644,9 +644,9 @@ void Architecture::restoreFromSpec(DocumentStorage &store)
|
|||
translate = newtrans;
|
||||
modifySpaces(newtrans); // Give architecture chance to modify spaces, before copying
|
||||
copySpaces(newtrans);
|
||||
insertSpace( new FspecSpace(this,translate,"fspec",numSpaces()));
|
||||
insertSpace( new IopSpace(this,translate,"iop",numSpaces()));
|
||||
insertSpace( new JoinSpace(this,translate,"join",numSpaces()));
|
||||
insertSpace( new FspecSpace(this,translate,numSpaces()));
|
||||
insertSpace( new IopSpace(this,translate,numSpaces()));
|
||||
insertSpace( new JoinSpace(this,translate,numSpaces()));
|
||||
userops.initialize(this);
|
||||
if (translate->getAlignment() <= 8)
|
||||
min_funcsymbol_size = translate->getAlignment();
|
||||
|
@ -843,7 +843,7 @@ void Architecture::addOtherSpace(void)
|
|||
|
||||
{
|
||||
Scope *scope = symboltab->getGlobalScope();
|
||||
AddrSpace *otherSpace = getSpaceByName("OTHER");
|
||||
AddrSpace *otherSpace = getSpaceByName(OtherSpace::NAME);
|
||||
symboltab->addRange(scope,otherSpace,0,otherSpace->getHighest());
|
||||
if (otherSpace->isOverlayBase()) {
|
||||
int4 num = numSpaces();
|
||||
|
|
|
@ -1702,16 +1702,17 @@ int4 ParamActive::getNumUsed(void) const
|
|||
return count;
|
||||
}
|
||||
|
||||
const string FspecSpace::NAME = "fspec";
|
||||
|
||||
/// Constructor for the \b fspec space.
|
||||
/// There is only one such space, and it is considered
|
||||
/// internal to the model, i.e. the Translate engine should never
|
||||
/// generate addresses in this space.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name of the space (always \b fspec)
|
||||
/// \param ind is the index associated with the space
|
||||
FspecSpace::FspecSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_FSPEC,nm,sizeof(void *),1,ind,0,1)
|
||||
FspecSpace::FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_FSPEC,NAME,sizeof(void *),1,ind,0,1)
|
||||
{
|
||||
clearFlags(heritaged|does_deadcode|big_endian);
|
||||
if (HOST_ENDIAN==1) // Endianness always set by host
|
||||
|
|
|
@ -286,12 +286,13 @@ public:
|
|||
/// value of the pointer
|
||||
class FspecSpace : public AddrSpace {
|
||||
public:
|
||||
FspecSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); ///< Constructor
|
||||
FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind); ///< Constructor
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset) const;
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const;
|
||||
virtual void printRaw(ostream &s,uintb offset) const;
|
||||
virtual void saveXml(ostream &s) const;
|
||||
virtual void restoreXml(const Element *el);
|
||||
static const string NAME; ///< Reserved name for the fspec space
|
||||
};
|
||||
|
||||
/// \brief Basic elements of a parameter: address, data-type, properties
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
Funcdata::Funcdata(const string &nm,Scope *scope,const Address &addr,FunctionSymbol *sym,int4 sz)
|
||||
: baseaddr(addr),
|
||||
funcp(),
|
||||
vbank(scope->getArch(),
|
||||
scope->getArch()->getUniqueSpace(),
|
||||
0x10000000), // Unique space which is reused per function starts here
|
||||
vbank(scope->getArch()),
|
||||
heritage(this),
|
||||
covermerge(*this)
|
||||
|
||||
|
|
|
@ -278,8 +278,8 @@ void InjectPayloadDynamic::inject(InjectContext &context,PcodeEmit &emit) const
|
|||
emit.restoreXmlOp(*iter,glb->translate);
|
||||
}
|
||||
|
||||
PcodeInjectLibrarySleigh::PcodeInjectLibrarySleigh(Architecture *g,uintb tmpbase)
|
||||
: PcodeInjectLibrary(g,tmpbase)
|
||||
PcodeInjectLibrarySleigh::PcodeInjectLibrarySleigh(Architecture *g)
|
||||
: PcodeInjectLibrary(g,g->translate->getUniqueStart(Translate::INJECT))
|
||||
{
|
||||
slgh = (const SleighBase *)g->translate;
|
||||
contextCache.glb = g;
|
||||
|
|
|
@ -97,7 +97,7 @@ protected:
|
|||
virtual int4 allocateInject(const string &sourceName,const string &name,int4 type);
|
||||
virtual void registerInject(int4 injectid);
|
||||
public:
|
||||
PcodeInjectLibrarySleigh(Architecture *g,uintb tmpbase);
|
||||
PcodeInjectLibrarySleigh(Architecture *g);
|
||||
virtual void restoreDebug(const Element *el);
|
||||
virtual int4 manualCallFixup(const string &name,const string &snippetstring);
|
||||
virtual int4 manualCallOtherFixup(const string &name,const string &outname,const vector<string> &inname,
|
||||
|
|
|
@ -16,16 +16,17 @@
|
|||
#include "op.hh"
|
||||
#include "funcdata.hh"
|
||||
|
||||
const string IopSpace::NAME = "iop";
|
||||
|
||||
/// Constructor for the \b iop space.
|
||||
/// There is only one such space, and it is considered internal
|
||||
/// to the model, i.e. the Translate engine should never generate
|
||||
/// addresses in this space.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name of the space (always \b iop)
|
||||
/// \param ind is the associated index
|
||||
IopSpace::IopSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_IOP,nm,sizeof(void *),1,ind,0,1)
|
||||
IopSpace::IopSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_IOP,NAME,sizeof(void *),1,ind,0,1)
|
||||
{
|
||||
clearFlags(heritaged|does_deadcode|big_endian);
|
||||
if (HOST_ENDIAN==1) // Endianness always set to host
|
||||
|
|
|
@ -31,12 +31,13 @@
|
|||
/// within the \b fspec space.
|
||||
class IopSpace : public AddrSpace {
|
||||
public:
|
||||
IopSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind);
|
||||
IopSpace(AddrSpaceManager *m,const Translate *t,int4 ind);
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset) const { s << " space=\"iop\""; }
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const { s << " space=\"iop\""; }
|
||||
virtual void printRaw(ostream &s,uintb offset) const;
|
||||
virtual void saveXml(ostream &s) const;
|
||||
virtual void restoreXml(const Element *el);
|
||||
static const string NAME; ///< Reserved name for the iop space
|
||||
};
|
||||
|
||||
/// \brief Lowest level operation of the \b p-code language
|
||||
|
|
|
@ -58,7 +58,7 @@ class PcodeCompile {
|
|||
AddrSpace *uniqspace;
|
||||
uint4 local_labelcount; // Number of labels in current constructor
|
||||
bool enforceLocalKey; // Force slaspec to use 'local' keyword when defining temporary varnodes
|
||||
virtual uintb allocateTemp(void)=0;
|
||||
virtual uint4 allocateTemp(void)=0;
|
||||
virtual void addSymbol(SleighSymbol *sym)=0;
|
||||
public:
|
||||
PcodeCompile(void) { defaultspace=(AddrSpace *)0; constantspace=(AddrSpace *)0;
|
||||
|
|
|
@ -162,7 +162,7 @@ public:
|
|||
class PcodeInjectLibrary {
|
||||
protected:
|
||||
Architecture *glb; ///< The Architecture to which the injection payloads apply
|
||||
uintb tempbase; ///< Offset within \e unique space for allocating temporaries within a payload
|
||||
uint4 tempbase; ///< Offset within \e unique space for allocating temporaries within a payload
|
||||
vector<InjectPayload *> injection; ///< Registered injections
|
||||
map<string,int4> callFixupMap; ///< Map of registered call-fixup names to injection id
|
||||
map<string,int4> callOtherFixupMap; ///< Map of registered callother-fixup names to injection id
|
||||
|
@ -195,9 +195,9 @@ protected:
|
|||
/// \param injectid is the id of the InjectPayload to finalize
|
||||
virtual void registerInject(int4 injectid)=0;
|
||||
public:
|
||||
PcodeInjectLibrary(Architecture *g,uintb tmpbase) { glb = g; tempbase = tmpbase; } ///< Constructor
|
||||
PcodeInjectLibrary(Architecture *g,uint4 tmpbase) { glb = g; tempbase = tmpbase; } ///< Constructor
|
||||
virtual ~PcodeInjectLibrary(void); ///< Destructor
|
||||
uintb getUniqueBase(void) const { return tempbase; } ///< Get the (current) offset for building temporary registers
|
||||
uint4 getUniqueBase(void) const { return tempbase; } ///< Get the (current) offset for building temporary registers
|
||||
int4 getPayloadId(int4 type,const string &nm) const; ///< Map name and type to the payload id
|
||||
InjectPayload *getPayload(int4 id) const { return injection[id]; } ///< Get the InjectPayload by id
|
||||
string getCallFixupName(int4 injectid) const; ///< Get the call-fixup name associated with an id
|
||||
|
|
|
@ -3236,10 +3236,10 @@ void PcodeLexer::initialize(istream *t)
|
|||
}
|
||||
}
|
||||
|
||||
uintb PcodeSnippet::allocateTemp(void)
|
||||
uint4 PcodeSnippet::allocateTemp(void)
|
||||
|
||||
{ // Allocate a variable in the unique space and return the offset
|
||||
uintb res = tempbase;
|
||||
uint4 res = tempbase;
|
||||
tempbase += 16;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -71,11 +71,11 @@ class PcodeSnippet : public PcodeCompile {
|
|||
PcodeLexer lexer;
|
||||
const SleighBase *sleigh; // Language from which we get symbols
|
||||
SymbolTree tree; // Symbols in the local scope of the snippet (temporaries)
|
||||
uintb tempbase;
|
||||
uint4 tempbase;
|
||||
int4 errorcount;
|
||||
string firsterror;
|
||||
ConstructTpl *result;
|
||||
virtual uintb allocateTemp(void);
|
||||
virtual uint4 allocateTemp(void);
|
||||
virtual void addSymbol(SleighSymbol *sym);
|
||||
public:
|
||||
PcodeSnippet(const SleighBase *slgh);
|
||||
|
@ -87,8 +87,8 @@ public:
|
|||
virtual void reportWarning(const Location *loc, const string &msg) {}
|
||||
bool hasErrors(void) const { return (errorcount != 0); }
|
||||
const string getErrorMessage(void) const { return firsterror; }
|
||||
void setUniqueBase(uintb val) { tempbase = val; }
|
||||
uintb getUniqueBase(void) const { return tempbase; }
|
||||
void setUniqueBase(uint4 val) { tempbase = val; }
|
||||
uint4 getUniqueBase(void) const { return tempbase; }
|
||||
void clear(void);
|
||||
int lex(void);
|
||||
bool parseStream(istream& s);
|
||||
|
|
|
@ -186,6 +186,30 @@ AddrSpace *SleighBuilder::generatePointer(const VarnodeTpl *vntpl,VarnodeData &v
|
|||
return hand.space;
|
||||
}
|
||||
|
||||
void SleighBuilder::generatePointerAdd(PcodeData *op,const VarnodeTpl *vntpl)
|
||||
|
||||
{
|
||||
uintb offsetPlus = vntpl->getOffset().getReal() & 0xffff;
|
||||
if (offsetPlus == 0) {
|
||||
return;
|
||||
}
|
||||
PcodeData *nextop = cache->allocateInstruction();
|
||||
nextop->opc = op->opc;
|
||||
nextop->invar = op->invar;
|
||||
nextop->isize = op->isize;
|
||||
nextop->outvar = op->outvar;
|
||||
op->isize = 2;
|
||||
op->opc = CPUI_INT_ADD;
|
||||
VarnodeData *newparams = op->invar = cache->allocateVarnodes(2);
|
||||
newparams[0] = nextop->invar[1];
|
||||
newparams[1].space = const_space; // Add in V_OFFSET_PLUS
|
||||
newparams[1].offset = offsetPlus;
|
||||
newparams[1].size = newparams[0].size;
|
||||
op->outvar = nextop->invar + 1; // Output of ADD is input to original op
|
||||
op->outvar->space = uniq_space; // Result of INT_ADD in special runtime temp
|
||||
op->outvar->offset = uniq_space->getTrans()->getUniqueStart(Translate::RUNTIME_BITRANGE_EA);
|
||||
}
|
||||
|
||||
void SleighBuilder::dump(OpTpl *op)
|
||||
|
||||
{ // Dump on op through low-level dump interface
|
||||
|
@ -211,6 +235,8 @@ void SleighBuilder::dump(OpTpl *op)
|
|||
loadvars[0].space = const_space;
|
||||
loadvars[0].offset = (uintb)(uintp)spc;
|
||||
loadvars[0].size = sizeof(spc);
|
||||
if (vn->getOffset().getSelect() == ConstTpl::v_offset_plus)
|
||||
generatePointerAdd(load_op, vn);
|
||||
}
|
||||
else
|
||||
generateLocation(vn,invars[i]);
|
||||
|
@ -238,6 +264,8 @@ void SleighBuilder::dump(OpTpl *op)
|
|||
storevars[0].space = const_space;
|
||||
storevars[0].offset = (uintb)(uintp)spc; // space in which to store
|
||||
storevars[0].size = sizeof(spc);
|
||||
if (outvn->getOffset().getSelect() == ConstTpl::v_offset_plus)
|
||||
generatePointerAdd(store_op,outvn);
|
||||
}
|
||||
else {
|
||||
thisop->outvar = cache->allocateVarnodes(1);
|
||||
|
|
|
@ -136,6 +136,7 @@ class SleighBuilder : public PcodeBuilder {
|
|||
void buildEmpty(Constructor *ct,int4 secnum);
|
||||
void generateLocation(const VarnodeTpl *vntpl,VarnodeData &vn);
|
||||
AddrSpace *generatePointer(const VarnodeTpl *vntpl,VarnodeData &vn);
|
||||
void generatePointerAdd(PcodeData *op,const VarnodeTpl *vntpl);
|
||||
void setUniqueOffset(const Address &addr); ///< Set uniquifying bits for the current instruction
|
||||
public:
|
||||
SleighBuilder(ParserWalker *w,DisassemblyCache *dcache,PcodeCacher *pc,AddrSpace *cspc,AddrSpace *uspc,uint4 umask);
|
||||
|
|
|
@ -161,7 +161,7 @@ PcodeInjectLibrary *SleighArchitecture::buildPcodeInjectLibrary(void)
|
|||
{ // Build the pcode injector based on sleigh
|
||||
PcodeInjectLibrary *res;
|
||||
|
||||
res = new PcodeInjectLibrarySleigh(this,translate->getUniqueBase());
|
||||
res = new PcodeInjectLibrarySleigh(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
const int4 SleighBase::SLA_FORMAT_VERSION = 3;
|
||||
|
||||
const uintb SleighBase::MAX_UNIQUE_SIZE = 128;
|
||||
const uint4 SleighBase::MAX_UNIQUE_SIZE = 128;
|
||||
|
||||
int4 SourceFileIndexer::index(const string filename){
|
||||
auto it = fileToIndex.find(filename);
|
||||
|
|
|
@ -69,7 +69,7 @@ protected:
|
|||
void reregisterContext(void); ///< Reregister context fields for a new executable
|
||||
void restoreXml(const Element *el); ///< Read a SLEIGH specification from XML
|
||||
public:
|
||||
static const uintb MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java)
|
||||
static const uint4 MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java)
|
||||
SleighBase(void); ///< Construct an uninitialized translator
|
||||
bool isInitialized(void) const { return (root != (SubtableSymbol *)0); } ///< Return \b true if \b this is initialized
|
||||
virtual ~SleighBase(void) {} ///< Destructor
|
||||
|
|
|
@ -1739,7 +1739,7 @@ void MacroBuilder::setLabel(OpTpl *op)
|
|||
outvec.push_back(clone);
|
||||
}
|
||||
|
||||
uintb SleighPcode::allocateTemp(void)
|
||||
uint4 SleighPcode::allocateTemp(void)
|
||||
|
||||
{
|
||||
return compiler->getUniqueAddr();
|
||||
|
@ -1799,14 +1799,14 @@ void SleighCompile::predefinedSymbols(void)
|
|||
// Some predefined symbols
|
||||
root = new SubtableSymbol("instruction"); // Base constructors
|
||||
symtab.addSymbol(root);
|
||||
insertSpace(new ConstantSpace(this,this,"const",AddrSpace::constant_space_index));
|
||||
insertSpace(new ConstantSpace(this,this));
|
||||
SpaceSymbol *spacesym = new SpaceSymbol(getConstantSpace()); // Constant space
|
||||
symtab.addSymbol(spacesym);
|
||||
OtherSpace *otherSpace = new OtherSpace(this,this,"OTHER",AddrSpace::other_space_index);
|
||||
OtherSpace *otherSpace = new OtherSpace(this,this,OtherSpace::INDEX);
|
||||
insertSpace(otherSpace);
|
||||
spacesym = new SpaceSymbol(otherSpace);
|
||||
symtab.addSymbol(spacesym);
|
||||
insertSpace(new UniqueSpace(this,this,"unique",numSpaces(),0));
|
||||
insertSpace(new UniqueSpace(this,this,numSpaces(),0));
|
||||
spacesym = new SpaceSymbol(getUniqueSpace()); // Temporary register space
|
||||
symtab.addSymbol(spacesym);
|
||||
StartSymbol *startsym = new StartSymbol("inst_start",getConstantSpace());
|
||||
|
@ -2271,10 +2271,10 @@ void SleighCompile::reportWarning(const string &msg)
|
|||
/// this method does not make an assumption about the size of the requested temporary Varnode.
|
||||
/// It reserves a fixed amount of space and returns its starting offset.
|
||||
/// \return the starting offset of the new temporary register
|
||||
uintb SleighCompile::getUniqueAddr(void)
|
||||
uint4 SleighCompile::getUniqueAddr(void)
|
||||
|
||||
{
|
||||
uintb base = getUniqueBase();
|
||||
uint4 base = getUniqueBase();
|
||||
setUniqueBase(base + SleighBase::MAX_UNIQUE_SIZE);
|
||||
return base;
|
||||
}
|
||||
|
@ -3422,7 +3422,7 @@ void SleighCompile::checkUniqueAllocation(void)
|
|||
if (i>=tables.size()) break;
|
||||
sym = tables[i];
|
||||
}
|
||||
uintm ubase = getUniqueBase(); // We have to adjust the unique base
|
||||
uint4 ubase = getUniqueBase(); // We have to adjust the unique base
|
||||
ubase <<= sa;
|
||||
setUniqueBase(ubase);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ public:
|
|||
/// parser.
|
||||
class SleighPcode : public PcodeCompile {
|
||||
SleighCompile *compiler; ///< The main SLEIGH parser
|
||||
virtual uintb allocateTemp(void);
|
||||
virtual uint4 allocateTemp(void);
|
||||
virtual const Location *getLocation(SleighSymbol *sym) const;
|
||||
virtual void reportError(const Location* loc, const string &msg);
|
||||
virtual void reportWarning(const Location* loc, const string &msg);
|
||||
|
@ -332,7 +332,7 @@ public:
|
|||
void reportWarning(const Location *loc, const string &msg); ///< Issue a warning message with a source location
|
||||
int4 numErrors(void) const { return errors; } ///< Return the current number of fatal errors
|
||||
|
||||
uintb getUniqueAddr(void); ///< Get the next available temporary register offset
|
||||
uint4 getUniqueAddr(void); ///< Get the next available temporary register offset
|
||||
|
||||
/// \brief Set whether unnecessary truncation and extension operators generate warnings individually
|
||||
///
|
||||
|
|
|
@ -350,16 +350,17 @@ void AddrSpace::restoreXml(const Element *el)
|
|||
calcScaleMask();
|
||||
}
|
||||
|
||||
const string ConstantSpace::NAME = "const";
|
||||
|
||||
const int4 ConstantSpace::INDEX = 0;
|
||||
|
||||
/// This constructs the unique constant space
|
||||
/// By convention, the name is always "const" and the index
|
||||
/// is always 0.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name
|
||||
/// \param ind is the integer identifier
|
||||
ConstantSpace::ConstantSpace(AddrSpaceManager *m,const Translate *t,
|
||||
const string &nm,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_CONSTANT,nm,sizeof(uintb),1,ind,0,0)
|
||||
ConstantSpace::ConstantSpace(AddrSpaceManager *m,const Translate *t)
|
||||
: AddrSpace(m,t,IPTR_CONSTANT,NAME,sizeof(uintb),1,INDEX,0,0)
|
||||
{
|
||||
clearFlags(heritaged|does_deadcode|big_endian);
|
||||
if (HOST_ENDIAN==1) // Endianness always matches host
|
||||
|
@ -390,16 +391,18 @@ void ConstantSpace::restoreXml(const Element *el)
|
|||
throw LowlevelError("Should never restore the constant space from XML");
|
||||
}
|
||||
|
||||
const string OtherSpace::NAME = "OTHER";
|
||||
|
||||
const int4 OtherSpace::INDEX = 1;
|
||||
|
||||
/// Construct the \b other space, which is automatically constructed
|
||||
/// by the compiler, and is only constructed once. The name should
|
||||
/// always by \b OTHER.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name of the space
|
||||
/// \param ind is the integer identifier
|
||||
OtherSpace::OtherSpace(AddrSpaceManager *m,const Translate *t,
|
||||
const string &nm,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_PROCESSOR,nm,sizeof(uintb),1,ind,0,0)
|
||||
OtherSpace::OtherSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_PROCESSOR,NAME,sizeof(uintb),1,INDEX,0,0)
|
||||
{
|
||||
clearFlags(heritaged|does_deadcode);
|
||||
setFlags(is_otherspace);
|
||||
|
@ -426,17 +429,19 @@ void OtherSpace::saveXml(ostream &s) const
|
|||
s << "/>\n";
|
||||
}
|
||||
|
||||
const string UniqueSpace::NAME = "unique";
|
||||
|
||||
const uint4 UniqueSpace::SIZE = 4;
|
||||
|
||||
/// This is the constructor for the \b unique space, which is
|
||||
/// automatically constructed by the analysis engine, and
|
||||
/// constructed only once. The name should always be \b unique.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name of the space
|
||||
/// \param ind is the integer identifier
|
||||
/// \param fl are attribute flags (currently unused)
|
||||
UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t,const string &nm,
|
||||
int4 ind,uint4 fl)
|
||||
: AddrSpace(m,t,IPTR_INTERNAL,nm,sizeof(uintm),1,ind,fl,0)
|
||||
UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl)
|
||||
: AddrSpace(m,t,IPTR_INTERNAL,NAME,SIZE,1,ind,fl,0)
|
||||
{
|
||||
setFlags(hasphysical);
|
||||
}
|
||||
|
@ -455,14 +460,15 @@ void UniqueSpace::saveXml(ostream &s) const
|
|||
s << "/>\n";
|
||||
}
|
||||
|
||||
const string JoinSpace::NAME = "join";
|
||||
|
||||
/// This is the constructor for the \b join space, which is automatically constructed by the
|
||||
/// analysis engine, and constructed only once. The name should always be \b join.
|
||||
/// \param m is the associated address space manager
|
||||
/// \param t is the associated processor translator
|
||||
/// \param nm is the name of the space
|
||||
/// \param ind is the integer identifier
|
||||
JoinSpace::JoinSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_JOIN,nm,sizeof(uintm),1,ind,0,0)
|
||||
JoinSpace::JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
|
||||
: AddrSpace(m,t,IPTR_JOIN,NAME,sizeof(uintm),1,ind,0,0)
|
||||
{
|
||||
// This is a virtual space
|
||||
// setFlags(hasphysical);
|
||||
|
|
|
@ -86,10 +86,6 @@ public:
|
|||
is_otherspace = 512, ///< Quick check for the OtherSpace derived class
|
||||
has_nearpointers = 0x400 ///< Does there exist near pointers into this space
|
||||
};
|
||||
enum {
|
||||
constant_space_index = 0, ///< Reserved index for the constant space
|
||||
other_space_index = 1 ///< Reserved index for the other space
|
||||
};
|
||||
private:
|
||||
spacetype type; ///< Type of space (PROCESSOR, CONSTANT, INTERNAL, ...)
|
||||
AddrSpaceManager *manage; ///< Manager for processor using this space
|
||||
|
@ -178,19 +174,23 @@ public:
|
|||
/// by the offset field of an Address.
|
||||
class ConstantSpace : public AddrSpace {
|
||||
public:
|
||||
ConstantSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); ///< Only constructor
|
||||
ConstantSpace(AddrSpaceManager *m,const Translate *t); ///< Only constructor
|
||||
virtual void printRaw(ostream &s,uintb offset) const;
|
||||
virtual void saveXml(ostream &s) const;
|
||||
virtual void restoreXml(const Element *el);
|
||||
static const string NAME; // Reserved name for the address space
|
||||
static const int4 INDEX; // Reserved index for constant space
|
||||
};
|
||||
|
||||
/// \brief Special AddrSpace for special/user-defined address spaces
|
||||
class OtherSpace : public AddrSpace {
|
||||
public:
|
||||
OtherSpace(AddrSpaceManager *m, const Translate *t, const string &nm, int4 ind); ///< Constructor
|
||||
OtherSpace(AddrSpaceManager *m, const Translate *t, int4 ind); ///< Constructor
|
||||
OtherSpace(AddrSpaceManager *m, const Translate *t); ///< For use with restoreXml
|
||||
virtual void printRaw(ostream &s, uintb offset) const;
|
||||
virtual void saveXml(ostream &s) const;
|
||||
static const string NAME; // Reserved name for the address space
|
||||
static const int4 INDEX; // Reserved index for the other space
|
||||
};
|
||||
|
||||
/// \brief The pool of temporary storage registers
|
||||
|
@ -204,9 +204,11 @@ public:
|
|||
/// \b unique.
|
||||
class UniqueSpace : public AddrSpace {
|
||||
public:
|
||||
UniqueSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind,uint4 fl); ///< Constructor
|
||||
UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl); ///< Constructor
|
||||
UniqueSpace(AddrSpaceManager *m,const Translate *t); ///< For use with restoreXml
|
||||
virtual void saveXml(ostream &s) const;
|
||||
static const string NAME; ///< Reserved name for the unique space
|
||||
static const uint4 SIZE; ///< Fixed size (in bytes) for unique space offsets
|
||||
};
|
||||
|
||||
/// \brief The pool of logically joined variables
|
||||
|
@ -219,7 +221,7 @@ public:
|
|||
/// have an absolute meaning, the database may vary what offset is assigned to what set of pieces.
|
||||
class JoinSpace : public AddrSpace {
|
||||
public:
|
||||
JoinSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind);
|
||||
JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind);
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset) const;
|
||||
virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const;
|
||||
virtual uintb restoreXmlAttributes(const Element *el,uint4 &size) const;
|
||||
|
@ -227,6 +229,7 @@ public:
|
|||
virtual uintb read(const string &s,int4 &size) const;
|
||||
virtual void saveXml(ostream &s) const;
|
||||
virtual void restoreXml(const Element *el);
|
||||
static const string NAME; ///< Reserved name for the join space
|
||||
};
|
||||
|
||||
/// \brief An overlay space.
|
||||
|
|
|
@ -229,7 +229,7 @@ void AddrSpaceManager::restoreXmlSpaces(const Element *el,const Translate *trans
|
|||
|
||||
{
|
||||
// The first space should always be the constant space
|
||||
insertSpace(new ConstantSpace(this,trans,"const",AddrSpace::constant_space_index));
|
||||
insertSpace(new ConstantSpace(this,trans));
|
||||
|
||||
string defname(el->getAttributeValue("defaultspace"));
|
||||
const List &list(el->getChildren());
|
||||
|
@ -302,14 +302,14 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
|||
bool duplicateId = false;
|
||||
switch(spc->getType()) {
|
||||
case IPTR_CONSTANT:
|
||||
if (spc->getName() != "const")
|
||||
if (spc->getName() != ConstantSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
if (spc->index != AddrSpace::constant_space_index)
|
||||
if (spc->index != ConstantSpace::INDEX)
|
||||
throw LowlevelError("const space must be assigned index 0");
|
||||
constantspace = spc;
|
||||
break;
|
||||
case IPTR_INTERNAL:
|
||||
if (spc->getName() != "unique")
|
||||
if (spc->getName() != UniqueSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
if (uniqspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
|
@ -323,7 +323,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
|||
fspecspace = spc;
|
||||
break;
|
||||
case IPTR_JOIN:
|
||||
if (spc->getName() != "join")
|
||||
if (spc->getName() != JoinSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
if (joinspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
|
@ -349,7 +349,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
|||
ospc->getBaseSpace()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed
|
||||
}
|
||||
else if (spc->isOtherSpace()) {
|
||||
if (spc->index != AddrSpace::other_space_index)
|
||||
if (spc->index != OtherSpace::INDEX)
|
||||
throw LowlevelError("OTHER space must be assigned index 1");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -292,21 +292,32 @@ public:
|
|||
/// with the processor. In particular, it knows about all the
|
||||
/// address spaces, registers, and spacebases for the processor.
|
||||
class Translate : public AddrSpaceManager {
|
||||
public:
|
||||
/// Tagged addresses in the \e unique address space
|
||||
enum UniqueLayout {
|
||||
RUNTIME_BOOLEAN_INVERT=0, ///< Location of the runtime temporary for boolean inversion
|
||||
RUNTIME_RETURN_LOCATION=0x80, ///< Location of the runtime temporary storing the return value
|
||||
RUNTIME_BITRANGE_EA=0x100, ///< Location of the runtime temporary for storing an effective address
|
||||
INJECT=0x200, ///< Range of temporaries for use in compiling p-code snippets
|
||||
ANALYSIS=0x10000000 ///< Range of temporaries for use during decompiler analysis
|
||||
};
|
||||
private:
|
||||
bool target_isbigendian; ///< \b true if the general endianness of the process is big endian
|
||||
uintm unique_base; ///< Starting offset into unique space
|
||||
uint4 unique_base; ///< Starting offset into unique space
|
||||
protected:
|
||||
int4 alignment; ///< Byte modulo on which instructions are aligned
|
||||
vector<FloatFormat> floatformats; ///< Floating point formats utilized by the processor
|
||||
|
||||
void setBigEndian(bool val); ///< Set general endianness to \b big if val is \b true
|
||||
void setUniqueBase(uintm val); ///< Set the base offset for new temporary registers
|
||||
void setUniqueBase(uint4 val); ///< Set the base offset for new temporary registers
|
||||
public:
|
||||
Translate(void); ///< Constructor for the translator
|
||||
void setDefaultFloatFormats(void); ///< If no explicit float formats, set up default formats
|
||||
bool isBigEndian(void) const; ///< Is the processor big endian?
|
||||
const FloatFormat *getFloatFormat(int4 size) const; ///< Get format for a particular floating point encoding
|
||||
int4 getAlignment(void) const; ///< Get the instruction alignment for the processor
|
||||
uintm getUniqueBase(void) const; ///< Get the base offset for new temporary registers
|
||||
uint4 getUniqueBase(void) const; ///< Get the base offset for new temporary registers
|
||||
uint4 getUniqueStart(UniqueLayout layout) const; ///< Get a tagged address within the \e unique space
|
||||
|
||||
/// \brief Initialize the translator given XML configuration documents
|
||||
///
|
||||
|
@ -551,7 +562,7 @@ inline void Translate::setBigEndian(bool val) {
|
|||
/// for the pcode engine, and sets the base offset where registers
|
||||
/// created by the simplification process can start being allocated.
|
||||
/// \param val is the boundary offset
|
||||
inline void Translate::setUniqueBase(uintm val) {
|
||||
inline void Translate::setUniqueBase(uint4 val) {
|
||||
if (val>unique_base) unique_base = val;
|
||||
}
|
||||
|
||||
|
@ -573,14 +584,19 @@ inline int4 Translate::getAlignment(void) const {
|
|||
return alignment;
|
||||
}
|
||||
|
||||
/// This routine gets the base offset, within the \e unique
|
||||
/// temporary register space, where new registers can be
|
||||
/// allocated for the simplification process. Locations before
|
||||
/// this offset are reserved registers needed by the pcode
|
||||
/// translation engine.
|
||||
/// Return the first offset within the \e unique space after the range statically reserved by Translate.
|
||||
/// This is generally the starting offset where dynamic temporary registers can start to be allocated.
|
||||
/// \return the first allocatable offset
|
||||
inline uintm Translate::getUniqueBase(void) const {
|
||||
inline uint4 Translate::getUniqueBase(void) const {
|
||||
return unique_base;
|
||||
}
|
||||
|
||||
/// Regions of the \e unique space are reserved for specific uses. We select the start of a specific
|
||||
/// region based on the given tag.
|
||||
/// \param layout is the given tag
|
||||
/// \return the absolute offset into the \e unique space
|
||||
inline uint4 Translate::getUniqueStart(UniqueLayout layout) const {
|
||||
return (layout != ANALYSIS) ? layout + unique_base : layout;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -852,17 +852,15 @@ void Varnode::printRaw(ostream &s,const Varnode *vn)
|
|||
}
|
||||
|
||||
/// \param m is the underlying address space manager
|
||||
/// \param uspace is the \e unique space
|
||||
/// \param ubase is the base offset for allocating temporaries
|
||||
VarnodeBank::VarnodeBank(AddrSpaceManager *m,AddrSpace *uspace,uintm ubase)
|
||||
VarnodeBank::VarnodeBank(AddrSpaceManager *m)
|
||||
: searchvn(0,Address(Address::m_minimal),(Datatype *)0)
|
||||
|
||||
{
|
||||
manage = m;
|
||||
searchvn.flags = Varnode::input; // searchvn is always an input varnode of size 0
|
||||
uniq_space = uspace;
|
||||
uniqbase = ubase;
|
||||
uniqid = ubase;
|
||||
uniq_space = m->getUniqueSpace();
|
||||
uniqbase = uniq_space->getTrans()->getUniqueStart(Translate::ANALYSIS);
|
||||
uniqid = uniqbase;
|
||||
create_index = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ class VarnodeBank {
|
|||
mutable Varnode searchvn; ///< Template varnode for searching trees
|
||||
Varnode *xref(Varnode *vn); ///< Insert a Varnode into the sorted lists
|
||||
public:
|
||||
VarnodeBank(AddrSpaceManager *m,AddrSpace *uspace,uintm ubase); ///< Construct the container
|
||||
VarnodeBank(AddrSpaceManager *m); ///< Construct the container
|
||||
void clear(void); ///< Clear out all Varnodes and reset counters
|
||||
~VarnodeBank(void) { clear(); } ///< Destructor
|
||||
int4 numVarnodes(void) const { return loc_tree.size(); } ///< Get number of Varnodes \b this contains
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue