mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-3065 Special parsing for mixed format attribute
This commit is contained in:
parent
03d61101e2
commit
94aca176ef
9 changed files with 250 additions and 28 deletions
|
@ -2317,14 +2317,7 @@ void ProtoModel::decode(Decoder &decoder)
|
|||
if (attribId == ATTRIB_NAME)
|
||||
name = decoder.readString();
|
||||
else if (attribId == ATTRIB_EXTRAPOP) {
|
||||
string extrapopString = decoder.readString();
|
||||
if (extrapopString == "unknown")
|
||||
extrapop = extrapop_unknown;
|
||||
else {
|
||||
istringstream s(extrapopString);
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> extrapop;
|
||||
}
|
||||
extrapop = decoder.readSignedIntegerExpectString("unknown", extrapop_unknown);
|
||||
}
|
||||
else if (attribId == ATTRIB_STACKSHIFT) {
|
||||
// Allow this attribute for backward compatibility
|
||||
|
@ -4409,11 +4402,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb)
|
|||
}
|
||||
else if (attribId == ATTRIB_EXTRAPOP) {
|
||||
seenextrapop = true;
|
||||
try {
|
||||
readextrapop = decoder.readSignedInteger();
|
||||
} catch(DecoderError &err) {
|
||||
readextrapop = ProtoModel::extrapop_unknown;
|
||||
}
|
||||
readextrapop = decoder.readSignedIntegerExpectString("unknown", ProtoModel::extrapop_unknown);
|
||||
}
|
||||
else if (attribId == ATTRIB_MODELLOCK) {
|
||||
if (decoder.readBool())
|
||||
|
|
|
@ -295,6 +295,33 @@ intb XmlDecode::readSignedInteger(const AttributeId &attribId)
|
|||
return res;
|
||||
}
|
||||
|
||||
intb XmlDecode::readSignedIntegerExpectString(const string &expect,intb expectval)
|
||||
|
||||
{
|
||||
const Element *el = elStack.back();
|
||||
const string &value( el->getAttributeValue(attributeIndex) );
|
||||
if (value == expect)
|
||||
return expectval;
|
||||
istringstream s2(value);
|
||||
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
intb res = 0;
|
||||
s2 >> res;
|
||||
return res;
|
||||
}
|
||||
|
||||
intb XmlDecode::readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)
|
||||
|
||||
{
|
||||
string value = readString(attribId);
|
||||
if (value == expect)
|
||||
return expectval;
|
||||
istringstream s2(value);
|
||||
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
intb res = 0;
|
||||
s2 >> res;
|
||||
return res;
|
||||
}
|
||||
|
||||
uintb XmlDecode::readUnsignedInteger(void)
|
||||
|
||||
{
|
||||
|
@ -691,9 +718,9 @@ bool PackedDecode::readBool(void)
|
|||
if ((header1 & HEADEREXTEND_MASK)!=0)
|
||||
getNextByte(curPos);
|
||||
uint1 typeByte = getNextByte(curPos);
|
||||
attributeRead = true;
|
||||
if ((typeByte >> TYPECODE_SHIFT) != TYPECODE_BOOLEAN)
|
||||
throw DecoderError("Expecting boolean attribute");
|
||||
attributeRead = true;
|
||||
return ((typeByte & LENGTHCODE_MASK) != 0);
|
||||
}
|
||||
|
||||
|
@ -724,6 +751,7 @@ intb PackedDecode::readSignedInteger(void)
|
|||
}
|
||||
else {
|
||||
skipAttributeRemaining(typeByte);
|
||||
attributeRead = true;
|
||||
throw DecoderError("Expecting signed integer attribute");
|
||||
}
|
||||
attributeRead = true;
|
||||
|
@ -739,6 +767,40 @@ intb PackedDecode::readSignedInteger(const AttributeId &attribId)
|
|||
return res;
|
||||
}
|
||||
|
||||
intb PackedDecode::readSignedIntegerExpectString(const string &expect,intb expectval)
|
||||
|
||||
{
|
||||
intb res;
|
||||
Position tmpPos = curPos;
|
||||
uint1 header1 = getNextByte(tmpPos);
|
||||
if ((header1 & HEADEREXTEND_MASK)!=0)
|
||||
getNextByte(tmpPos);
|
||||
uint1 typeByte = getNextByte(tmpPos);
|
||||
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
|
||||
if (typeCode == TYPECODE_STRING) {
|
||||
string val = readString();
|
||||
if (val != expect) {
|
||||
ostringstream s;
|
||||
s << "Expecting string \"" << expect << "\" but read \"" << val << "\"";
|
||||
throw DecoderError(s.str());
|
||||
}
|
||||
res = expectval;
|
||||
}
|
||||
else {
|
||||
res = readSignedInteger();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
intb PackedDecode::readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)
|
||||
|
||||
{
|
||||
findMatchingAttribute(attribId);
|
||||
intb res = readSignedIntegerExpectString(expect,expectval);
|
||||
curPos = startPos;
|
||||
return res;
|
||||
}
|
||||
|
||||
uintb PackedDecode::readUnsignedInteger(void)
|
||||
|
||||
{
|
||||
|
@ -753,6 +815,7 @@ uintb PackedDecode::readUnsignedInteger(void)
|
|||
}
|
||||
else {
|
||||
skipAttributeRemaining(typeByte);
|
||||
attributeRead = true;
|
||||
throw DecoderError("Expecting unsigned integer attribute");
|
||||
}
|
||||
attributeRead = true;
|
||||
|
@ -778,6 +841,7 @@ string PackedDecode::readString(void)
|
|||
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
|
||||
if (typeCode != TYPECODE_STRING) {
|
||||
skipAttributeRemaining(typeByte);
|
||||
attributeRead = true;
|
||||
throw DecoderError("Expecting string attribute");
|
||||
}
|
||||
int4 length = readLengthCode(typeByte);
|
||||
|
@ -842,6 +906,7 @@ AddrSpace *PackedDecode::readSpace(void)
|
|||
}
|
||||
else {
|
||||
skipAttributeRemaining(typeByte);
|
||||
attributeRead = true;
|
||||
throw DecoderError("Expecting space attribute");
|
||||
}
|
||||
attributeRead = true;
|
||||
|
|
|
@ -188,6 +188,29 @@ public:
|
|||
/// \return the signed integer value
|
||||
virtual intb readSignedInteger(const AttributeId &attribId)=0;
|
||||
|
||||
/// \brief Parse the current attribute as either a signed integer value or a string.
|
||||
///
|
||||
/// If the attribute is an integer, its value is returned. If the attribute is a string, it must match an
|
||||
/// expected string passed to the method, and a predetermined integer value associated with the string is returned.
|
||||
/// If the attribute neither matches the expected string nor is an integer, the return value is undefined.
|
||||
/// \param expect is the string value to expect if the attribute is encoded as a string
|
||||
/// \param expectval is the integer value to return if the attribute matches the expected string
|
||||
/// \return the encoded integer or the integer value associated with the expected string
|
||||
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval)=0;
|
||||
|
||||
/// \brief Find and parse a specific attribute in the current element as either a signed integer or a string.
|
||||
///
|
||||
/// If the attribute is an integer, its value is parsed and returned.
|
||||
/// If the attribute is encoded as a string, it must match an expected string passed to this method.
|
||||
/// In this case, a predetermined integer value is passed back, indicating a matching string was parsed.
|
||||
/// If the attribute neither matches the expected string nor is an integer, the return value is undefined.
|
||||
/// If there is no attribute matching the id, an exception is thrown.
|
||||
/// \param attribId is the specific attribute id to match
|
||||
/// \param expect is the string to expect, if the attribute is not encoded as an integer
|
||||
/// \param expectval is the integer value to return if the attribute matches the expected string
|
||||
/// \return the encoded integer or the integer value associated with the expected string
|
||||
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)=0;
|
||||
|
||||
/// \brief Parse the current attribute as an unsigned integer value
|
||||
///
|
||||
/// The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer, and its value is returned.
|
||||
|
@ -337,6 +360,8 @@ public:
|
|||
virtual bool readBool(const AttributeId &attribId);
|
||||
virtual intb readSignedInteger(void);
|
||||
virtual intb readSignedInteger(const AttributeId &attribId);
|
||||
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval);
|
||||
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval);
|
||||
virtual uintb readUnsignedInteger(void);
|
||||
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
||||
virtual string readString(void);
|
||||
|
@ -470,6 +495,8 @@ public:
|
|||
virtual bool readBool(const AttributeId &attribId);
|
||||
virtual intb readSignedInteger(void);
|
||||
virtual intb readSignedInteger(const AttributeId &attribId);
|
||||
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval);
|
||||
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval);
|
||||
virtual uintb readUnsignedInteger(void);
|
||||
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
||||
virtual string readString(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue