GP-2157 Marshaling refactor. Decompiler side.

This commit is contained in:
caheckman 2022-05-17 16:15:21 -04:00
parent 672c1f11e2
commit d8c10bf229
97 changed files with 5313 additions and 3733 deletions

View file

@ -15,42 +15,43 @@
*/
#include "inject_ghidra.hh"
void InjectContextGhidra::saveXml(ostream &s) const
void InjectContextGhidra::encode(Encoder &encoder) const
{
s << "<context>\n";
baseaddr.saveXml(s);
calladdr.saveXml(s);
encoder.openElement(ELEM_CONTEXT);
baseaddr.encode(encoder);
calladdr.encode(encoder);
if (!inputlist.empty()) {
s << "<input>\n";
encoder.openElement(ELEM_INPUT);
for(int4 i=0;i<inputlist.size();++i) {
const VarnodeData &vn( inputlist[i] );
s << "<addr";
vn.space->saveXmlAttributes(s,vn.offset,vn.size);
s << "/>\n";
encoder.openElement(ELEM_ADDR);
vn.space->encodeAttributes(encoder,vn.offset,vn.size);
encoder.closeElement(ELEM_ADDR);
}
s << "</input>\n";
encoder.closeElement(ELEM_INPUT);
}
if (!output.empty()) {
s << "<output>\n";
encoder.openElement(ELEM_OUTPUT);
for(int4 i=0;i<output.size();++i) {
const VarnodeData &vn( output[i] );
s << "<addr";
vn.space->saveXmlAttributes(s,vn.offset,vn.size);
s << "/>\n";
encoder.openElement(ELEM_ADDR);
vn.space->encodeAttributes(encoder,vn.offset,vn.size);
encoder.closeElement(ELEM_ADDR);
}
s << "</output>\n";
encoder.closeElement(ELEM_OUTPUT);
}
s << "</context>\n";
encoder.closeElement(ELEM_CONTEXT);
}
void InjectPayloadGhidra::inject(InjectContext &con,PcodeEmit &emit) const
{
Document *doc;
ArchitectureGhidra *ghidra = (ArchitectureGhidra *)con.glb;
XmlDecode decoder;
try {
doc = ghidra->getPcodeInject(name,type,con);
if (!ghidra->getPcodeInject(name,type,con,decoder))
throw LowlevelError("Could not retrieve pcode snippet: "+name);
}
catch(JavaError &err) {
throw LowlevelError("Error getting pcode snippet: " + err.explain);
@ -58,15 +59,19 @@ void InjectPayloadGhidra::inject(InjectContext &con,PcodeEmit &emit) const
catch(XmlError &err) {
throw LowlevelError("Error in pcode snippet xml: "+err.explain);
}
if (doc == (Document *)0) {
throw LowlevelError("Could not retrieve pcode snippet: "+name);
}
const Element *el = doc->getRoot();
const List &list(el->getChildren());
List::const_iterator iter;
for(iter=list.begin();iter!=list.end();++iter)
emit.restoreXmlOp(*iter,ghidra->translate);
delete doc;
uint4 elemId = decoder.openElement();
while(decoder.peekElement() != 0)
emit.decodeOp(decoder,ghidra->translate);
decoder.closeElement(elemId);
}
void InjectPayloadGhidra::decode(Decoder &decoder)
{
// Restore a raw <pcode> tag. Used for uponentry, uponreturn
uint4 elemId = decoder.openElement(ELEM_PCODE);
decodePayloadAttributes(decoder);
decoder.closeElementSkipping(elemId);
}
void InjectPayloadGhidra::printTemplate(ostream &s) const
@ -80,10 +85,12 @@ InjectCallfixupGhidra::InjectCallfixupGhidra(const string &src,const string &nm)
{
}
void InjectCallfixupGhidra::restoreXml(const Element *el)
void InjectCallfixupGhidra::decode(Decoder &decoder)
{
name = el->getAttributeValue("name");
uint4 elemId = decoder.openElement(ELEM_CALLFIXUP);
name = decoder.readString(ATTRIB_NAME);
decoder.closeElementSkipping(elemId); // Skip processing the body, let ghidra handle this
}
InjectCallotherGhidra::InjectCallotherGhidra(const string &src,const string &nm)
@ -91,16 +98,18 @@ InjectCallotherGhidra::InjectCallotherGhidra(const string &src,const string &nm)
{
}
void InjectCallotherGhidra::restoreXml(const Element *el)
void InjectCallotherGhidra::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
name = el->getAttributeValue("targetop");
iter = list.begin();
if ((iter == list.end()) || ((*iter)->getName() != "pcode"))
uint4 elemId = decoder.openElement(ELEM_CALLOTHERFIXUP);
name = decoder.readString(ATTRIB_TARGETOP);
uint4 subId = decoder.openElement();
if (subId != ELEM_PCODE)
throw LowlevelError("<callotherfixup> does not contain a <pcode> tag");
InjectPayload::restoreXml(*iter);
decodePayloadAttributes(decoder);
decodePayloadParams(decoder);
decoder.closeElementSkipping(subId); // Skip processing the body, let ghidra handle this
decoder.closeElement(elemId);
}
ExecutablePcodeGhidra::ExecutablePcodeGhidra(Architecture *g,const string &src,const string &nm)
@ -111,10 +120,11 @@ ExecutablePcodeGhidra::ExecutablePcodeGhidra(Architecture *g,const string &src,c
void ExecutablePcodeGhidra::inject(InjectContext &con,PcodeEmit &emit) const
{
Document *doc;
ArchitectureGhidra *ghidra = (ArchitectureGhidra *)con.glb;
XmlDecode decoder;
try {
doc = ghidra->getPcodeInject(name,type,con);
if (!ghidra->getPcodeInject(name,type,con,decoder))
throw LowlevelError("Could not retrieve pcode snippet: "+name);
}
catch(JavaError &err) {
throw LowlevelError("Error getting pcode snippet: " + err.explain);
@ -122,22 +132,22 @@ void ExecutablePcodeGhidra::inject(InjectContext &con,PcodeEmit &emit) const
catch(XmlError &err) {
throw LowlevelError("Error in pcode snippet xml: "+err.explain);
}
if (doc == (Document *)0) {
throw LowlevelError("Could not retrieve pcode snippet: "+name);
}
const Element *el = doc->getRoot();
const List &list(el->getChildren());
List::const_iterator iter;
for(iter=list.begin();iter!=list.end();++iter)
emit.restoreXmlOp(*iter,ghidra->translate);
delete doc;
uint4 elemId = decoder.openElement();
while(decoder.peekElement() != 0)
emit.decodeOp(decoder,ghidra->translate);
decoder.closeElement(elemId);
}
void ExecutablePcodeGhidra::restoreXml(const Element *el)
void ExecutablePcodeGhidra::decode(Decoder &decoder)
{
InjectPayload::restoreXml(el); // Read parameters
// But ignore rest of body
uint4 elemId = decoder.openElement();
if (elemId != ELEM_CASE_PCODE && elemId != ELEM_ADDR_PCODE &&
elemId != ELEM_DEFAULT_PCODE && elemId != ELEM_SIZE_PCODE)
throw XmlError("Expecting <case_pcode>, <addr_pcode>, <default_pcode>, or <size_pcode>");
decodePayloadAttributes(decoder);
decodePayloadParams(decoder); // Parse the parameters
decoder.closeElementSkipping(elemId); // But skip rest of body
}
void ExecutablePcodeGhidra::printTemplate(ostream &s) const