mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
Decompiler support for default data space
This commit is contained in:
parent
660062691a
commit
46e8a54948
21 changed files with 97 additions and 65 deletions
|
@ -289,7 +289,7 @@ void Range::restoreXml(const Element *el,const AddrSpaceManager *manage)
|
|||
s >> last;
|
||||
}
|
||||
else if (el->getAttributeName(i) == "name") {
|
||||
const Translate *trans = manage->getDefaultSpace()->getTrans();
|
||||
const Translate *trans = manage->getDefaultCodeSpace()->getTrans();
|
||||
const VarnodeData &point(trans->getRegister(el->getAttributeValue(i)));
|
||||
spc = point.space;
|
||||
first = point.offset;
|
||||
|
|
|
@ -652,7 +652,8 @@ void Architecture::cacheAddrSpaceProperties(void)
|
|||
|
||||
{
|
||||
vector<AddrSpace *> copyList = inferPtrSpaces;
|
||||
copyList.push_back(getDefaultSpace()); // Make sure the default space is their
|
||||
copyList.push_back(getDefaultCodeSpace()); // Make sure the default code space is present
|
||||
copyList.push_back(getDefaultDataSpace()); // Make sure the default data space is present
|
||||
inferPtrSpaces.clear();
|
||||
sort(copyList.begin(),copyList.end(),AddrSpace::compareByIndex);
|
||||
AddrSpace *lastSpace = (AddrSpace *)0;
|
||||
|
@ -670,7 +671,7 @@ void Architecture::cacheAddrSpaceProperties(void)
|
|||
int4 defPos = -1;
|
||||
for(int4 i=0;i<inferPtrSpaces.size();++i) {
|
||||
AddrSpace *spc = inferPtrSpaces[i];
|
||||
if (spc == getDefaultSpace())
|
||||
if (spc == getDefaultDataSpace()) // Make the default for inferring pointers the data space
|
||||
defPos = i;
|
||||
SegmentOp *segOp = getSegmentOp(spc);
|
||||
if (segOp != (SegmentOp *)0) {
|
||||
|
@ -1085,6 +1086,12 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
|
|||
else if (elname == "register_data") {
|
||||
parseLaneSizes(*iter);
|
||||
}
|
||||
else if (elname == "data_space") {
|
||||
AddrSpace *spc = getSpaceByName(el->getAttributeValue("space"));
|
||||
if (spc == (AddrSpace *)0)
|
||||
throw LowlevelError("Undefined space: "+el->getAttributeValue("space"));
|
||||
setDefaultDataSpace(spc->getIndex());
|
||||
}
|
||||
else if (elname == "segmented_address") {
|
||||
}
|
||||
else if (elname == "default_symbols") {
|
||||
|
@ -1095,8 +1102,6 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
|
|||
}
|
||||
else if (elname == "properties") {
|
||||
}
|
||||
else if (elname == "data_space") {
|
||||
}
|
||||
else
|
||||
throw LowlevelError("Unknown element in <processor_spec>: "+elname);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ void BfdArchitecture::postSpecFile(void)
|
|||
|
||||
{ // Attach default space to loader
|
||||
Architecture::postSpecFile();
|
||||
((LoadImageBfd *)loader)->attachToSpace(getDefaultSpace());
|
||||
((LoadImageBfd *)loader)->attachToSpace(getDefaultCodeSpace());
|
||||
}
|
||||
|
||||
/// This just wraps the base class constructor
|
||||
|
|
|
@ -432,7 +432,7 @@ void CodeDataAnalysis::addTargetHit(const Address &codeaddr,uintb targethit)
|
|||
targethits.push_back(TargetHit());
|
||||
targethits.back().funcstart = findFunctionStart( codeaddr );
|
||||
targethits.back().codeaddr = codeaddr;
|
||||
targethits.back().thunkaddr = Address(glb->translate->getDefaultSpace(),targethit);
|
||||
targethits.back().thunkaddr = Address(glb->translate->getDefaultCodeSpace(),targethit);
|
||||
map<Address,TargetFeature>::const_iterator titer;
|
||||
titer = targets.find( targethits.back().thunkaddr );
|
||||
if (titer != targets.end())
|
||||
|
|
|
@ -3627,7 +3627,7 @@ int4 ActionPrototypeTypes::apply(Funcdata &data)
|
|||
else
|
||||
data.initActiveOutput(); // Initiate gathering potential return values
|
||||
|
||||
AddrSpace *spc = data.getArch()->getDefaultSpace();
|
||||
AddrSpace *spc = data.getArch()->getDefaultCodeSpace();
|
||||
if (spc->isTruncated()) {
|
||||
// For truncated spaces we need a zext op, from the truncated stack pointer
|
||||
// into the full stack pointer
|
||||
|
@ -4244,7 +4244,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
|
|||
case CPUI_INT_OR:
|
||||
case CPUI_INT_XOR:
|
||||
if (invn->isSpacebase()) {
|
||||
AddrSpace *spc = typegrp->getArch()->getDefaultSpace();
|
||||
AddrSpace *spc = typegrp->getArch()->getDefaultDataSpace();
|
||||
newtype = typegrp->getTypePointer(alttype->getSize(),typegrp->getBase(1,TYPE_UNKNOWN),spc->getWordSize());
|
||||
}
|
||||
else
|
||||
|
@ -4260,7 +4260,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
|
|||
break;
|
||||
case CPUI_SEGMENTOP:
|
||||
{
|
||||
AddrSpace *spc = typegrp->getArch()->getDefaultSpace();
|
||||
AddrSpace *spc = typegrp->getArch()->getDefaultDataSpace();
|
||||
Datatype *btype = ((TypePointer *)alttype)->getPtrTo();
|
||||
newtype = typegrp->getTypePointer(outvn->getSize(),btype,spc->getWordSize());
|
||||
}
|
||||
|
|
|
@ -441,8 +441,8 @@ inline Address EmulatePcodeCache::getExecuteAddress(void) const
|
|||
\code
|
||||
void setupMemoryState(Translate &trans,LoadImage &loader) {
|
||||
// Set up memory state object
|
||||
MemoryImage loadmemory(trans.getDefaultSpace(),8,4096,&loader);
|
||||
MemoryPageOverlay ramstate(trans.getDefaultSpace(),8,4096,&loadmemory);
|
||||
MemoryImage loadmemory(trans.getDefaultCodeSpace(),8,4096,&loader);
|
||||
MemoryPageOverlay ramstate(trans.getDefaultCodeSpace(),8,4096,&loadmemory);
|
||||
MemoryHashOverlay registerstate(trans.getSpaceByName("register"),8,4096,4096,(MemoryBank *)0);
|
||||
MemoryHashOverlay tmpstate(trans.getUniqueSpace(),8,4096,4096,(MemoryBank *)0);
|
||||
|
||||
|
@ -518,10 +518,10 @@ inline Address EmulatePcodeCache::getExecuteAddress(void) const
|
|||
|
||||
// Set up the initial stack pointer
|
||||
memstate.setValue("ESP",0xbffffffc);
|
||||
emulator.setExecuteAddress(Address(trans.getDefaultSpace(),0x1D00114)); // Initial execution address
|
||||
emulator.setExecuteAddress(Address(trans.getDefaultCodeSpace(),0x1D00114)); // Initial execution address
|
||||
|
||||
PutsCallBack putscallback;
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultSpace(),0x1D00130),&putscallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultCodeSpace(),0x1D00130),&putscallback);
|
||||
|
||||
AssemblyRaw assememit;
|
||||
for(;;) {
|
||||
|
|
|
@ -550,7 +550,7 @@ void ParamListStandard::assignMap(const vector<Datatype *> &proto,bool isinput,T
|
|||
// Assume datatype is stored elsewhere and only the pointer is passed
|
||||
AddrSpace *spc = spacebase;
|
||||
if (spc == (AddrSpace *)0)
|
||||
spc = typefactory.getArch()->getDefaultSpace();
|
||||
spc = typefactory.getArch()->getDefaultDataSpace();
|
||||
int4 pointersize = spc->getAddrSize();
|
||||
int4 wordsize = spc->getWordSize();
|
||||
Datatype *pointertp = typefactory.getTypePointerAbsolute(pointersize,proto[i],wordsize);
|
||||
|
@ -1096,7 +1096,7 @@ void ParamListStandardOut::assignMap(const vector<Datatype *> &proto,bool isinpu
|
|||
if (res.back().addr.isInvalid()) { // Could not assign an address (too big)
|
||||
AddrSpace *spc = spacebase;
|
||||
if (spc == (AddrSpace *)0)
|
||||
spc = typefactory.getArch()->getDefaultSpace();
|
||||
spc = typefactory.getArch()->getDefaultDataSpace();
|
||||
int4 pointersize = spc->getAddrSize();
|
||||
int4 wordsize = spc->getWordSize();
|
||||
Datatype *pointertp = typefactory.getTypePointerAbsolute(pointersize, proto[0], wordsize);
|
||||
|
|
|
@ -652,9 +652,9 @@ void GrammarLexer::getNextToken(GrammarToken &token)
|
|||
Datatype *PointerModifier::modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const
|
||||
|
||||
{
|
||||
int4 addrsize = glb->getDefaultSize();
|
||||
int4 addrsize = glb->getDefaultDataSpace()->getAddrSize();
|
||||
Datatype *restype;
|
||||
restype = glb->types->getTypePointerAbsolute(addrsize,base,glb->getDefaultSpace()->getWordSize());
|
||||
restype = glb->types->getTypePointerAbsolute(addrsize,base,glb->getDefaultDataSpace()->getWordSize());
|
||||
return restype;
|
||||
}
|
||||
|
||||
|
@ -1495,7 +1495,7 @@ Address parse_machaddr(istream &s,int4 &defaultsize,const TypeFactory &typegrp,b
|
|||
}
|
||||
else {
|
||||
if (tok == '0') {
|
||||
b = manage->getDefaultSpace();
|
||||
b = manage->getDefaultCodeSpace();
|
||||
}
|
||||
else {
|
||||
b = manage->getSpaceByShortcut(tok);
|
||||
|
|
|
@ -117,7 +117,7 @@ void ExecutablePcode::build(void)
|
|||
icontext.clear();
|
||||
uintb uniqReserve = 0x10; // Temporary register space reserved for inputs and output
|
||||
Architecture *glb = emulator.getArch();
|
||||
AddrSpace *codeSpace = glb->getDefaultSpace();
|
||||
AddrSpace *codeSpace = glb->getDefaultCodeSpace();
|
||||
AddrSpace *uniqSpace = glb->getUniqueSpace();
|
||||
icontext.baseaddr = Address(codeSpace,0x1000); // Fake address
|
||||
icontext.nextaddr = icontext.baseaddr;
|
||||
|
|
|
@ -686,7 +686,7 @@ PcodeSnippet::PcodeSnippet(const SleighBase *slgh)
|
|||
tempbase = 0;
|
||||
errorcount = 0;
|
||||
result = (ConstructTpl *)0;
|
||||
setDefaultSpace(slgh->getDefaultSpace());
|
||||
setDefaultSpace(slgh->getDefaultCodeSpace());
|
||||
setConstantSpace(slgh->getConstantSpace());
|
||||
setUniqueSpace(slgh->getUniqueSpace());
|
||||
int4 num = slgh->numSpaces();
|
||||
|
|
|
@ -34,7 +34,7 @@ void VarnodeData::restoreXml(const Element *el,const AddrSpaceManager *manage)
|
|||
return;
|
||||
}
|
||||
else if (el->getAttributeName(i)=="name") {
|
||||
const Translate *trans = manage->getDefaultSpace()->getTrans();
|
||||
const Translate *trans = manage->getDefaultCodeSpace()->getTrans();
|
||||
const VarnodeData &point(trans->getRegister(el->getAttributeValue(i)));
|
||||
*this = point;
|
||||
return;
|
||||
|
|
|
@ -1414,7 +1414,7 @@ bool PrintC::pushPtrCharConstant(uintb val,const TypePointer *ct,const Varnode *
|
|||
|
||||
{
|
||||
if (val==0) return false;
|
||||
AddrSpace *spc = glb->getDefaultSpace();
|
||||
AddrSpace *spc = glb->getDefaultDataSpace();
|
||||
uintb fullEncoding;
|
||||
Address stringaddr = glb->resolveConstant(spc,val,ct->getSize(),op->getAddr(),fullEncoding);
|
||||
if (stringaddr.isInvalid()) return false;
|
||||
|
@ -1443,7 +1443,7 @@ bool PrintC::pushPtrCodeConstant(uintb val,const TypePointer *ct,
|
|||
const Varnode *vn,
|
||||
const PcodeOp *op)
|
||||
{
|
||||
AddrSpace *spc = glb->getDefaultSpace();
|
||||
AddrSpace *spc = glb->getDefaultCodeSpace();
|
||||
Funcdata *fd = (Funcdata *)0;
|
||||
val = AddrSpace::addressToByte(val,spc->getWordSize());
|
||||
fd = glb->symboltab->getGlobalScope()->queryFunction( Address(spc,val));
|
||||
|
|
|
@ -72,7 +72,7 @@ void RawBinaryArchitecture::postSpecFile(void)
|
|||
|
||||
{
|
||||
Architecture::postSpecFile();
|
||||
((RawLoadImage *)loader)->attachToSpace(getDefaultSpace()); // Attach default space to loader
|
||||
((RawLoadImage *)loader)->attachToSpace(getDefaultCodeSpace()); // Attach default space to loader
|
||||
}
|
||||
|
||||
RawBinaryArchitecture::RawBinaryArchitecture(const string &fname,const string &targ,ostream *estream)
|
||||
|
|
|
@ -7348,7 +7348,7 @@ RulePtrFlow::RulePtrFlow(const string &g,Architecture *conf)
|
|||
: Rule( g, 0, "ptrflow")
|
||||
{
|
||||
glb = conf;
|
||||
hasTruncations = glb->getDefaultSpace()->isTruncated();
|
||||
hasTruncations = glb->getDefaultDataSpace()->isTruncated();
|
||||
}
|
||||
|
||||
void RulePtrFlow::getOpList(vector<uint4> &oplist) const
|
||||
|
@ -7486,7 +7486,7 @@ int4 RulePtrFlow::applyOp(PcodeOp *op,Funcdata &data)
|
|||
case CPUI_CALLIND:
|
||||
case CPUI_BRANCHIND:
|
||||
vn = op->getIn(0);
|
||||
spc = data.getArch()->getDefaultSpace();
|
||||
spc = data.getArch()->getDefaultCodeSpace();
|
||||
if (vn->getSize() > spc->getAddrSize()) {
|
||||
vn = truncatePointer(spc,op,vn,0,data);
|
||||
madeChange = 1;
|
||||
|
|
|
@ -325,7 +325,7 @@ public:
|
|||
\code
|
||||
AssemblyEmit *assememit = new AssemblyRaw();
|
||||
|
||||
Address addr(trans->getDefaultSpace(),0x80484c0);
|
||||
Address addr(trans->getDefaultCodeSpace(),0x80484c0);
|
||||
int4 length; // Length of instruction in bytes
|
||||
|
||||
length = trans->printAssembly(*assememit,addr);
|
||||
|
@ -398,7 +398,7 @@ public:
|
|||
\code
|
||||
PcodeEmit *pcodeemit = new PcodeRawOut();
|
||||
|
||||
Address addr(trans->getDefaultSpace(),0x80484c0);
|
||||
Address addr(trans->getDefaultCodeSpace(),0x80484c0);
|
||||
int4 length; // Length of instruction in bytes
|
||||
|
||||
length = trans->oneInstruction(*pcodeemit,addr);
|
||||
|
|
|
@ -157,7 +157,7 @@ void SleighBase::saveXml(ostream &s) const
|
|||
s << ">\n";
|
||||
|
||||
s << "<spaces";
|
||||
a_v(s,"defaultspace",getDefaultSpace()->getName());
|
||||
a_v(s,"defaultspace",getDefaultCodeSpace()->getName());
|
||||
s << ">\n";
|
||||
for(int4 i=0;i<numSpaces();++i) {
|
||||
AddrSpace *spc = getSpace(i);
|
||||
|
|
|
@ -113,8 +113,8 @@ static void dumpAssembly(Translate &trans)
|
|||
AssemblyRaw assememit; // Set up the disassembly dumper
|
||||
int4 length; // Number of bytes of each machine instruction
|
||||
|
||||
Address addr(trans.getDefaultSpace(),0x80483b4); // First disassembly address
|
||||
Address lastaddr(trans.getDefaultSpace(),0x804846c); // Last disassembly address
|
||||
Address addr(trans.getDefaultCodeSpace(),0x80483b4); // First disassembly address
|
||||
Address lastaddr(trans.getDefaultCodeSpace(),0x804846c); // Last disassembly address
|
||||
|
||||
while(addr < lastaddr) {
|
||||
length = trans.printAssembly(assememit,addr);
|
||||
|
@ -164,8 +164,8 @@ static void dumpPcode(Translate &trans)
|
|||
AssemblyRaw assememit; // Set up the disassembly dumper
|
||||
int4 length; // Number of bytes of each machine instruction
|
||||
|
||||
Address addr(trans.getDefaultSpace(),0x80483b4); // First address to translate
|
||||
Address lastaddr(trans.getDefaultSpace(),0x80483bf); // Last address
|
||||
Address addr(trans.getDefaultCodeSpace(),0x80483b4); // First address to translate
|
||||
Address lastaddr(trans.getDefaultCodeSpace(),0x80483bf); // Last address
|
||||
|
||||
while(addr < lastaddr) {
|
||||
cout << "--- ";
|
||||
|
@ -251,8 +251,8 @@ static void doEmulation(Translate &trans,LoadImage &loader)
|
|||
|
||||
{
|
||||
// Set up memory state object
|
||||
MemoryImage loadmemory(trans.getDefaultSpace(),8,4096,&loader);
|
||||
MemoryPageOverlay ramstate(trans.getDefaultSpace(),8,4096,&loadmemory);
|
||||
MemoryImage loadmemory(trans.getDefaultCodeSpace(),8,4096,&loader);
|
||||
MemoryPageOverlay ramstate(trans.getDefaultCodeSpace(),8,4096,&loadmemory);
|
||||
MemoryHashOverlay registerstate(trans.getSpaceByName("register"),8,4096,4096,(MemoryBank *)0);
|
||||
MemoryHashOverlay tmpstate(trans.getUniqueSpace(),8,4096,4096,(MemoryBank *)0);
|
||||
|
||||
|
@ -266,15 +266,15 @@ static void doEmulation(Translate &trans,LoadImage &loader)
|
|||
|
||||
// Set up the initial register state for execution
|
||||
memstate.setValue("ESP",0xbffffffc);
|
||||
emulater.setExecuteAddress(Address(trans.getDefaultSpace(),0x80483b4));
|
||||
emulater.setExecuteAddress(Address(trans.getDefaultCodeSpace(),0x80483b4));
|
||||
|
||||
// Register callbacks
|
||||
PutsCallBack putscallback;
|
||||
PrintfCallBack printfcallback;
|
||||
TerminateCallBack terminatecallback;
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultSpace(),0x80482c8),&putscallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultSpace(),0x80482b8),&printfcallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultSpace(),0x804846b),&terminatecallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultCodeSpace(),0x80482c8),&putscallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultCodeSpace(),0x80482b8),&printfcallback);
|
||||
breaktable.registerAddressCallback(Address(trans.getDefaultCodeSpace(),0x804846b),&terminatecallback);
|
||||
|
||||
emulater.setHalt(false);
|
||||
|
||||
|
|
|
@ -1865,7 +1865,7 @@ void SleighCompile::process(void)
|
|||
|
||||
{ // Do all post processing on the parsed data structures
|
||||
checkNops();
|
||||
if (getDefaultSpace() == (AddrSpace *)0)
|
||||
if (getDefaultCodeSpace() == (AddrSpace *)0)
|
||||
reportError("No default space specified");
|
||||
if (errors>0) return;
|
||||
checkConsistency();
|
||||
|
@ -2037,10 +2037,10 @@ void SleighCompile::newSpace(SpaceQuality *qual)
|
|||
AddrSpace *spc = new AddrSpace(this,this,IPTR_PROCESSOR,qual->name,qual->size,qual->wordsize,numSpaces(),AddrSpace::hasphysical,delay);
|
||||
insertSpace(spc);
|
||||
if (qual->isdefault) {
|
||||
if (getDefaultSpace() != (AddrSpace *)0)
|
||||
reportError(getCurrentLocation(), "Multiple default spaces -- '" + getDefaultSpace()->getName() + "', '" + qual->name + "'");
|
||||
if (getDefaultCodeSpace() != (AddrSpace *)0)
|
||||
reportError(getCurrentLocation(), "Multiple default spaces -- '" + getDefaultCodeSpace()->getName() + "', '" + qual->name + "'");
|
||||
else {
|
||||
setDefaultSpace(spc->getIndex()); // Make the flagged space the default
|
||||
setDefaultCodeSpace(spc->getIndex()); // Make the flagged space the default
|
||||
pcode.setDefaultSpace(spc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,8 +449,8 @@ expr: varnode { $$ = new ExprTree($1); }
|
|||
;
|
||||
sizedstar: '*' '[' SPACESYM ']' ':' INTEGER { $$ = new StarQuality; $$->size = *$6; delete $6; $$->id=ConstTpl($3->getSpace()); }
|
||||
| '*' '[' SPACESYM ']' { $$ = new StarQuality; $$->size = 0; $$->id=ConstTpl($3->getSpace()); }
|
||||
| '*' ':' INTEGER { $$ = new StarQuality; $$->size = *$3; delete $3; $$->id=ConstTpl(slgh->getDefaultSpace()); }
|
||||
| '*' { $$ = new StarQuality; $$->size = 0; $$->id=ConstTpl(slgh->getDefaultSpace()); }
|
||||
| '*' ':' INTEGER { $$ = new StarQuality; $$->size = *$3; delete $3; $$->id=ConstTpl(slgh->getDefaultCodeSpace()); }
|
||||
| '*' { $$ = new StarQuality; $$->size = 0; $$->id=ConstTpl(slgh->getDefaultCodeSpace()); }
|
||||
;
|
||||
jumpdest: STARTSYM { VarnodeTpl *sym = $1->getVarnode(); $$ = new VarnodeTpl(ConstTpl(ConstTpl::j_curspace),sym->getOffset(),ConstTpl(ConstTpl::j_curspace_size)); delete sym; }
|
||||
| ENDSYM { VarnodeTpl *sym = $1->getVarnode(); $$ = new VarnodeTpl(ConstTpl(ConstTpl::j_curspace),sym->getOffset(),ConstTpl(ConstTpl::j_curspace_size)); delete sym; }
|
||||
|
|
|
@ -143,7 +143,8 @@ bool JoinRecord::operator<(const JoinRecord &op2) const
|
|||
AddrSpaceManager::AddrSpaceManager(void)
|
||||
|
||||
{
|
||||
defaultspace = (AddrSpace *)0;
|
||||
defaultcodespace = (AddrSpace *)0;
|
||||
defaultdataspace = (AddrSpace *)0;
|
||||
constantspace = (AddrSpace *)0;
|
||||
iopspace = (AddrSpace *)0;
|
||||
fspecspace = (AddrSpace *)0;
|
||||
|
@ -207,23 +208,36 @@ void AddrSpaceManager::restoreXmlSpaces(const Element *el,const Translate *trans
|
|||
AddrSpace *spc = getSpaceByName(defname);
|
||||
if (spc == (AddrSpace *)0)
|
||||
throw LowlevelError("Bad 'defaultspace' attribute: "+defname);
|
||||
setDefaultSpace(spc->getIndex());
|
||||
setDefaultCodeSpace(spc->getIndex());
|
||||
}
|
||||
|
||||
/// Once all the address spaces have been initialized, this routine
|
||||
/// should be called once to establish the official \e default
|
||||
/// space for the processor, via its index. Should only be
|
||||
/// called during initialization.
|
||||
/// \todo This really shouldn't be public
|
||||
/// \param index is the index of the desired default space
|
||||
void AddrSpaceManager::setDefaultSpace(int4 index)
|
||||
void AddrSpaceManager::setDefaultCodeSpace(int4 index)
|
||||
|
||||
{
|
||||
if (defaultspace != (AddrSpace *)0)
|
||||
if (defaultcodespace != (AddrSpace *)0)
|
||||
throw LowlevelError("Default space set multiple times");
|
||||
if (baselist.size()<=index || baselist[index] == (AddrSpace *)0)
|
||||
throw LowlevelError("Bad index for default space");
|
||||
defaultspace = baselist[index];
|
||||
defaultcodespace = baselist[index];
|
||||
defaultdataspace = defaultcodespace; // By default the default data space is the same
|
||||
}
|
||||
|
||||
/// If the architecture has different code and data spaces, this routine can be called
|
||||
/// to set the \e data space after the \e code space has been set.
|
||||
/// \param index is the index of the desired default space
|
||||
void AddrSpaceManager::setDefaultDataSpace(int4 index)
|
||||
|
||||
{
|
||||
if (defaultcodespace == (AddrSpace *)0)
|
||||
throw LowlevelError("Default data space must be set after the code space");
|
||||
if (baselist.size()<=index || baselist[index] == (AddrSpace *)0)
|
||||
throw LowlevelError("Bad index for default data space");
|
||||
defaultdataspace = baselist[index];
|
||||
}
|
||||
|
||||
/// For spaces with alignment restrictions, the address of a small variable must be justified
|
||||
|
@ -343,7 +357,8 @@ void AddrSpaceManager::copySpaces(const AddrSpaceManager *op2)
|
|||
if (spc != (AddrSpace *)0)
|
||||
insertSpace(spc);
|
||||
}
|
||||
setDefaultSpace(op2->getDefaultSpace()->getIndex());
|
||||
setDefaultCodeSpace(op2->getDefaultCodeSpace()->getIndex());
|
||||
setDefaultDataSpace(op2->getDefaultDataSpace()->getIndex());
|
||||
}
|
||||
|
||||
/// Perform the \e privileged act of associating a base register with an existing \e virtual space
|
||||
|
@ -684,8 +699,8 @@ Address AddrSpaceManager::constructJoinAddress(const Translate *translate,
|
|||
((lotp != IPTR_SPACEBASE)&&(lotp != IPTR_PROCESSOR)))
|
||||
throw LowlevelError("Trying to join in appropriate locations");
|
||||
if ((hitp == IPTR_SPACEBASE)||(lotp == IPTR_SPACEBASE)||
|
||||
(hiaddr.getSpace() == getDefaultSpace())||
|
||||
(loaddr.getSpace() == getDefaultSpace()))
|
||||
(hiaddr.getSpace() == getDefaultCodeSpace())||
|
||||
(loaddr.getSpace() == getDefaultCodeSpace()))
|
||||
usejoinspace = false;
|
||||
if (hiaddr.isContiguous(hisz,loaddr,losz)) { // If we are contiguous
|
||||
if (!usejoinspace) { // and in a mappable space, just return the earliest address
|
||||
|
|
|
@ -220,7 +220,8 @@ class AddrSpaceManager {
|
|||
map<string,AddrSpace *> name2Space; ///< Map from name -> space
|
||||
map<int4,AddrSpace *> shortcut2Space; ///< Map from shortcut -> space
|
||||
AddrSpace *constantspace; ///< Quick reference to constant space
|
||||
AddrSpace *defaultspace; ///< Generally primary RAM, where assembly pointers point to
|
||||
AddrSpace *defaultcodespace; ///< Default space where code lives, generally main RAM
|
||||
AddrSpace *defaultdataspace; ///< Default space where data lives
|
||||
AddrSpace *iopspace; ///< Space for internal pcode op pointers
|
||||
AddrSpace *fspecspace; ///< Space for internal callspec pointers
|
||||
AddrSpace *joinspace; ///< Space for unifying split variables
|
||||
|
@ -232,7 +233,8 @@ class AddrSpaceManager {
|
|||
protected:
|
||||
AddrSpace *restoreXmlSpace(const Element *el,const Translate *trans); ///< Add a space to the model based an on XML tag
|
||||
void restoreXmlSpaces(const Element *el,const Translate *trans); ///< Restore address spaces in the model from an XML tag
|
||||
void setDefaultSpace(int4 index); ///< Set the default address space
|
||||
void setDefaultCodeSpace(int4 index); ///< Set the default address space (for code)
|
||||
void setDefaultDataSpace(int4 index); ///< Set the default address space for data
|
||||
void setReverseJustified(AddrSpace *spc); ///< Set reverse justified property on this space
|
||||
void assignShortcut(AddrSpace *spc); ///< Select a shortcut character for a new space
|
||||
void markNearPointers(AddrSpace *spc,int4 size); ///< Mark that given space can be accessed with near pointers
|
||||
|
@ -251,7 +253,8 @@ public:
|
|||
AddrSpace *getJoinSpace(void) const; ///< Get the joining space
|
||||
AddrSpace *getStackSpace(void) const; ///< Get the stack space for this processor
|
||||
AddrSpace *getUniqueSpace(void) const; ///< Get the temporary register space for this processor
|
||||
AddrSpace *getDefaultSpace(void) const; ///< Get the default address space of this processor
|
||||
AddrSpace *getDefaultCodeSpace(void) const; ///< Get the default address space of this processor
|
||||
AddrSpace *getDefaultDataSpace(void) const; ///< Get the default address space where data is stored
|
||||
AddrSpace *getConstantSpace(void) const; ///< Get the constant space
|
||||
Address getConstant(uintb val) const; ///< Get a constant encoded as an Address
|
||||
Address createConstFromSpace(AddrSpace *spc) const; ///< Create a constant address encoding an address space
|
||||
|
@ -423,7 +426,7 @@ public:
|
|||
/// default space. This space is usually the main RAM databus.
|
||||
/// \return the size of an address in bytes
|
||||
inline int4 AddrSpaceManager::getDefaultSize(void) const {
|
||||
return defaultspace->getAddrSize();
|
||||
return defaultcodespace->getAddrSize();
|
||||
}
|
||||
|
||||
/// There is a special address space reserved for encoding pointers
|
||||
|
@ -475,12 +478,21 @@ inline AddrSpace *AddrSpaceManager::getUniqueSpace(void) const {
|
|||
}
|
||||
|
||||
/// Most processors have a main address bus, on which the bulk
|
||||
/// of the processor's RAM is mapped. Everything referenced
|
||||
/// with this address bus should be modeled in pcode with a
|
||||
/// single address space, referred to as the \e default space.
|
||||
/// \return a pointer to the \e default space
|
||||
inline AddrSpace *AddrSpaceManager::getDefaultSpace(void) const {
|
||||
return defaultspace;
|
||||
/// of the processor's RAM is mapped. This matches SLEIGH's notion
|
||||
/// of the \e default space. For Harvard architectures, this is the
|
||||
/// space where code exists (as opposed to data).
|
||||
/// \return a pointer to the \e default code space
|
||||
inline AddrSpace *AddrSpaceManager::getDefaultCodeSpace(void) const {
|
||||
return defaultcodespace;
|
||||
}
|
||||
|
||||
/// Return the default address space for holding data. For most processors, this
|
||||
/// is just the main RAM space and is the same as the default \e code space.
|
||||
/// For Harvard architectures, this is the space where data is stored
|
||||
/// (as opposed to code).
|
||||
/// \return a pointer to the \e default data space
|
||||
inline AddrSpace *AddrSpaceManager::getDefaultDataSpace(void) const {
|
||||
return defaultdataspace;
|
||||
}
|
||||
|
||||
/// Pcode represents constant values within an operation as
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue