#ifndef __CPUI_SPACE__
#define __CPUI_SPACE__
#include "error.hh"
#include "xml.hh"
enum spacetype {
IPTR_CONSTANT = 0, IPTR_PROCESSOR = 1, IPTR_SPACEBASE = 2, IPTR_INTERNAL = 3, IPTR_FSPEC = 4, IPTR_IOP = 5, IPTR_JOIN = 6 };
class AddrSpace;
class AddrSpaceManager;
struct VarnodeData;
class Translate;
class AddrSpace {
friend class AddrSpaceManager; public:
enum {
big_endian = 1, heritaged = 2, does_deadcode = 4, programspecific = 8, reverse_justification = 16, overlay = 32, overlaybase = 64, truncated = 128, hasphysical = 256, is_otherspace = 512, has_nearpointers = 0x400 };
private:
spacetype type; AddrSpaceManager *manage; const Translate *trans; int4 refcount; uint4 flags; uintb highest; uintb pointerLowerBound; uintb pointerUpperBound; char shortcut; protected:
string name; uint4 addressSize; uint4 wordsize; int4 minimumPointerSize; int4 index; int4 delay; int4 deadcodedelay; void calcScaleMask(void); void setFlags(uint4 fl); void clearFlags(uint4 fl); void saveBasicAttributes(ostream &s) const; void truncateSpace(uint4 newsize);
public:
AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const string &nm,uint4 size,uint4 ws,int4 ind,uint4 fl,int4 dl);
AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp); virtual ~AddrSpace(void) {} const string &getName(void) const; AddrSpaceManager *getManager(void) const; const Translate *getTrans(void) const; spacetype getType(void) const; int4 getDelay(void) const; int4 getDeadcodeDelay(void) const; int4 getIndex(void) const; uint4 getWordSize(void) const; uint4 getAddrSize(void) const; uintb getHighest(void) const; uintb getPointerLowerBound(void) const; uintb getPointerUpperBound(void) const; int4 getMinimumPtrSize(void) const; uintb wrapOffset(uintb off) const; char getShortcut(void) const; bool isHeritaged(void) const; bool doesDeadcode(void) const; bool hasPhysical(void) const; bool isBigEndian(void) const; bool isReverseJustified(void) const; bool isOverlay(void) const; bool isOverlayBase(void) const; bool isOtherSpace(void) const; bool isTruncated(void) const; bool hasNearPointers(void) const; void printOffset(ostream &s,uintb offset) const;
virtual int4 numSpacebase(void) const; virtual const VarnodeData &getSpacebase(int4 i) const; virtual const VarnodeData &getSpacebaseFull(int4 i) const; virtual bool stackGrowsNegative(void) const; virtual AddrSpace *getContain(void) const; 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; virtual void printRaw(ostream &s,uintb offset) const; virtual uintb read(const string &s,int4 &size) const; virtual void saveXml(ostream &s) const; virtual void restoreXml(const Element *el);
static uintb addressToByte(uintb val,uint4 ws); static uintb byteToAddress(uintb val,uint4 ws); static int4 addressToByteInt(int4 val,uint4 ws); static int4 byteToAddressInt(int4 val,uint4 ws); static bool compareByIndex(const AddrSpace *a,const AddrSpace *b); };
class ConstantSpace : public AddrSpace {
public:
ConstantSpace(AddrSpaceManager *m,const Translate *t); virtual void printRaw(ostream &s,uintb offset) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
static const string NAME; static const int4 INDEX; };
class OtherSpace : public AddrSpace {
public:
OtherSpace(AddrSpaceManager *m, const Translate *t, int4 ind); OtherSpace(AddrSpaceManager *m, const Translate *t); virtual void printRaw(ostream &s, uintb offset) const;
virtual void saveXml(ostream &s) const;
static const string NAME; static const int4 INDEX; };
class UniqueSpace : public AddrSpace {
public:
UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl); UniqueSpace(AddrSpaceManager *m,const Translate *t); virtual void saveXml(ostream &s) const;
static const string NAME; static const uint4 SIZE; };
class JoinSpace : public AddrSpace {
public:
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;
virtual void printRaw(ostream &s,uintb offset) const;
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; };
class OverlaySpace : public AddrSpace {
AddrSpace *baseSpace; public:
OverlaySpace(AddrSpaceManager *m,const Translate *t); AddrSpace *getBaseSpace(void) const; virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
};
inline void AddrSpace::setFlags(uint4 fl) {
flags |= fl;
}
inline void AddrSpace::clearFlags(uint4 fl) {
flags &= ~fl;
}
inline const string &AddrSpace::getName(void) const {
return name;
}
inline AddrSpaceManager *AddrSpace::getManager(void) const {
return manage;
}
inline const Translate *AddrSpace::getTrans(void) const {
return trans;
}
inline spacetype AddrSpace::getType(void) const {
return type;
}
inline int4 AddrSpace::getDelay(void) const {
return delay;
}
inline int4 AddrSpace::getDeadcodeDelay(void) const {
return deadcodedelay;
}
inline int4 AddrSpace::getIndex(void) const {
return index;
}
inline uint4 AddrSpace::getWordSize(void) const {
return wordsize;
}
inline uint4 AddrSpace::getAddrSize(void) const {
return addressSize;
}
inline uintb AddrSpace::getHighest(void) const {
return highest;
}
inline uintb AddrSpace::getPointerLowerBound(void) const {
return pointerLowerBound;
}
inline uintb AddrSpace::getPointerUpperBound(void) const {
return pointerUpperBound;
}
inline int4 AddrSpace::getMinimumPtrSize(void) const {
return minimumPointerSize;
}
inline uintb AddrSpace::wrapOffset(uintb off) const {
if (off <= highest) return off;
intb mod = (intb)(highest+1);
intb res = (intb)off % mod; if (res<0) res += mod; return (uintb)res;
}
inline char AddrSpace::getShortcut(void) const {
return shortcut;
}
inline bool AddrSpace::isHeritaged(void) const {
return ((flags & heritaged)!=0);
}
inline bool AddrSpace::doesDeadcode(void) const {
return ((flags & does_deadcode)!=0);
}
inline bool AddrSpace::hasPhysical(void) const {
return ((flags & hasphysical) !=0);
}
inline bool AddrSpace::isBigEndian(void) const {
return ((flags&big_endian)!=0);
}
inline bool AddrSpace::isReverseJustified(void) const {
return ((flags&reverse_justification)!=0);
}
inline bool AddrSpace::isOverlay(void) const {
return ((flags&overlay)!=0);
}
inline bool AddrSpace::isOverlayBase(void) const {
return ((flags&overlaybase)!=0);
}
inline bool AddrSpace::isOtherSpace(void) const {
return ((flags&is_otherspace)!=0);
}
inline bool AddrSpace::isTruncated(void) const {
return ((flags&truncated)!=0);
}
inline bool AddrSpace::hasNearPointers(void) const {
return ((flags&has_nearpointers)!=0);
}
inline int4 AddrSpace::numSpacebase(void) const {
return 0;
}
inline const VarnodeData &AddrSpace::getSpacebase(int4 i) const {
throw LowlevelError(name+" space is not virtual and has no associated base register");
}
inline const VarnodeData &AddrSpace::getSpacebaseFull(int4 i) const {
throw LowlevelError(name+" has no truncated registers");
}
inline bool AddrSpace::stackGrowsNegative(void) const {
return true;
}
inline AddrSpace *AddrSpace::getContain(void) const {
return (AddrSpace *)0;
}
inline uintb AddrSpace::addressToByte(uintb val,uint4 ws) {
return val*ws;
}
inline uintb AddrSpace::byteToAddress(uintb val,uint4 ws) {
return val/ws;
}
inline int4 AddrSpace::addressToByteInt(int4 val,uint4 ws) {
return val*ws;
}
inline int4 AddrSpace::byteToAddressInt(int4 val,uint4 ws) {
return val/ws;
}
inline bool AddrSpace::compareByIndex(const AddrSpace *a,const AddrSpace *b) {
return (a->index < b->index);
}
#endif