mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-3174 Indexed attribute marshaling
This commit is contained in:
parent
a3ca5a67e1
commit
b39c60e221
16 changed files with 162 additions and 66 deletions
|
@ -1061,6 +1061,8 @@ SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op
|
||||||
if (slot==0)
|
if (slot==0)
|
||||||
return (SymbolEntry *)0;
|
return (SymbolEntry *)0;
|
||||||
break;
|
break;
|
||||||
|
case CPUI_PIECE:
|
||||||
|
// Pointers get concatenated in structures
|
||||||
case CPUI_COPY:
|
case CPUI_COPY:
|
||||||
case CPUI_INT_EQUAL:
|
case CPUI_INT_EQUAL:
|
||||||
case CPUI_INT_NOTEQUAL:
|
case CPUI_INT_NOTEQUAL:
|
||||||
|
|
|
@ -1918,6 +1918,12 @@ void Heritage::splitJoinRead(Varnode *vn,JoinRecord *joinrec)
|
||||||
|
|
||||||
{
|
{
|
||||||
PcodeOp *op = vn->loneDescend(); // vn isFree, so loneDescend must be non-null
|
PcodeOp *op = vn->loneDescend(); // vn isFree, so loneDescend must be non-null
|
||||||
|
bool preventConstCollapse = false;
|
||||||
|
if (vn->isTypeLock()) {
|
||||||
|
type_metatype meta = vn->getType()->getMetatype();
|
||||||
|
if (meta == TYPE_STRUCT || meta == TYPE_ARRAY)
|
||||||
|
preventConstCollapse = true;
|
||||||
|
}
|
||||||
|
|
||||||
vector<Varnode *> lastcombo;
|
vector<Varnode *> lastcombo;
|
||||||
vector<Varnode *> nextlev;
|
vector<Varnode *> nextlev;
|
||||||
|
@ -1937,6 +1943,8 @@ void Heritage::splitJoinRead(Varnode *vn,JoinRecord *joinrec)
|
||||||
fd->opSetInput(concat,mosthalf,0);
|
fd->opSetInput(concat,mosthalf,0);
|
||||||
fd->opSetInput(concat,leasthalf,1);
|
fd->opSetInput(concat,leasthalf,1);
|
||||||
fd->opInsertBefore(concat,op);
|
fd->opInsertBefore(concat,op);
|
||||||
|
if (preventConstCollapse)
|
||||||
|
fd->opMarkNoCollapse(concat);
|
||||||
mosthalf->setPrecisHi(); // Set precision flags to trigger "double precision" rules
|
mosthalf->setPrecisHi(); // Set precision flags to trigger "double precision" rules
|
||||||
leasthalf->setPrecisLo();
|
leasthalf->setPrecisLo();
|
||||||
op = concat; // Keep -op- as the earliest op in the concatenation construction
|
op = concat; // Keep -op- as the earliest op in the concatenation construction
|
||||||
|
|
|
@ -231,6 +231,25 @@ uint4 XmlDecode::getNextAttributeId(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint4 XmlDecode::getIndexedAttributeId(const AttributeId &attribId)
|
||||||
|
|
||||||
|
{
|
||||||
|
const Element *el = elStack.back();
|
||||||
|
if (attributeIndex < 0 || attributeIndex >= el->getNumAttributes())
|
||||||
|
return ATTRIB_UNKNOWN.getId();
|
||||||
|
// For XML, the index is encoded directly in the attribute name
|
||||||
|
const string &attribName(el->getAttributeName(attributeIndex));
|
||||||
|
// Does the name start with desired attribute base name?
|
||||||
|
if (0 != attribName.compare(0,attribId.getName().size(),attribId.getName()))
|
||||||
|
return ATTRIB_UNKNOWN.getId();
|
||||||
|
uint4 val = 0;
|
||||||
|
istringstream s(attribName.substr(attribId.getName().size())); // Strip off the base name
|
||||||
|
s >> dec >> val; // Decode the remaining decimal integer (starting at 1)
|
||||||
|
if (val == 0)
|
||||||
|
throw LowlevelError("Bad indexed attribute: " + attribId.getName());
|
||||||
|
return attribId.getId() + (val-1);
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Find the attribute index, within the given element, for the given name
|
/// \brief Find the attribute index, within the given element, for the given name
|
||||||
///
|
///
|
||||||
/// Run through the attributes of the element until we find the one matching the name,
|
/// Run through the attributes of the element until we find the one matching the name,
|
||||||
|
@ -479,6 +498,16 @@ void XmlEncode::writeString(const AttributeId &attribId,const string &val)
|
||||||
a_v(outStream,attribId.getName(),val);
|
a_v(outStream,attribId.getName(),val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XmlEncode::writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val)
|
||||||
|
|
||||||
|
{
|
||||||
|
outStream << ' ' << attribId.getName() << dec << index + 1;
|
||||||
|
outStream << "=\"";
|
||||||
|
xml_escape(outStream,val.c_str());
|
||||||
|
outStream << "\"";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void XmlEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
|
void XmlEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -711,6 +740,12 @@ uint4 PackedDecode::getNextAttributeId(void)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint4 PackedDecode::getIndexedAttributeId(const AttributeId &attribId)
|
||||||
|
|
||||||
|
{
|
||||||
|
return ATTRIB_UNKNOWN.getId(); // PackedDecode never needs to reinterpret an attribute
|
||||||
|
}
|
||||||
|
|
||||||
bool PackedDecode::readBool(void)
|
bool PackedDecode::readBool(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1046,6 +1081,15 @@ void PackedEncode::writeString(const AttributeId &attribId,const string &val)
|
||||||
outStream.write(val.c_str(), length);
|
outStream.write(val.c_str(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackedEncode::writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val)
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 length = val.length();
|
||||||
|
writeHeader(ATTRIBUTE, attribId.getId() + index);
|
||||||
|
writeInteger((TYPECODE_STRING << TYPECODE_SHIFT), length);
|
||||||
|
outStream.write(val.c_str(), length);
|
||||||
|
}
|
||||||
|
|
||||||
void PackedEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
|
void PackedEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,15 @@ public:
|
||||||
/// \return the id of the next attribute or 0
|
/// \return the id of the next attribute or 0
|
||||||
virtual uint4 getNextAttributeId(void)=0;
|
virtual uint4 getNextAttributeId(void)=0;
|
||||||
|
|
||||||
|
/// \brief Get the id for the (current) attribute, assuming it is indexed
|
||||||
|
///
|
||||||
|
/// Assuming the previous call to getNextAttributeId() returned the id of ATTRIB_UNKNOWN,
|
||||||
|
/// reinterpret the attribute as being an indexed form of the given attribute. If the attribute
|
||||||
|
/// matches, return this indexed id, otherwise return ATTRIB_UNKNOWN.
|
||||||
|
/// \param attribId is the attribute being indexed
|
||||||
|
/// \return the indexed id or ATTRIB_UNKNOWN
|
||||||
|
virtual uint4 getIndexedAttributeId(const AttributeId &attribId)=0;
|
||||||
|
|
||||||
/// \brief Reset attribute traversal for the current element
|
/// \brief Reset attribute traversal for the current element
|
||||||
///
|
///
|
||||||
/// Attributes for a single element can be traversed more than once using the getNextAttributeId method.
|
/// Attributes for a single element can be traversed more than once using the getNextAttributeId method.
|
||||||
|
@ -322,6 +331,17 @@ public:
|
||||||
/// \param val is the string to encode
|
/// \param val is the string to encode
|
||||||
virtual void writeString(const AttributeId &attribId,const string &val)=0;
|
virtual void writeString(const AttributeId &attribId,const string &val)=0;
|
||||||
|
|
||||||
|
/// \brief Write an annotated string, using an indexed attribute, into the encoding
|
||||||
|
///
|
||||||
|
/// Multiple attributes with a shared name can be written to the same element by calling this method
|
||||||
|
/// multiple times with a different \b index value. The encoding will use attribute ids up to the base id
|
||||||
|
/// plus the maximum index passed in. Implementors must be careful to not use other attributes with ids
|
||||||
|
/// bigger than the base id within the element taking the indexed attribute.
|
||||||
|
/// \param attribId is the shared AttributeId
|
||||||
|
/// \param index is the unique index to associated with the string
|
||||||
|
/// \param val is the string to encode
|
||||||
|
virtual void writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val)=0;
|
||||||
|
|
||||||
/// \brief Write an address space reference into the encoding
|
/// \brief Write an address space reference into the encoding
|
||||||
///
|
///
|
||||||
/// The address space is associated with the given AttributeId annotation and the current open element.
|
/// The address space is associated with the given AttributeId annotation and the current open element.
|
||||||
|
@ -357,6 +377,7 @@ public:
|
||||||
virtual void closeElementSkipping(uint4 id);
|
virtual void closeElementSkipping(uint4 id);
|
||||||
virtual void rewindAttributes(void);
|
virtual void rewindAttributes(void);
|
||||||
virtual uint4 getNextAttributeId(void);
|
virtual uint4 getNextAttributeId(void);
|
||||||
|
virtual uint4 getIndexedAttributeId(const AttributeId &attribId);
|
||||||
virtual bool readBool(void);
|
virtual bool readBool(void);
|
||||||
virtual bool readBool(const AttributeId &attribId);
|
virtual bool readBool(const AttributeId &attribId);
|
||||||
virtual intb readSignedInteger(void);
|
virtual intb readSignedInteger(void);
|
||||||
|
@ -387,6 +408,7 @@ public:
|
||||||
virtual void writeSignedInteger(const AttributeId &attribId,intb val);
|
virtual void writeSignedInteger(const AttributeId &attribId,intb val);
|
||||||
virtual void writeUnsignedInteger(const AttributeId &attribId,uintb val);
|
virtual void writeUnsignedInteger(const AttributeId &attribId,uintb val);
|
||||||
virtual void writeString(const AttributeId &attribId,const string &val);
|
virtual void writeString(const AttributeId &attribId,const string &val);
|
||||||
|
virtual void writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val);
|
||||||
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
|
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -492,6 +514,7 @@ public:
|
||||||
virtual void closeElementSkipping(uint4 id);
|
virtual void closeElementSkipping(uint4 id);
|
||||||
virtual void rewindAttributes(void);
|
virtual void rewindAttributes(void);
|
||||||
virtual uint4 getNextAttributeId(void);
|
virtual uint4 getNextAttributeId(void);
|
||||||
|
virtual uint4 getIndexedAttributeId(const AttributeId &attribId);
|
||||||
virtual bool readBool(void);
|
virtual bool readBool(void);
|
||||||
virtual bool readBool(const AttributeId &attribId);
|
virtual bool readBool(const AttributeId &attribId);
|
||||||
virtual intb readSignedInteger(void);
|
virtual intb readSignedInteger(void);
|
||||||
|
@ -521,6 +544,7 @@ public:
|
||||||
virtual void writeSignedInteger(const AttributeId &attribId,intb val);
|
virtual void writeSignedInteger(const AttributeId &attribId,intb val);
|
||||||
virtual void writeUnsignedInteger(const AttributeId &attribId,uintb val);
|
virtual void writeUnsignedInteger(const AttributeId &attribId,uintb val);
|
||||||
virtual void writeString(const AttributeId &attribId,const string &val);
|
virtual void writeString(const AttributeId &attribId,const string &val);
|
||||||
|
virtual void writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val);
|
||||||
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
|
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,6 @@ int4 PcodeOp::getRepeatSlot(const Varnode *vn,int4 firstSlot,list<PcodeOp *>::co
|
||||||
bool PcodeOp::isCollapsible(void) const
|
bool PcodeOp::isCollapsible(void) const
|
||||||
|
|
||||||
{
|
{
|
||||||
if (code() == CPUI_COPY) return false;
|
|
||||||
if ((flags & PcodeOp::nocollapse)!=0) return false;
|
if ((flags & PcodeOp::nocollapse)!=0) return false;
|
||||||
if (!isAssignment()) return false;
|
if (!isAssignment()) return false;
|
||||||
if (inrefs.size()==0) return false;
|
if (inrefs.size()==0) return false;
|
||||||
|
|
|
@ -21,15 +21,11 @@ AttributeId ATTRIB_DEADCODEDELAY = AttributeId("deadcodedelay",90);
|
||||||
AttributeId ATTRIB_DELAY = AttributeId("delay", 91);
|
AttributeId ATTRIB_DELAY = AttributeId("delay", 91);
|
||||||
AttributeId ATTRIB_LOGICALSIZE = AttributeId("logicalsize",92);
|
AttributeId ATTRIB_LOGICALSIZE = AttributeId("logicalsize",92);
|
||||||
AttributeId ATTRIB_PHYSICAL = AttributeId("physical",93);
|
AttributeId ATTRIB_PHYSICAL = AttributeId("physical",93);
|
||||||
AttributeId ATTRIB_PIECE1 = AttributeId("piece1",94); // piece attributes must have sequential ids
|
|
||||||
AttributeId ATTRIB_PIECE2 = AttributeId("piece2",95);
|
// ATTRIB_PIECE is a special attribute for supporting the legacy attributes "piece1", "piece2", ..., "piece9",
|
||||||
AttributeId ATTRIB_PIECE3 = AttributeId("piece3",96);
|
// It is effectively a sequence of indexed attributes for use with Encoder::writeStringIndexed.
|
||||||
AttributeId ATTRIB_PIECE4 = AttributeId("piece4",97);
|
// The index starts at the ids reserved for "piece1" thru "piece9" but can extend farther.
|
||||||
AttributeId ATTRIB_PIECE5 = AttributeId("piece5",98);
|
AttributeId ATTRIB_PIECE = AttributeId("piece",94); // Open slots 94-102
|
||||||
AttributeId ATTRIB_PIECE6 = AttributeId("piece6",99);
|
|
||||||
AttributeId ATTRIB_PIECE7 = AttributeId("piece7",100);
|
|
||||||
AttributeId ATTRIB_PIECE8 = AttributeId("piece8",101);
|
|
||||||
AttributeId ATTRIB_PIECE9 = AttributeId("piece9",102);
|
|
||||||
|
|
||||||
/// Calculate \e highest based on \e addressSize, and \e wordsize.
|
/// Calculate \e highest based on \e addressSize, and \e wordsize.
|
||||||
/// This also calculates the default pointerLowerBound
|
/// This also calculates the default pointerLowerBound
|
||||||
|
@ -552,20 +548,17 @@ int4 JoinSpace::overlapJoin(uintb offset,int4 size,AddrSpace *pointSpace,uintb p
|
||||||
void JoinSpace::encodeAttributes(Encoder &encoder,uintb offset) const
|
void JoinSpace::encodeAttributes(Encoder &encoder,uintb offset) const
|
||||||
|
|
||||||
{
|
{
|
||||||
static AttributeId *pieceArray[] = { &ATTRIB_PIECE1, &ATTRIB_PIECE2, &ATTRIB_PIECE3, &ATTRIB_PIECE4,
|
|
||||||
&ATTRIB_PIECE5, &ATTRIB_PIECE6, &ATTRIB_PIECE7, &ATTRIB_PIECE8, &ATTRIB_PIECE9 };
|
|
||||||
JoinRecord *rec = getManager()->findJoin(offset); // Record must already exist
|
JoinRecord *rec = getManager()->findJoin(offset); // Record must already exist
|
||||||
encoder.writeSpace(ATTRIB_SPACE, this);
|
encoder.writeSpace(ATTRIB_SPACE, this);
|
||||||
int4 num = rec->numPieces();
|
int4 num = rec->numPieces();
|
||||||
if (num >= 8)
|
if (num > MAX_PIECES)
|
||||||
throw LowlevelError("Cannot encode more than 8 pieces");
|
throw LowlevelError("Exceeded maximum pieces in one join address");
|
||||||
for(int4 i=0;i<num;++i) {
|
for(int4 i=0;i<num;++i) {
|
||||||
const VarnodeData &vdata( rec->getPiece(i) );
|
const VarnodeData &vdata( rec->getPiece(i) );
|
||||||
ostringstream t;
|
ostringstream t;
|
||||||
AttributeId *attribId = pieceArray[i];
|
|
||||||
t << vdata.space->getName() << ":0x";
|
t << vdata.space->getName() << ":0x";
|
||||||
t << hex << vdata.offset << ':' << dec << vdata.size;
|
t << hex << vdata.offset << ':' << dec << vdata.size;
|
||||||
encoder.writeString(*attribId, t.str());
|
encoder.writeStringIndexed(ATTRIB_PIECE, i, t.str());
|
||||||
}
|
}
|
||||||
if (num == 1)
|
if (num == 1)
|
||||||
encoder.writeUnsignedInteger(ATTRIB_LOGICALSIZE, rec->getUnified().size);
|
encoder.writeUnsignedInteger(ATTRIB_LOGICALSIZE, rec->getUnified().size);
|
||||||
|
@ -602,9 +595,13 @@ uintb JoinSpace::decodeAttributes(Decoder &decoder,uint4 &size) const
|
||||||
logicalsize = decoder.readUnsignedInteger();
|
logicalsize = decoder.readUnsignedInteger();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (attribId < ATTRIB_PIECE1.getId() || attribId > ATTRIB_PIECE9.getId())
|
else if (attribId == ATTRIB_UNKNOWN)
|
||||||
|
attribId = decoder.getIndexedAttributeId(ATTRIB_PIECE);
|
||||||
|
if (attribId < ATTRIB_PIECE.getId())
|
||||||
|
continue;
|
||||||
|
int4 pos = (int4)(attribId - ATTRIB_PIECE.getId());
|
||||||
|
if (pos > MAX_PIECES)
|
||||||
continue;
|
continue;
|
||||||
int4 pos = (int4)(attribId - ATTRIB_PIECE1.getId());
|
|
||||||
while(pieces.size() <= pos)
|
while(pieces.size() <= pos)
|
||||||
pieces.emplace_back();
|
pieces.emplace_back();
|
||||||
VarnodeData &vdat( pieces[pos] );
|
VarnodeData &vdat( pieces[pos] );
|
||||||
|
|
|
@ -45,15 +45,7 @@ extern AttributeId ATTRIB_DEADCODEDELAY; ///< Marshaling attribute "deadcodedela
|
||||||
extern AttributeId ATTRIB_DELAY; ///< Marshaling attribute "delay"
|
extern AttributeId ATTRIB_DELAY; ///< Marshaling attribute "delay"
|
||||||
extern AttributeId ATTRIB_LOGICALSIZE; ///< Marshaling attribute "logicalsize"
|
extern AttributeId ATTRIB_LOGICALSIZE; ///< Marshaling attribute "logicalsize"
|
||||||
extern AttributeId ATTRIB_PHYSICAL; ///< Marshaling attribute "physical"
|
extern AttributeId ATTRIB_PHYSICAL; ///< Marshaling attribute "physical"
|
||||||
extern AttributeId ATTRIB_PIECE1; ///< Marshaling attribute "piece1"
|
extern AttributeId ATTRIB_PIECE; ///< Marshaling attribute "piece"
|
||||||
extern AttributeId ATTRIB_PIECE2; ///< Marshaling attribute "piece2"
|
|
||||||
extern AttributeId ATTRIB_PIECE3; ///< Marshaling attribute "piece3"
|
|
||||||
extern AttributeId ATTRIB_PIECE4; ///< Marshaling attribute "piece4"
|
|
||||||
extern AttributeId ATTRIB_PIECE5; ///< Marshaling attribute "piece5"
|
|
||||||
extern AttributeId ATTRIB_PIECE6; ///< Marshaling attribute "piece6"
|
|
||||||
extern AttributeId ATTRIB_PIECE7; ///< Marshaling attribute "piece7"
|
|
||||||
extern AttributeId ATTRIB_PIECE8; ///< Marshaling attribute "piece8"
|
|
||||||
extern AttributeId ATTRIB_PIECE9; ///< Marshaling attribute "piece9"
|
|
||||||
|
|
||||||
/// \brief A region where processor data is stored
|
/// \brief A region where processor data is stored
|
||||||
///
|
///
|
||||||
|
@ -68,8 +60,8 @@ extern AttributeId ATTRIB_PIECE9; ///< Marshaling attribute "piece9"
|
||||||
/// offsets ranging from 0x00000000 to 0xffffffff within the space
|
/// offsets ranging from 0x00000000 to 0xffffffff within the space
|
||||||
/// for a total of 2^32 addressable bytes within the space.
|
/// for a total of 2^32 addressable bytes within the space.
|
||||||
/// There can be multiple address spaces, and it is typical to have spaces
|
/// There can be multiple address spaces, and it is typical to have spaces
|
||||||
/// - \b ram Modelling the main processor address bus
|
/// - \b ram Modeling the main processor address bus
|
||||||
/// - \b register Modelling a processors registers
|
/// - \b register Modeling a processors registers
|
||||||
///
|
///
|
||||||
/// The processor specification can set up any address spaces it
|
/// The processor specification can set up any address spaces it
|
||||||
/// needs in an arbitrary manner, but \e all data manipulated by
|
/// needs in an arbitrary manner, but \e all data manipulated by
|
||||||
|
@ -80,7 +72,7 @@ extern AttributeId ATTRIB_PIECE9; ///< Marshaling attribute "piece9"
|
||||||
/// The analysis engine also uses additional address spaces to
|
/// The analysis engine also uses additional address spaces to
|
||||||
/// model special concepts. These include
|
/// model special concepts. These include
|
||||||
/// - \b const There is a \e constant address space for
|
/// - \b const There is a \e constant address space for
|
||||||
/// modelling constant values in pcode expressions
|
/// modeling constant values in p-code expressions
|
||||||
/// (See ConstantSpace)
|
/// (See ConstantSpace)
|
||||||
/// - \b unique There is always a \e unique address space used
|
/// - \b unique There is always a \e unique address space used
|
||||||
/// as a pool for temporary registers. (See UniqueSpace)
|
/// as a pool for temporary registers. (See UniqueSpace)
|
||||||
|
@ -240,6 +232,7 @@ public:
|
||||||
/// mapping the logical address in this space to its physical pieces. Offsets into this space do not
|
/// mapping the logical address in this space to its physical pieces. Offsets into this space do not
|
||||||
/// have an absolute meaning, the database may vary what offset is assigned to what set of pieces.
|
/// have an absolute meaning, the database may vary what offset is assigned to what set of pieces.
|
||||||
class JoinSpace : public AddrSpace {
|
class JoinSpace : public AddrSpace {
|
||||||
|
static const int4 MAX_PIECES = 64; ///< Maximum number of pieces that can be marshaled in one \e join address
|
||||||
public:
|
public:
|
||||||
JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind);
|
JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind);
|
||||||
virtual int4 overlapJoin(uintb offset,int4 size,AddrSpace *pointSpace,uintb pointOff,int4 pointSkip) const;
|
virtual int4 overlapJoin(uintb offset,int4 size,AddrSpace *pointSpace,uintb pointOff,int4 pointSkip) const;
|
||||||
|
|
|
@ -306,7 +306,7 @@ void TypeOpFunc::printRaw(ostream &s,const PcodeOp *op)
|
||||||
TypeOpCopy::TypeOpCopy(TypeFactory *t) : TypeOp(t,CPUI_COPY,"copy")
|
TypeOpCopy::TypeOpCopy(TypeFactory *t) : TypeOp(t,CPUI_COPY,"copy")
|
||||||
|
|
||||||
{
|
{
|
||||||
opflags = PcodeOp::unary;
|
opflags = PcodeOp::unary | PcodeOp::nocollapse;
|
||||||
behave = new OpBehaviorCopy();
|
behave = new OpBehaviorCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ import ghidra.xml.XmlParseException;
|
||||||
* The static restoreXML methods read an \<addr> tag and produce a general AddressXML object.
|
* The static restoreXML methods read an \<addr> tag and produce a general AddressXML object.
|
||||||
*/
|
*/
|
||||||
public class AddressXML {
|
public class AddressXML {
|
||||||
|
|
||||||
|
public static int MAX_PIECES = 64; // Maximum pieces that can be marshaled in one join address
|
||||||
private AddressSpace space; // Address space containing the memory range
|
private AddressSpace space; // Address space containing the memory range
|
||||||
private long offset; // Starting offset of the range
|
private long offset; // Starting offset of the range
|
||||||
private long size; // Number of bytes in the size
|
private long size; // Number of bytes in the size
|
||||||
|
@ -596,32 +598,13 @@ public class AddressXML {
|
||||||
AddressXML.encode(encoder, varnodes[0].getAddress(), varnodes[0].getSize());
|
AddressXML.encode(encoder, varnodes[0].getAddress(), varnodes[0].getSize());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (varnodes.length > MAX_PIECES) {
|
||||||
|
throw new IOException("Exceeded maximum pieces in one join address");
|
||||||
|
}
|
||||||
encoder.openElement(ELEM_ADDR);
|
encoder.openElement(ELEM_ADDR);
|
||||||
encoder.writeSpace(ATTRIB_SPACE, AddressSpace.VARIABLE_SPACE);
|
encoder.writeSpace(ATTRIB_SPACE, AddressSpace.VARIABLE_SPACE);
|
||||||
encoder.writeString(ATTRIB_PIECE1, varnodes[0].encodePiece());
|
for (int i = 0; i < varnodes.length; ++i) {
|
||||||
if (varnodes.length > 1) {
|
encoder.writeStringIndexed(ATTRIB_PIECE, i, varnodes[i].encodePiece());
|
||||||
encoder.writeString(ATTRIB_PIECE2, varnodes[1].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 2) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE3, varnodes[2].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 3) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE4, varnodes[3].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 4) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE5, varnodes[4].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 5) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE6, varnodes[5].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 6) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE7, varnodes[6].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 7) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE8, varnodes[7].encodePiece());
|
|
||||||
}
|
|
||||||
if (varnodes.length > 8) {
|
|
||||||
encoder.writeString(ATTRIB_PIECE9, varnodes[8].encodePiece());
|
|
||||||
}
|
}
|
||||||
if (logicalsize != 0) {
|
if (logicalsize != 0) {
|
||||||
encoder.writeUnsignedInteger(ATTRIB_LOGICALSIZE, logicalsize);
|
encoder.writeUnsignedInteger(ATTRIB_LOGICALSIZE, logicalsize);
|
||||||
|
|
|
@ -175,15 +175,7 @@ public record AttributeId(String name, int id) {
|
||||||
public static final AttributeId ATTRIB_DELAY = new AttributeId("delay", 91);
|
public static final AttributeId ATTRIB_DELAY = new AttributeId("delay", 91);
|
||||||
public static final AttributeId ATTRIB_LOGICALSIZE = new AttributeId("logicalsize", 92);
|
public static final AttributeId ATTRIB_LOGICALSIZE = new AttributeId("logicalsize", 92);
|
||||||
public static final AttributeId ATTRIB_PHYSICAL = new AttributeId("physical", 93);
|
public static final AttributeId ATTRIB_PHYSICAL = new AttributeId("physical", 93);
|
||||||
public static final AttributeId ATTRIB_PIECE1 = new AttributeId("piece1", 94); // piece attributes must have sequential ids
|
public static final AttributeId ATTRIB_PIECE = new AttributeId("piece", 94);
|
||||||
public static final AttributeId ATTRIB_PIECE2 = new AttributeId("piece2", 95);
|
|
||||||
public static final AttributeId ATTRIB_PIECE3 = new AttributeId("piece3", 96);
|
|
||||||
public static final AttributeId ATTRIB_PIECE4 = new AttributeId("piece4", 97);
|
|
||||||
public static final AttributeId ATTRIB_PIECE5 = new AttributeId("piece5", 98);
|
|
||||||
public static final AttributeId ATTRIB_PIECE6 = new AttributeId("piece6", 99);
|
|
||||||
public static final AttributeId ATTRIB_PIECE7 = new AttributeId("piece7", 100);
|
|
||||||
public static final AttributeId ATTRIB_PIECE8 = new AttributeId("piece8", 101);
|
|
||||||
public static final AttributeId ATTRIB_PIECE9 = new AttributeId("piece9", 102);
|
|
||||||
|
|
||||||
// architecture
|
// architecture
|
||||||
public static final AttributeId ATTRIB_ADJUSTVMA = new AttributeId("adjustvma", 103);
|
public static final AttributeId ATTRIB_ADJUSTVMA = new AttributeId("adjustvma", 103);
|
||||||
|
|
|
@ -92,6 +92,17 @@ public interface Decoder extends ByteIngest {
|
||||||
*/
|
*/
|
||||||
public int getNextAttributeId() throws DecoderException;
|
public int getNextAttributeId() throws DecoderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id for the (current) attribute, assuming it is indexed.
|
||||||
|
* Assuming the previous call to getNextAttributeId() returned the id of ATTRIB_UNKNOWN,
|
||||||
|
* reinterpret the attribute as being an indexed form of the given attribute. If the attribute
|
||||||
|
* matches, return this indexed id, otherwise return ATTRIB_UNKNOWN.
|
||||||
|
* @param attribId is the attribute being indexed
|
||||||
|
* @return the indexed id or ATTRIB_UNKNOWN
|
||||||
|
* @throws DecoderException for unexpected end of stream
|
||||||
|
*/
|
||||||
|
public int getIndexedAttributeId(AttributeId attribId) throws DecoderException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset attribute traversal for the current element
|
* Reset attribute traversal for the current element
|
||||||
* Attributes for a single element can be traversed more than once using the getNextAttributeId
|
* Attributes for a single element can be traversed more than once using the getNextAttributeId
|
||||||
|
|
|
@ -93,6 +93,19 @@ public interface Encoder {
|
||||||
*/
|
*/
|
||||||
void writeString(AttributeId attribId, String val) throws IOException;
|
void writeString(AttributeId attribId, String val) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an annotated string, using an indexed attribute, into the encoding.
|
||||||
|
* Multiple attributes with a shared name can be written to the same element by calling this
|
||||||
|
* method multiple times with a different index value. The encoding will use attribute ids up
|
||||||
|
* to the base id plus the maximum index passed in. Implementors must be careful to not use
|
||||||
|
* other attributes with ids bigger than the base id within the element taking the indexed attribute.
|
||||||
|
* @param attribId is the shared AttributeId
|
||||||
|
* @param index is the unique index to associated with the string
|
||||||
|
* @param val is the string to encode
|
||||||
|
* @throws IOException for errors in the underlying stream
|
||||||
|
*/
|
||||||
|
void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write an address space reference into the encoding
|
* Write an address space reference into the encoding
|
||||||
* The address space is associated with the given AttributeId annotation and the current open element.
|
* The address space is associated with the given AttributeId annotation and the current open element.
|
||||||
|
|
|
@ -310,6 +310,11 @@ public class PackedDecode implements Decoder {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndexedAttributeId(AttributeId attribId) throws DecoderException {
|
||||||
|
return AttributeId.ATTRIB_UNKNOWN.id();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rewindAttributes() {
|
public void rewindAttributes() {
|
||||||
curPos.copy(startPos);
|
curPos.copy(startPos);
|
||||||
|
|
|
@ -165,6 +165,14 @@ public class PackedEncode implements PatchEncoder {
|
||||||
outStream.write(bytes);
|
outStream.write(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException {
|
||||||
|
byte[] bytes = val.getBytes();
|
||||||
|
writeHeader(ATTRIBUTE, attribId.id() + index);
|
||||||
|
writeInteger((TYPECODE_STRING << TYPECODE_SHIFT), bytes.length);
|
||||||
|
outStream.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
||||||
writeHeader(ATTRIBUTE, attribId.id());
|
writeHeader(ATTRIBUTE, attribId.id());
|
||||||
|
|
|
@ -497,8 +497,15 @@ public class Varnode {
|
||||||
if (attribId == 0) {
|
if (attribId == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (attribId >= ATTRIB_PIECE1.id() && attribId <= ATTRIB_PIECE9.id()) {
|
else if (attribId == ATTRIB_UNKNOWN.id()) {
|
||||||
int index = attribId - ATTRIB_PIECE1.id();
|
attribId = decoder.getIndexedAttributeId(ATTRIB_PIECE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribId >= ATTRIB_PIECE.id()) {
|
||||||
|
int index = attribId - ATTRIB_PIECE.id();
|
||||||
|
if (index > AddressXML.MAX_PIECES) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (index != list.size()) {
|
if (index != list.size()) {
|
||||||
throw new DecoderException("\"piece\" attributes must be in order");
|
throw new DecoderException("\"piece\" attributes must be in order");
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,16 @@ public class XmlEncode implements Encoder {
|
||||||
buffer.append("\"");
|
buffer.append("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException {
|
||||||
|
buffer.append(' ');
|
||||||
|
buffer.append(attribId.name());
|
||||||
|
buffer.append(index + 1);
|
||||||
|
buffer.append("=\"");
|
||||||
|
SpecXmlUtils.xmlEscape(buffer, val);
|
||||||
|
buffer.append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
||||||
String spcName;
|
String spcName;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue