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

@ -17,34 +17,43 @@
#include "block.hh"
#include "funcdata.hh"
/// The edge is saved assuming we already know what block we are in
/// \param s is the output stream
void BlockEdge::saveXml(ostream &s) const
AttributeId ATTRIB_ALTINDEX = AttributeId("altindex",40);
AttributeId ATTRIB_DEPTH = AttributeId("depth",41);
AttributeId ATTRIB_END = AttributeId("end",42);
AttributeId ATTRIB_OPCODE = AttributeId("opcode",43);
AttributeId ATTRIB_REV = AttributeId("rev",44);
ElementId ELEM_BHEAD = ElementId("bhead",47);
ElementId ELEM_BLOCK = ElementId("block",48);
ElementId ELEM_BLOCKEDGE = ElementId("blockedge",49);
ElementId ELEM_EDGE = ElementId("edge",50);
/// The edge is saved assuming we already know what block we are in.
/// \param encoder is the stream encoder
void BlockEdge::encode(Encoder &encoder) const
{
s << "<edge";
encoder.openElement(ELEM_EDGE);
// We are not saving label currently
a_v_i(s,"end",point->getIndex()); // Reference to other end of edge
a_v_i(s,"rev",reverse_index); // Position within other blocks edgelist
s << "/>\n";
encoder.writeSignedInteger(ATTRIB_END, point->getIndex()); // Reference to other end of edge
encoder.writeSignedInteger(ATTRIB_REV, reverse_index); // Position within other blocks edgelist
encoder.closeElement(ELEM_EDGE);
}
/// \param el is the \<edge> tag
/// Parse an \<edge> element
/// \param decoder is the stream decoder
/// \param resolver is used to cross-reference the edge's FlowBlock endpoints
void BlockEdge::restoreXml(const Element *el,BlockMap &resolver)
void BlockEdge::decode(Decoder &decoder,BlockMap &resolver)
{
uint4 elemId = decoder.openElement(ELEM_EDGE);
label = 0; // Tag does not currently contain info about label
int4 endIndex;
istringstream s(el->getAttributeValue("end"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> endIndex;
int4 endIndex = decoder.readSignedInteger(ATTRIB_END);
point = resolver.findLevelBlock(endIndex);
if (point == (FlowBlock *)0)
throw LowlevelError("Bad serialized edge in block graph");
istringstream s2(el->getAttributeValue("rev"));
s2.unsetf(ios::dec | ios::hex | ios::oct);
s2 >> reverse_index;
reverse_index = decoder.readSignedInteger(ATTRIB_REV);
decoder.closeElement(elemId);
}
FlowBlock::FlowBlock(void)
@ -68,14 +77,15 @@ void FlowBlock::addInEdge(FlowBlock *b,uint4 lab)
b->outofthis.push_back(BlockEdge(this,lab,brev));
}
/// \param el is the \<edge> element
/// Parse the next \<edge> element in the stream
/// \param decoder is the stream decoder
/// \param resolver is used to resolve block references
void FlowBlock::restoreNextInEdge(const Element *el,BlockMap &resolver)
void FlowBlock::decodeNextInEdge(Decoder &decoder,BlockMap &resolver)
{
intothis.emplace_back();
BlockEdge &inedge(intothis.back());
inedge.restoreXml(el,resolver);
inedge.decode(decoder,resolver);
while(inedge.point->outofthis.size() <= inedge.reverse_index)
inedge.point->outofthis.emplace_back();
BlockEdge &outedge(inedge.point->outofthis[inedge.reverse_index]);
@ -621,7 +631,7 @@ JumpTable *FlowBlock::getJumptable(void) const
}
/// Given a string describing a FlowBlock type, return the block_type.
/// This is currently only used by the restoreXml() process.
/// This is currently only used by the decode() process.
/// TODO: Fill in the remaining names and types
/// \param nm is the name string
/// \return the corresponding block_type
@ -1286,14 +1296,14 @@ void BlockGraph::finalizePrinting(Funcdata &data) const
(*iter)->finalizePrinting(data);
}
void BlockGraph::saveXmlBody(ostream &s) const
void BlockGraph::encodeBody(Encoder &encoder) const
{
FlowBlock::saveXmlBody(s);
FlowBlock::encodeBody(encoder);
for(int4 i=0;i<list.size();++i) {
FlowBlock *bl = list[i];
s << "<bhead";
a_v_i(s,"index",bl->getIndex());
encoder.openElement(ELEM_BHEAD);
encoder.writeSignedInteger(ATTRIB_INDEX, bl->getIndex());
FlowBlock::block_type bt = bl->getType();
string nm;
if (bt == FlowBlock::t_if) {
@ -1307,54 +1317,47 @@ void BlockGraph::saveXmlBody(ostream &s) const
}
else
nm = FlowBlock::typeToName(bt);
a_v(s,"type",nm);
s << "/>\n";
encoder.writeString(ATTRIB_TYPE, nm);
encoder.closeElement(ELEM_BHEAD);
}
for(int4 i=0;i<list.size();++i)
list[i]->saveXml(s);
list[i]->encode(encoder);
}
void BlockGraph::restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver)
void BlockGraph::decodeBody(Decoder &decoder,BlockMap &resolver)
{
BlockMap newresolver(resolver);
FlowBlock::restoreXmlBody(iter,enditer,newresolver);
vector<FlowBlock *> tmplist;
while(iter != enditer) {
const Element *el = *iter;
if (el->getName() != "bhead") break;
++iter;
int4 newindex;
istringstream s(el->getAttributeValue("index"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> newindex;
const string &nm( el->getAttributeValue("type") );
FlowBlock *bl = newresolver.createBlock(nm);
for(;;) {
uint4 subId = decoder.peekElement();
if (subId != ELEM_BHEAD) break;
decoder.openElement();
int4 newindex = decoder.readSignedInteger(ATTRIB_INDEX);
FlowBlock *bl = newresolver.createBlock(decoder.readString(ATTRIB_TYPE));
bl->index = newindex; // Need to set index here for sort
tmplist.push_back(bl);
decoder.closeElement(subId);
}
newresolver.sortList();
for(int4 i=0;i<tmplist.size();++i) {
if (iter == enditer)
throw LowlevelError("Bad BlockGraph xml");
FlowBlock *bl = tmplist[i];
bl->restoreXml(*iter,newresolver);
bl->decode(decoder,newresolver);
addBlock(bl);
++iter;
}
}
/// This is currently just a wrapper around the FlowBlock::restoreXml()
/// that sets of the BlockMap resolver
/// \param el is the root \<block> tag
/// Parse a \<block> element. This is currently just a wrapper around the
/// FlowBlock::decode() that sets of the BlockMap resolver
/// \param decoder is the stream decoder
/// \param m is the address space manager
void BlockGraph::restoreXml(const Element *el,const AddrSpaceManager *m)
void BlockGraph::decode(Decoder &decoder,const AddrSpaceManager *m)
{
BlockMap resolver(m);
FlowBlock::restoreXml(el,resolver);
FlowBlock::decode(decoder,resolver);
// Restore goto references here
}
@ -2353,77 +2356,70 @@ bool BlockBasic::isComplex(void) const
return false;
}
/// \param s is the output stream
void FlowBlock::saveXmlHeader(ostream &s) const
/// \param encoder is the stream encoder
void FlowBlock::encodeHeader(Encoder &encoder) const
{
a_v_i(s,"index",index);
encoder.writeSignedInteger(ATTRIB_INDEX, index);
}
/// \param el is the XML element to pull attributes from
void FlowBlock::restoreXmlHeader(const Element *el)
/// \param decoder is the stream decoder to pull attributes from
void FlowBlock::decodeHeader(Decoder &decoder)
{
istringstream s(el->getAttributeValue("index"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> index;
index = decoder.readSignedInteger(ATTRIB_INDEX);
}
/// Write \<edge> tags to stream
/// \param s is the output stream
void FlowBlock::saveXmlEdges(ostream &s) const
/// Write \<edge> element to a stream
/// \param encoder is the stream encoder
void FlowBlock::encodeEdges(Encoder &encoder) const
{
for(int4 i=0;i<intothis.size();++i) {
intothis[i].saveXml(s);
intothis[i].encode(encoder);
}
}
/// \brief Restore edges from an XML stream
/// \brief Restore edges from an encoded stream
///
/// \param iter is an iterator to the \<edge> tags
/// \param enditer marks the end of the list of tags
/// \param decoder is the stream decoder
/// \param resolver is used to recover FlowBlock cross-references
void FlowBlock::restoreXmlEdges(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver)
void FlowBlock::decodeEdges(Decoder &decoder,BlockMap &resolver)
{
while(iter != enditer) {
const Element *el = *iter;
if (el->getName() != "edge")
return;
++iter;
restoreNextInEdge(el,resolver);
for(;;) {
uint4 subId = decoder.peekElement();
if (subId != ELEM_EDGE)
break;
decodeNextInEdge(decoder,resolver);
}
}
/// Serialize \b this and all its sub-components as an XML \<block> tag.
/// \param s is the output stream
void FlowBlock::saveXml(ostream &s) const
/// Encode \b this and all its sub-components as a \<block> element.
/// \param encoder is the stream encoder
void FlowBlock::encode(Encoder &encoder) const
{
s << "<block";
saveXmlHeader(s);
s << ">\n";
saveXmlBody(s);
saveXmlEdges(s);
s << "</block>\n";
encoder.openElement(ELEM_BLOCK);
encodeHeader(encoder);
encodeBody(encoder);
encodeEdges(encoder);
encoder.closeElement(ELEM_BLOCK);
}
/// Recover \b this and all it sub-components from an XML \<block> tag.
/// Recover \b this and all it sub-components from a \<block> element.
///
/// This will construct all the sub-components using \b resolver as a factory.
/// \param el is the root XML element
/// \param decoder is the stream decoder
/// \param resolver acts as a factory and resolves cross-references
void FlowBlock::restoreXml(const Element *el,BlockMap &resolver)
void FlowBlock::decode(Decoder &decoder,BlockMap &resolver)
{
restoreXmlHeader(el);
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
restoreXmlBody(iter,list.end(),resolver);
restoreXmlEdges(iter,list.end(),resolver);
uint4 elemId = decoder.openElement(ELEM_BLOCK);
decodeHeader(decoder);
decodeBody(decoder,resolver);
decodeEdges(decoder,resolver);
decoder.closeElement(elemId);
}
/// If there are two branches, pick the fall-thru branch
@ -2560,17 +2556,16 @@ void BlockBasic::setOrder(void)
}
}
void BlockBasic::saveXmlBody(ostream &s) const
void BlockBasic::encodeBody(Encoder &encoder) const
{
cover.saveXml(s);
cover.encode(encoder);
}
void BlockBasic::restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver)
void BlockBasic::decodeBody(Decoder &decoder,BlockMap &resolver)
{
cover.restoreXml(*iter, resolver.getAddressManager());
++iter;
cover.decode(decoder, resolver.getAddressManager());
}
void BlockBasic::printHeader(ostream &s) const
@ -2635,12 +2630,12 @@ void BlockCopy::printTree(ostream &s,int4 level) const
copy->printTree(s,level);
}
void BlockCopy::saveXmlHeader(ostream &s) const
void BlockCopy::encodeHeader(Encoder &encoder) const
{
FlowBlock::saveXmlHeader(s);
FlowBlock::encodeHeader(encoder);
int4 altindex = copy->getIndex();
a_v_i(s,"altindex",altindex);
encoder.writeSignedInteger(ATTRIB_ALTINDEX, altindex);
}
void BlockGoto::markUnstructured(void)
@ -2692,17 +2687,17 @@ FlowBlock *BlockGoto::nextFlowAfter(const FlowBlock *bl) const
return getGotoTarget()->getFrontLeaf();
}
void BlockGoto::saveXmlBody(ostream &s) const
void BlockGoto::encodeBody(Encoder &encoder) const
{
BlockGraph::saveXmlBody(s);
s << "<target";
BlockGraph::encodeBody(encoder);
encoder.openElement(ELEM_TARGET);
const FlowBlock *leaf = gototarget->getFrontLeaf();
int4 depth = gototarget->calcDepth(leaf);
a_v_i(s,"index",leaf->getIndex());
a_v_i(s,"depth",depth);
a_v_u(s,"type",gototype);
s << "/>\n";
encoder.writeSignedInteger(ATTRIB_INDEX, leaf->getIndex());
encoder.writeSignedInteger(ATTRIB_DEPTH, depth);
encoder.writeUnsignedInteger(ATTRIB_TYPE, gototype);
encoder.closeElement(ELEM_TARGET);
}
void BlockMultiGoto::scopeBreak(int4 curexit,int4 curloopexit)
@ -2725,18 +2720,18 @@ FlowBlock *BlockMultiGoto::nextFlowAfter(const FlowBlock *bl) const
return (FlowBlock *)0;
}
void BlockMultiGoto::saveXmlBody(ostream &s) const
void BlockMultiGoto::encodeBody(Encoder &encoder) const
{
BlockGraph::saveXmlBody(s);
BlockGraph::encodeBody(encoder);
for(int4 i=0;i<gotoedges.size();++i) {
FlowBlock *gototarget = gotoedges[i];
const FlowBlock *leaf = gototarget->getFrontLeaf();
int4 depth = gototarget->calcDepth(leaf);
s << "<target";
a_v_i(s,"index",leaf->getIndex());
a_v_i(s,"depth",depth);
s << "/>\n";
encoder.openElement(ELEM_TARGET);
encoder.writeSignedInteger(ATTRIB_INDEX, leaf->getIndex());
encoder.writeSignedInteger(ATTRIB_DEPTH, depth);
encoder.closeElement(ELEM_TARGET);
}
}
@ -2846,12 +2841,12 @@ FlowBlock *BlockCondition::nextFlowAfter(const FlowBlock *bl) const
return (FlowBlock *)0; // Do not know where flow goes
}
void BlockCondition::saveXmlHeader(ostream &s) const
void BlockCondition::encodeHeader(Encoder &encoder) const
{
BlockGraph::saveXmlHeader(s);
BlockGraph::encodeHeader(encoder);
string nm(get_opname(opc));
a_v(s,"opcode",nm);
encoder.writeString(ATTRIB_OPCODE, nm);
}
void BlockIf::markUnstructured(void)
@ -2924,18 +2919,18 @@ FlowBlock *BlockIf::nextFlowAfter(const FlowBlock *bl) const
return getParent()->nextFlowAfter(this);
}
void BlockIf::saveXmlBody(ostream &s) const
void BlockIf::encodeBody(Encoder &encoder) const
{
BlockGraph::saveXmlBody(s);
BlockGraph::encodeBody(encoder);
if (getSize() == 1) { // If this is a if GOTO block
const FlowBlock *leaf = gototarget->getFrontLeaf();
int4 depth = gototarget->calcDepth(leaf);
s << "<target";
a_v_i(s,"index",leaf->getIndex());
a_v_i(s,"depth",depth);
a_v_u(s,"type",gototype);
s << "/>\n";
encoder.openElement(ELEM_TARGET);
encoder.writeSignedInteger(ATTRIB_INDEX, leaf->getIndex());
encoder.writeSignedInteger(ATTRIB_DEPTH, depth);
encoder.writeUnsignedInteger(ATTRIB_TYPE, gototype);
encoder.closeElement(ELEM_TARGET);
}
}