mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-2157 Marshaling refactor. Decompiler side.
This commit is contained in:
parent
672c1f11e2
commit
d8c10bf229
97 changed files with 5313 additions and 3733 deletions
|
@ -15,41 +15,52 @@
|
|||
*/
|
||||
#include "cpool.hh"
|
||||
|
||||
/// Save the constant pool object description as a \<cpoolrec> tag.
|
||||
/// \param s is the output stream
|
||||
void CPoolRecord::saveXml(ostream &s) const
|
||||
AttributeId ATTRIB_A = AttributeId("a",45);
|
||||
AttributeId ATTRIB_B = AttributeId("b",46);
|
||||
AttributeId ATTRIB_LENGTH = AttributeId("length",47);
|
||||
AttributeId ATTRIB_TAG = AttributeId("tag",48);
|
||||
|
||||
ElementId ELEM_CONSTANTPOOL = ElementId("constantpool",56);
|
||||
ElementId ELEM_CPOOLREC = ElementId("cpoolrec",57);
|
||||
ElementId ELEM_REF = ElementId("ref",58);
|
||||
ElementId ELEM_TOKEN = ElementId("token",59);
|
||||
|
||||
/// Encode the constant pool object description as a \<cpoolrec> element.
|
||||
/// \param encoder is the stream encoder
|
||||
void CPoolRecord::encode(Encoder &encoder) const
|
||||
|
||||
{
|
||||
s << "<cpoolrec";
|
||||
encoder.openElement(ELEM_CPOOLREC);
|
||||
if (tag == pointer_method)
|
||||
a_v(s,"tag","method");
|
||||
encoder.writeString(ATTRIB_TAG, "method");
|
||||
else if (tag == pointer_field)
|
||||
a_v(s,"tag","field");
|
||||
encoder.writeString(ATTRIB_TAG, "field");
|
||||
else if (tag == instance_of)
|
||||
a_v(s,"tag","instanceof");
|
||||
encoder.writeString(ATTRIB_TAG, "instanceof");
|
||||
else if (tag == array_length)
|
||||
a_v(s,"tag","arraylength");
|
||||
encoder.writeString(ATTRIB_TAG, "arraylength");
|
||||
else if (tag == check_cast)
|
||||
a_v(s,"tag","checkcast");
|
||||
encoder.writeString(ATTRIB_TAG, "checkcast");
|
||||
else if (tag == string_literal)
|
||||
a_v(s,"tag","string");
|
||||
encoder.writeString(ATTRIB_TAG, "string");
|
||||
else if (tag == class_reference)
|
||||
a_v(s,"tag","classref");
|
||||
encoder.writeString(ATTRIB_TAG, "classref");
|
||||
else
|
||||
a_v(s,"tag","primitive");
|
||||
encoder.writeString(ATTRIB_TAG, "primitive");
|
||||
if (isConstructor())
|
||||
a_v_b(s,"constructor",true);
|
||||
encoder.writeBool(ATTRIB_CONSTRUCTOR, true);
|
||||
if (isDestructor())
|
||||
a_v_b(s,"destructor",true);
|
||||
s << ">\n";
|
||||
encoder.writeBool(ATTRIB_DESTRUCTOR, true);
|
||||
if (tag == primitive) {
|
||||
s << " <value>0x";
|
||||
s << hex << value;
|
||||
s << "</value>\n";
|
||||
encoder.openElement(ELEM_VALUE);
|
||||
encoder.writeUnsignedInteger(ATTRIB_CONTENT, value);
|
||||
encoder.closeElement(ELEM_VALUE);
|
||||
}
|
||||
if (byteData != (uint1 *)0) {
|
||||
s << " <data length=\"" << dec << byteDataLen << "\">\n";
|
||||
encoder.openElement(ELEM_DATA);
|
||||
encoder.writeSignedInteger(ATTRIB_LENGTH, byteDataLen);
|
||||
int4 wrap = 0;
|
||||
ostringstream s;
|
||||
for(int4 i=0;i<byteDataLen;++i) {
|
||||
s << setfill('0') << setw(2) << hex << byteData[i] << ' ';
|
||||
wrap += 1;
|
||||
|
@ -58,31 +69,33 @@ void CPoolRecord::saveXml(ostream &s) const
|
|||
wrap = 0;
|
||||
}
|
||||
}
|
||||
s << " </data>\n";
|
||||
encoder.writeString(ATTRIB_CONTENT, s.str());
|
||||
encoder.closeElement(ELEM_DATA);
|
||||
}
|
||||
else {
|
||||
s << " <token>";
|
||||
xml_escape(s,token.c_str());
|
||||
s << " </token>\n";
|
||||
encoder.openElement(ELEM_TOKEN);
|
||||
encoder.writeString(ATTRIB_CONTENT, token);
|
||||
encoder.closeElement(ELEM_TOKEN);
|
||||
}
|
||||
type->saveXml(s);
|
||||
s << "</cpoolrec>\n";
|
||||
type->encode(encoder);
|
||||
encoder.closeElement(ELEM_CPOOLREC);
|
||||
}
|
||||
|
||||
/// Initialize \b this CPoolRecord instance from a \<cpoolrec> tag.
|
||||
/// \param el is the \<cpoolrec> element
|
||||
/// Initialize \b this CPoolRecord instance from a \<cpoolrec> element.
|
||||
/// \param decoder is the stream decoder
|
||||
/// \param typegrp is the TypeFactory used to resolve data-types
|
||||
void CPoolRecord::restoreXml(const Element *el,TypeFactory &typegrp)
|
||||
void CPoolRecord::decode(Decoder &decoder,TypeFactory &typegrp)
|
||||
|
||||
{
|
||||
tag = primitive; // Default tag
|
||||
value = 0;
|
||||
flags = 0;
|
||||
int4 num = el->getNumAttributes();
|
||||
for(int4 i=0;i<num;++i) {
|
||||
const string &attr(el->getAttributeName(i));
|
||||
if (attr == "tag") {
|
||||
const string &tagstring(el->getAttributeValue(i));
|
||||
uint4 elemId = decoder.openElement(ELEM_CPOOLREC);
|
||||
for(;;) {
|
||||
uint4 attribId = decoder.getNextAttributeId();
|
||||
if (attribId == 0) break;
|
||||
if (attribId == ATTRIB_TAG) {
|
||||
string tagstring = decoder.readString();
|
||||
if (tagstring == "method")
|
||||
tag = pointer_method;
|
||||
else if (tagstring == "field")
|
||||
|
@ -98,36 +111,27 @@ void CPoolRecord::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
else if (tagstring == "classref")
|
||||
tag = class_reference;
|
||||
}
|
||||
else if (attr == "constructor") {
|
||||
if (xml_readbool(el->getAttributeValue(i)))
|
||||
else if (attribId == ATTRIB_CONSTRUCTOR) {
|
||||
if (decoder.readBool())
|
||||
flags |= CPoolRecord::is_constructor;
|
||||
}
|
||||
else if (attr == "destructor") {
|
||||
if (xml_readbool(el->getAttributeValue(i)))
|
||||
else if (attribId == ATTRIB_DESTRUCTOR) {
|
||||
if (decoder.readBool())
|
||||
flags |= CPoolRecord::is_destructor;
|
||||
}
|
||||
}
|
||||
const List &list(el->getChildren());
|
||||
List::const_iterator iter;
|
||||
|
||||
iter = list.begin();
|
||||
const Element *subel;
|
||||
uint4 subId;
|
||||
if (tag == primitive) { // First tag must be value
|
||||
subel = *iter;
|
||||
istringstream s1(subel->getContent());
|
||||
s1.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s1 >> value;
|
||||
++iter;
|
||||
subId = decoder.openElement(ELEM_VALUE);
|
||||
value = decoder.readUnsignedInteger(ATTRIB_CONTENT);
|
||||
decoder.closeElement(subId);
|
||||
}
|
||||
subel = *iter;
|
||||
++iter;
|
||||
if (subel->getName() == "token")
|
||||
token = subel->getContent();
|
||||
subId = decoder.openElement();
|
||||
if (subId == ELEM_TOKEN)
|
||||
token = decoder.readString(ATTRIB_CONTENT);
|
||||
else {
|
||||
istringstream s2(subel->getAttributeValue("length"));
|
||||
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s2 >> byteDataLen;
|
||||
istringstream s3(subel->getContent());
|
||||
byteDataLen = decoder.readSignedInteger(ATTRIB_LENGTH);
|
||||
istringstream s3(decoder.readString(ATTRIB_CONTENT));
|
||||
byteData = new uint1[byteDataLen];
|
||||
for(int4 i=0;i<byteDataLen;++i) {
|
||||
uint4 val;
|
||||
|
@ -135,16 +139,17 @@ void CPoolRecord::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
byteData[i] = (uint1)val;
|
||||
}
|
||||
}
|
||||
decoder.closeElement(subId);
|
||||
if (tag == string_literal && (byteData == (uint1 *)0))
|
||||
throw LowlevelError("Bad constant pool record: missing <data>");
|
||||
subel = *iter;
|
||||
if (flags != 0) {
|
||||
bool isConstructor = ((flags & is_constructor)!=0);
|
||||
bool isDestructor = ((flags & is_destructor)!=0);
|
||||
type = typegrp.restoreXmlTypeWithCodeFlags(subel,isConstructor,isDestructor);
|
||||
type = typegrp.decodeTypeWithCodeFlags(decoder,isConstructor,isDestructor);
|
||||
}
|
||||
else
|
||||
type = typegrp.restoreXmlType(subel);
|
||||
type = typegrp.decodeType(decoder);
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
void ConstantPool::putRecord(const vector<uintb> &refs,uint4 tag,const string &tok,Datatype *ct)
|
||||
|
@ -156,36 +161,34 @@ void ConstantPool::putRecord(const vector<uintb> &refs,uint4 tag,const string &t
|
|||
newrec->type = ct;
|
||||
}
|
||||
|
||||
const CPoolRecord *ConstantPool::restoreXmlRecord(const vector<uintb> &refs,const Element *el,TypeFactory &typegrp)
|
||||
const CPoolRecord *ConstantPool::decodeRecord(const vector<uintb> &refs,Decoder &decoder,TypeFactory &typegrp)
|
||||
|
||||
{
|
||||
CPoolRecord *newrec = createRecord(refs);
|
||||
newrec->restoreXml(el,typegrp);
|
||||
newrec->decode(decoder,typegrp);
|
||||
return newrec;
|
||||
}
|
||||
|
||||
/// The reference is output as a \<ref> tag.
|
||||
/// \param s is the output stream
|
||||
void ConstantPoolInternal::CheapSorter::saveXml(ostream &s) const
|
||||
/// The reference is encoded as a \<ref> element.
|
||||
/// \param encoder is the stream encoder
|
||||
void ConstantPoolInternal::CheapSorter::encode(Encoder &encoder) const
|
||||
|
||||
{
|
||||
s << "<ref";
|
||||
a_v_u(s,"a",a);
|
||||
a_v_u(s,"b",b);
|
||||
s << "/>\n";
|
||||
encoder.openElement(ELEM_REF);
|
||||
encoder.writeUnsignedInteger(ATTRIB_A, a);
|
||||
encoder.writeUnsignedInteger(ATTRIB_B, b);
|
||||
encoder.closeElement(ELEM_REF);
|
||||
}
|
||||
|
||||
/// Restore \b this \e reference from a \<ref> XML tag
|
||||
/// \param el is the XML element
|
||||
void ConstantPoolInternal::CheapSorter::restoreXml(const Element *el)
|
||||
/// Restore \b this \e reference from a \<ref> element
|
||||
/// \param decoder is the stream decoder
|
||||
void ConstantPoolInternal::CheapSorter::decode(Decoder &decoder)
|
||||
|
||||
{
|
||||
istringstream s1(el->getAttributeValue("a"));
|
||||
s1.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s1 >> a;
|
||||
istringstream s2(el->getAttributeValue("b"));
|
||||
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s2 >> b;
|
||||
uint4 elemId = decoder.openElement(ELEM_REF);
|
||||
a = decoder.readUnsignedInteger(ATTRIB_A);
|
||||
b = decoder.readUnsignedInteger(ATTRIB_B);
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
CPoolRecord *ConstantPoolInternal::createRecord(const vector<uintb> &refs)
|
||||
|
@ -210,32 +213,29 @@ const CPoolRecord *ConstantPoolInternal::getRecord(const vector<uintb> &refs) co
|
|||
return &(*iter).second;
|
||||
}
|
||||
|
||||
void ConstantPoolInternal::saveXml(ostream &s) const
|
||||
void ConstantPoolInternal::encode(Encoder &encoder) const
|
||||
|
||||
{
|
||||
map<CheapSorter,CPoolRecord>::const_iterator iter;
|
||||
s << "<constantpool>\n";
|
||||
encoder.openElement(ELEM_CONSTANTPOOL);
|
||||
for(iter=cpoolMap.begin();iter!=cpoolMap.end();++iter) {
|
||||
(*iter).first.saveXml(s);
|
||||
(*iter).second.saveXml(s);
|
||||
(*iter).first.encode(encoder);
|
||||
(*iter).second.encode(encoder);
|
||||
}
|
||||
s << "</constantpool>\n";
|
||||
encoder.closeElement(ELEM_CONSTANTPOOL);
|
||||
}
|
||||
|
||||
void ConstantPoolInternal::restoreXml(const Element *el,TypeFactory &typegrp)
|
||||
void ConstantPoolInternal::decode(Decoder &decoder,TypeFactory &typegrp)
|
||||
|
||||
{
|
||||
const List &list(el->getChildren());
|
||||
List::const_iterator iter;
|
||||
for(iter=list.begin();iter!=list.end();++iter) {
|
||||
const Element *subel = *iter;
|
||||
uint4 elemId = decoder.openElement(ELEM_CONSTANTPOOL);
|
||||
while(decoder.peekElement() != 0) {
|
||||
CheapSorter sorter;
|
||||
sorter.restoreXml(subel);
|
||||
sorter.decode(decoder);
|
||||
vector<uintb> refs;
|
||||
sorter.apply(refs);
|
||||
++iter;
|
||||
subel = *iter;
|
||||
CPoolRecord *newrec = createRecord(refs);
|
||||
newrec->restoreXml(subel,typegrp);
|
||||
newrec->decode(decoder,typegrp);
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue