diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/address.cc index cc56143bde..1cb02c5b2f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.cc @@ -64,12 +64,12 @@ void SeqNum::encode(Encoder &encoder) const encoder.closeElement(ELEM_SEQNUM); } -SeqNum SeqNum::decode(Decoder &decoder,const AddrSpaceManager *manage) +SeqNum SeqNum::decode(Decoder &decoder) { uintm uniq = ~((uintm)0); uint4 elemId = decoder.openElement(ELEM_SEQNUM); - Address pc = Address::decode(decoder,manage); // Recover address + Address pc = Address::decode(decoder); // Recover address for(;;) { uint4 attribId = decoder.getNextAttributeId(); if (attribId == 0) break; @@ -199,14 +199,13 @@ void Address::renormalize(int4 size) { /// or a \e name attribute can be used to recover an address /// based on a register name. /// \param decoder is the stream decoder -/// \param manage is the address space manager for the program /// \return the resulting Address -Address Address::decode(Decoder &decoder,const AddrSpaceManager *manage) +Address Address::decode(Decoder &decoder) { VarnodeData var; - var.decode(decoder,manage); + var.decode(decoder); return Address(var.space,var.offset); } @@ -220,15 +219,14 @@ Address Address::decode(Decoder &decoder,const AddrSpaceManager *manage) /// and size based on a register name. If a size is recovered /// it is stored in \e size reference. /// \param decoder is the stream decoder -/// \param manage is the address space manager for the program /// \param size is the reference to any recovered size /// \return the resulting Address -Address Address::decode(Decoder &decoder,const AddrSpaceManager *manage,int4 &size) +Address Address::decode(Decoder &decoder,int4 &size) { VarnodeData var; - var.decode(decoder,manage); + var.decode(decoder); size = var.size; return Address(var.space,var.offset); } @@ -293,7 +291,7 @@ void Range::encode(Encoder &encoder) const { encoder.openElement(ELEM_RANGE); - encoder.writeString(ATTRIB_SPACE, spc->getName()); + encoder.writeSpace(ATTRIB_SPACE, spc); encoder.writeUnsignedInteger(ATTRIB_FIRST, first); encoder.writeUnsignedInteger(ATTRIB_LAST, last); encoder.closeElement(ELEM_RANGE); @@ -301,21 +299,19 @@ void Range::encode(Encoder &encoder) const /// Reconstruct this object from a \ or \ element /// \param decoder is the stream decoder -/// \param manage is the space manager for recovering AddrSpace objects -void Range::decode(Decoder &decoder,const AddrSpaceManager *manage) +void Range::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(); if (elemId != ELEM_RANGE && elemId != ELEM_REGISTER) throw XmlError("Expecting or element"); - decodeFromAttributes(decoder,manage); + decodeFromAttributes(decoder); decoder.closeElement(elemId); } /// Reconstruct from attributes that may not be part of a \ element. /// \param decoder is the stream decoder -/// \param manage is the space manager for recovering AddrSpace objects -void Range::decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage) +void Range::decodeFromAttributes(Decoder &decoder) { spc = (AddrSpace *)0; @@ -326,10 +322,7 @@ void Range::decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage uint4 attribId = decoder.getNextAttributeId(); if (attribId == 0) break; if (attribId == ATTRIB_SPACE) { - string spcname = decoder.readString(); - spc = manage->getSpaceByName(spcname); - if (spc == (AddrSpace *)0) - throw LowlevelError("Undefined space: "+spcname); + spc = decoder.readSpace(); } else if (attribId == ATTRIB_FIRST) { first = decoder.readUnsignedInteger(); @@ -339,7 +332,7 @@ void Range::decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage seenLast = true; } else if (attribId == ATTRIB_NAME) { - const Translate *trans = manage->getDefaultCodeSpace()->getTrans(); + const Translate *trans = decoder.getAddrSpaceManager()->getDefaultCodeSpace()->getTrans(); const VarnodeData &point(trans->getRegister(decoder.readString())); spc = point.space; first = point.offset; @@ -620,14 +613,13 @@ void RangeList::encode(Encoder &encoder) const /// Recover each individual disjoint Range for \b this RangeList. /// \param decoder is the stream decoder -/// \param manage is manager for retrieving address spaces -void RangeList::decode(Decoder &decoder,const AddrSpaceManager *manage) +void RangeList::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_RANGELIST); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,manage); + range.decode(decoder); tree.insert(range); } decoder.closeElement(elemId); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh index c7a63ca952..ace26f1750 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/address.hh @@ -96,10 +96,10 @@ public: void encode(Encoder &encoder,int4 size) const; ///< Encode \b this and a size to a stream /// Restore an address from parsed XML - static Address decode(Decoder &decoder,const AddrSpaceManager *manage); + static Address decode(Decoder &decoder); /// Restore an address and size from parsed XML - static Address decode(Decoder &decoder,const AddrSpaceManager *manage,int4 &size); + static Address decode(Decoder &decoder,int4 &size); }; /// \brief A class for uniquely labelling and comparing PcodeOps @@ -158,7 +158,7 @@ public: void encode(Encoder &encoder) const; /// Decode a SeqNum from a stream - static SeqNum decode(Decoder &decoder,const AddrSpaceManager *manage); + static SeqNum decode(Decoder &decoder); /// Write out a SeqNum in human readable form to a stream friend ostream &operator<<(ostream &s,const SeqNum &sq); @@ -202,8 +202,8 @@ public: return (first < op2.first); } void printBounds(ostream &s) const; ///< Print \b this Range to a stream void encode(Encoder &encoder) const; ///< Encode \b this Range to a stream - void decode(Decoder &decoder,const AddrSpaceManager *manage); ///< Restore \b this from a stream - void decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage); ///< Read \b from attributes on another tag + void decode(Decoder &decoder); ///< Restore \b this from a stream + void decodeFromAttributes(Decoder &decoder); ///< Read \b from attributes on another tag }; /// \brief A partially parsed description of a Range @@ -247,7 +247,7 @@ public: uintb longestFit(const Address &addr,uintb maxsize) const; ///< Find size of biggest Range containing given address void printBounds(ostream &s) const; ///< Print a description of \b this RangeList to stream void encode(Encoder &encoder) const; ///< Encode \b this RangeList to a stream - void decode(Decoder &decoder,const AddrSpaceManager *manage); ///< Decode \b this RangeList from a \ element + void decode(Decoder &decoder); ///< Decode \b this RangeList from a \ element }; /// Precalculated masks indexed by size diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc index 4f5c57bd45..8f75e8fc5b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc @@ -409,13 +409,13 @@ void Architecture::setPrintLanguage(const string &nm) PrintLanguageCapability *capa = PrintLanguageCapability::findCapability(nm); if (capa == (PrintLanguageCapability *)0) throw LowlevelError("Unknown print language: "+nm); - bool printxml = print->emitsXml(); // Copy settings for current print language + bool printMarkup = print->emitsMarkup(); // Copy settings for current print language ostream *t = print->getOutputStream(); print = capa->buildLanguage(this); print->setOutputStream(t); // Restore settings from previous language print->initializeFromArchitecture(); - if (printxml) - print->setXML(true); + if (printMarkup) + print->setMarkup(true); printlist.push_back(print); print->adjustTypeOperators(); return; @@ -446,8 +446,8 @@ void Architecture::decodeFlowOverride(Decoder &decoder) uint4 subId = decoder.openElement(); if (subId != ELEM_FLOW) break; string flowType = decoder.readString(ATTRIB_TYPE); - Address funcaddr = Address::decode(decoder,this); - Address overaddr = Address::decode(decoder,this); + Address funcaddr = Address::decode(decoder); + Address overaddr = Address::decode(decoder); Funcdata *fd = symboltab->getGlobalScope()->queryFunction(funcaddr); if (fd != (Funcdata *)0) fd->getOverride().insertFlowOverride(overaddr,Override::stringToType(flowType)); @@ -482,7 +482,7 @@ void Architecture::restoreXml(DocumentStorage &store) const Element *el = store.getTag(ELEM_SAVE_STATE.getName()); if (el == (const Element *)0) throw LowlevelError("Could not find save_state tag"); - XmlDecode decoder(el); + XmlDecode decoder(this,el); uint4 elemId = decoder.openElement(ELEM_SAVE_STATE); loadersymbols_parsed = false; for(;;) { @@ -500,11 +500,11 @@ void Architecture::restoreXml(DocumentStorage &store) else if (subId == ELEM_DB) symboltab->decode(decoder); else if (subId == ELEM_CONTEXT_POINTS) - context->decode(decoder,this); + context->decode(decoder); else if (subId == ELEM_COMMENTDB) - commentdb->decode(decoder,this); + commentdb->decode(decoder); else if (subId == ELEM_STRINGMANAGE) - stringManager->decode(decoder,this); + stringManager->decode(decoder); else if (subId == ELEM_CONSTANTPOOL) cpool->decode(decoder,*types); else if (subId == ELEM_OPTIONSLIST) @@ -607,7 +607,7 @@ void Architecture::buildTypegrp(DocumentStorage &store) const Element *el = store.getTag("coretypes"); types = new TypeFactory(this); // Initialize the object if (el != (const Element *)0) { - XmlDecode decoder(el); + XmlDecode decoder(this,el); types->decodeCoreTypes(decoder); } else { @@ -929,7 +929,7 @@ void Architecture::decodeReadOnly(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_READONLY); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,this); + range.decode(decoder); symboltab->setPropertyRange(Varnode::readonly,range); } decoder.closeElement(elemId); @@ -945,7 +945,7 @@ void Architecture::decodeVolatile(Decoder &decoder) userops.decodeVolatile(decoder,this); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,this); // Tag itself is range + range.decode(decoder); // Tag itself is range symboltab->setPropertyRange(Varnode::volatil,range); } decoder.closeElement(elemId); @@ -962,7 +962,7 @@ void Architecture::decodeReturnAddress(Decoder &decoder) if (subId != 0) { if (defaultReturnAddr.space != (AddrSpace *)0) throw LowlevelError("Multiple tags in .cspec"); - defaultReturnAddr.decode(decoder,this); + defaultReturnAddr.decode(decoder); } decoder.closeElement(elemId); } @@ -976,7 +976,7 @@ void Architecture::decodeIncidentalCopy(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_INCIDENTALCOPY); while(decoder.peekElement() != 0) { VarnodeData vdata; - vdata.decode(decoder,this); + vdata.decode(decoder); Range range( vdata.space, vdata.offset, vdata.offset+vdata.size-1); symboltab->setPropertyRange(Varnode::incidental_copy,range); } @@ -994,7 +994,7 @@ void Architecture::decodeLaneSizes(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_REGISTER_DATA); while(decoder.peekElement() != 0) { - if (lanedRegister.decode(decoder, this)) { + if (lanedRegister.decode(decoder)) { int4 sizeIndex = lanedRegister.getWholeSize(); while (maskList.size() <= sizeIndex) maskList.push_back(0); @@ -1016,10 +1016,10 @@ void Architecture::decodeStackPointer(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_STACKPOINTER); - string spaceName; string registerName; bool stackGrowth = true; // Default stack growth is in negative direction bool isreversejustify = false; + AddrSpace *basespace = (AddrSpace *)0; for(;;) { uint4 attribId = decoder.getNextAttributeId(); if (attribId == 0) break; @@ -1028,14 +1028,13 @@ void Architecture::decodeStackPointer(Decoder &decoder) else if (attribId == ATTRIB_GROWTH) stackGrowth = decoder.readString() == "negative"; else if (attribId == ATTRIB_SPACE) - spaceName = decoder.readString(); + basespace = decoder.readSpace(); else if (attribId == ATTRIB_REGISTER) registerName = decoder.readString(); } - AddrSpace *basespace = getSpaceByName(spaceName); if (basespace == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+spaceName); + throw LowlevelError(ELEM_STACKPOINTER.getName() + " element missing \"space\" attribute"); VarnodeData point = translate->getRegister(registerName); decoder.closeElement(elemId); @@ -1056,10 +1055,7 @@ void Architecture::decodeDeadcodeDelay(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_DEADCODEDELAY); - string spaceName = decoder.readString(ATTRIB_SPACE); - AddrSpace *spc = getSpaceByName(spaceName); - if (spc == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+spaceName); + AddrSpace *spc = decoder.readSpace(ATTRIB_SPACE); int4 delay = decoder.readSignedInteger(ATTRIB_DELAY); if (delay >= 0) setDeadcodeDelay(spc,delay); @@ -1075,7 +1071,7 @@ void Architecture::decodeInferPtrBounds(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_INFERPTRBOUNDS); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,this); + range.decode(decoder); setInferPtrBounds(range); } decoder.closeElement(elemId); @@ -1113,12 +1109,9 @@ void Architecture::decodeSpacebase(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_SPACEBASE); string nameString = decoder.readString(ATTRIB_NAME); string registerName = decoder.readString(ATTRIB_REGISTER); - string spaceName = decoder.readString(ATTRIB_SPACE); + AddrSpace *basespace = decoder.readSpace(ATTRIB_SPACE); decoder.closeElement(elemId); const VarnodeData &point(translate->getRegister(registerName)); - AddrSpace *basespace = getSpaceByName(spaceName); - if (basespace == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+spaceName); addSpacebase(basespace,nameString,point,point.size,false,false); } @@ -1131,7 +1124,7 @@ void Architecture::decodeNoHighPtr(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_NOHIGHPTR); while(decoder.peekElement() != 0) { // Iterate over every range tag in the list Range range; - range.decode(decoder,this); + range.decode(decoder); addNoHighPtr(range); } decoder.closeElement(elemId); @@ -1151,7 +1144,7 @@ void Architecture::decodePreferSplit(Decoder &decoder) while(decoder.peekElement() != 0) { splitrecords.emplace_back(); PreferSplitRecord &record( splitrecords.back() ); - record.storage.decode( decoder, this ); + record.storage.decode( decoder ); record.splitoffset = record.storage.size/2; } decoder.closeElement(elemId); @@ -1203,7 +1196,7 @@ void Architecture::parseProcessorConfig(DocumentStorage &store) const Element *el = store.getTag("processor_spec"); if (el == (const Element *)0) throw LowlevelError("No processor configuration tag found"); - XmlDecode decoder(el); + XmlDecode decoder(this,el); uint4 elemId = decoder.openElement(ELEM_PROCESSOR_SPEC); for(;;) { @@ -1218,7 +1211,7 @@ void Architecture::parseProcessorConfig(DocumentStorage &store) else if (subId == ELEM_INCIDENTALCOPY) decodeIncidentalCopy(decoder); else if (subId == ELEM_CONTEXT_DATA) - context->decodeFromSpec(decoder,this); + context->decodeFromSpec(decoder); else if (subId == ELEM_JUMPASSIST) userops.decodeJumpAssist(decoder, this); else if (subId == ELEM_SEGMENTOP) @@ -1228,11 +1221,8 @@ void Architecture::parseProcessorConfig(DocumentStorage &store) } else if (subId == ELEM_DATA_SPACE) { uint4 elemId = decoder.openElement(); - string spaceName = decoder.readString(ATTRIB_SPACE); + AddrSpace *spc = decoder.readSpace(ATTRIB_SPACE); decoder.closeElement(elemId); - AddrSpace *spc = getSpaceByName(spaceName); - if (spc == (AddrSpace *)0) - throw LowlevelError("Undefined space: "+spaceName); setDefaultDataSpace(spc->getIndex()); } else if (subId == ELEM_INFERPTRBOUNDS) { @@ -1273,7 +1263,7 @@ void Architecture::parseCompilerConfig(DocumentStorage &store) const Element *el = store.getTag("compiler_spec"); if (el == (const Element *)0) throw LowlevelError("No compiler configuration tag found"); - XmlDecode decoder(el); + XmlDecode decoder(this,el); uint4 elemId = decoder.openElement(ELEM_COMPILER_SPEC); for(;;) { @@ -1306,7 +1296,7 @@ void Architecture::parseCompilerConfig(DocumentStorage &store) else if (subId == ELEM_READONLY) decodeReadOnly(decoder); else if (subId == ELEM_CONTEXT_DATA) - context->decodeFromSpec(decoder,this); + context->decodeFromSpec(decoder); else if (subId == ELEM_RESOLVEPROTOTYPE) decodeProto(decoder); else if (subId == ELEM_EVAL_CALLED_PROTOTYPE) @@ -1337,7 +1327,7 @@ void Architecture::parseCompilerConfig(DocumentStorage &store) el = store.getTag("specextensions"); // Look for any user-defined configuration document if (el != (const Element *)0) { - XmlDecode decoderExt(el); + XmlDecode decoderExt(this,el); elemId = decoderExt.openElement(ELEM_SPECEXTENSIONS); for(;;) { uint4 subId = decoderExt.peekElement(); @@ -1388,7 +1378,7 @@ void Architecture::parseExtraRules(DocumentStorage &store) { const Element *expertag = store.getTag("experimental_rules"); if (expertag != (const Element *)0) { - XmlDecode decoder(expertag); + XmlDecode decoder(this,expertag); uint4 elemId = decoder.openElement(ELEM_EXPERIMENTAL_RULES); while(decoder.peekElement() != 0) decodeDynamicRule( decoder ); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc index 3f072e85b4..2d6e823bad 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/block.cc @@ -1324,10 +1324,10 @@ void BlockGraph::encodeBody(Encoder &encoder) const list[i]->encode(encoder); } -void BlockGraph::decodeBody(Decoder &decoder,BlockMap &resolver) +void BlockGraph::decodeBody(Decoder &decoder) { - BlockMap newresolver(resolver); + BlockMap newresolver; vector tmplist; for(;;) { @@ -1352,11 +1352,10 @@ void BlockGraph::decodeBody(Decoder &decoder,BlockMap &resolver) /// Parse a \ 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::decode(Decoder &decoder,const AddrSpaceManager *m) +void BlockGraph::decode(Decoder &decoder) { - BlockMap resolver(m); + BlockMap resolver; FlowBlock::decode(decoder,resolver); // Restore goto references here } @@ -2417,7 +2416,7 @@ void FlowBlock::decode(Decoder &decoder,BlockMap &resolver) { uint4 elemId = decoder.openElement(ELEM_BLOCK); decodeHeader(decoder); - decodeBody(decoder,resolver); + decodeBody(decoder); decodeEdges(decoder,resolver); decoder.closeElement(elemId); } @@ -2562,10 +2561,10 @@ void BlockBasic::encodeBody(Encoder &encoder) const cover.encode(encoder); } -void BlockBasic::decodeBody(Decoder &decoder,BlockMap &resolver) +void BlockBasic::decodeBody(Decoder &decoder) { - cover.decode(decoder, resolver.getAddressManager()); + cover.decode(decoder); } void BlockBasic::printHeader(ostream &s) const @@ -3440,12 +3439,6 @@ FlowBlock *BlockSwitch::nextFlowAfter(const FlowBlock *bl) const return getParent()->nextFlowAfter(this); } -BlockMap::BlockMap(const BlockMap &op2) - -{ - manage = op2.manage; -} - /// \param bt is the block_type /// \return a new instance of the specialized FlowBlock FlowBlock *BlockMap::resolveBlock(FlowBlock::block_type bt) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/block.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/block.hh index 72dc9d81ee..556789694e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/block.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/block.hh @@ -190,8 +190,7 @@ public: /// \brief Restore details about \b this FlowBlock from an element stream /// /// \param decoder is the stream decoder - /// \param resolver is used to recover FlowBlock objects based on elment references - virtual void decodeBody(Decoder &decoder,BlockMap &resolver) {} + virtual void decodeBody(Decoder &decoder) {} void encodeEdges(Encoder &encoder) const; ///< Encode edge information to a stream void decodeEdges(Decoder &decoder,BlockMap &resolver); void encode(Encoder &encoder) const; ///< Encode \b this to a stream @@ -310,8 +309,8 @@ public: virtual void finalTransform(Funcdata &data); virtual void finalizePrinting(Funcdata &data) const; virtual void encodeBody(Encoder &encoder) const; - virtual void decodeBody(Decoder &decoder,BlockMap &resolver); - void decode(Decoder &decoder,const AddrSpaceManager *m); ///< Restore \b this BlockGraph from an XML stream + virtual void decodeBody(Decoder &decoder); + void decode(Decoder &decoder); ///< Decode \b this BlockGraph from a stream void addEdge(FlowBlock *begin,FlowBlock *end); ///< Add a directed edge between component FlowBlocks void addLoopEdge(FlowBlock *begin,int4 outindex); ///< Mark a given edge as a \e loop edge void removeEdge(FlowBlock *begin,FlowBlock *end); ///< Remove an edge between component FlowBlocks @@ -394,7 +393,7 @@ public: virtual block_type getType(void) const { return t_basic; } virtual FlowBlock *subBlock(int4 i) const { return (FlowBlock *)0; } virtual void encodeBody(Encoder &encoder) const; - virtual void decodeBody(Decoder &decoder,BlockMap &resolver); + virtual void decodeBody(Decoder &decoder); virtual void printHeader(ostream &s) const; virtual void printRaw(ostream &s) const; virtual void emit(PrintLanguage *lng) const { lng->emitBlockBasic(this); } @@ -713,14 +712,10 @@ public: /// list of FlowBlock objects sorted by index and then looks up the FlowBlock matching a given /// index as edges specify them. class BlockMap { - const AddrSpaceManager *manage; ///< Address space manager used to decode FlowBlock address ranges vector sortlist; ///< The list of deserialized FlowBlock objects FlowBlock *resolveBlock(FlowBlock::block_type bt); ///< Construct a FlowBlock of the given type static FlowBlock *findBlock(const vector &list,int4 ind); ///< Locate a FlowBlock with a given index public: - BlockMap(const AddrSpaceManager *m) { manage = m; } ///< Construct given an address space manager - BlockMap(const BlockMap &op2); ///< Copy constructor - const AddrSpaceManager *getAddressManager(void) const { return manage; } ///< Get the address space manager void sortList(void); ///< Sort the list of FlowBlock objects /// \brief Find the FlowBlock matching the given index diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.cc index bc310d4801..2dd84a5b7b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.cc @@ -33,12 +33,11 @@ void CallGraphEdge::decode(Decoder &decoder,CallGraph *graph) { uint4 elemId = decoder.openElement(ELEM_EDGE); - const AddrSpaceManager *manage = graph->getArch(); Address fromaddr,toaddr,siteaddr; - fromaddr = Address::decode(decoder,manage); - toaddr = Address::decode(decoder,manage); - siteaddr = Address::decode(decoder,manage); + fromaddr = Address::decode(decoder); + toaddr = Address::decode(decoder); + siteaddr = Address::decode(decoder); decoder.closeElement(elemId); CallGraphNode *fromnode = graph->findNode(fromaddr); @@ -83,7 +82,7 @@ void CallGraphNode::decode(Decoder &decoder,CallGraph *graph) if (attribId == ATTRIB_NAME) name = decoder.readString(); } - Address addr = Address::decode(decoder,graph->getArch()); + Address addr = Address::decode(decoder); decoder.closeElement(elemId); graph->addNode(addr,name); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.hh index 1fc0cc3cac..f8419f15aa 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/callgraph.hh @@ -107,7 +107,6 @@ class CallGraph { void iterateFunctionsAddrOrder(Scope *scope); public: CallGraph(Architecture *g) { glb = g; } - Architecture *getArch(void) const { return glb; } CallGraphNode *addNode(Funcdata *f); CallGraphNode *addNode(const Address &addr,const string &nm); CallGraphNode *findNode(const Address &addr); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/comment.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/comment.cc index 07eff2f4f8..14754a3eb6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/comment.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/comment.cc @@ -52,16 +52,15 @@ void Comment::encode(Encoder &encoder) const /// Parse a \ element from the given stream decoder /// \param decoder is the given stream decoder -/// \param manage is a manager for resolving address space references -void Comment::decode(Decoder &decoder,const AddrSpaceManager *manage) +void Comment::decode(Decoder &decoder) { emitted = false; type = 0; uint4 elemId = decoder.openElement(ELEM_COMMENT); type = Comment::encodeCommentType(decoder.readString(ATTRIB_TYPE)); - funcaddr = Address::decode(decoder,manage); - addr = Address::decode(decoder,manage); + funcaddr = Address::decode(decoder); + addr = Address::decode(decoder); uint4 subId = decoder.peekElement(); if (subId != 0) { decoder.openElement(); @@ -249,13 +248,13 @@ void CommentDatabaseInternal::encode(Encoder &encoder) const encoder.closeElement(ELEM_COMMENTDB); } -void CommentDatabaseInternal::decode(Decoder &decoder,const AddrSpaceManager *manage) +void CommentDatabaseInternal::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_COMMENTDB); while(decoder.peekElement() != 0) { Comment com; - com.decode(decoder,manage); + com.decode(decoder); addComment(com.getType(),com.getFuncAddr(),com.getAddr(),com.getText()); } decoder.closeElement(elemId); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/comment.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/comment.hh index d9c0b2e43e..b2be60f0fc 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/comment.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/comment.hh @@ -66,7 +66,7 @@ public: int4 getUniq(void) const { return uniq; } ///< Get the sub-sorting index const string &getText(void) const { return text; } ///< Get the body of the comment void encode(Encoder &encoder) const; ///< Encode the comment to a stream - void decode(Decoder &decoder,const AddrSpaceManager *manage); ///< Restore the comment from XML + void decode(Decoder &decoder); ///< Restore the comment from XML static uint4 encodeCommentType(const string &name); ///< Convert name string to comment property static string decodeCommentType(uint4 val); ///< Convert comment property to string }; @@ -147,8 +147,7 @@ public: /// \brief Restore all comments from a \ element /// /// \param decoder is the stream decoder - /// \param manage is a manager for resolving address space references - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage)=0; + virtual void decode(Decoder &decoder)=0; }; @@ -171,7 +170,7 @@ public: virtual CommentSet::const_iterator beginComment(const Address &fad) const; virtual CommentSet::const_iterator endComment(const Address &fad) const; virtual void encode(Encoder &encoder) const; - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage); + virtual void decode(Decoder &decoder); }; /// \brief A class for sorting comments into and within basic blocks diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.cc index 7e10e12724..3df7705f87 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.cc @@ -40,9 +40,9 @@ void CommentDatabaseGhidra::fillCache(const Address &fad) const iter = cache.beginComment(fad); iterend = cache.endComment(fad); - XmlDecode decoder; + XmlDecode decoder(ghidra); if (ghidra->getComments(fad,commentfilter,decoder)) { - cache.decode(decoder,ghidra); + cache.decode(decoder); } } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.hh index 12183225ea..c0dc59c890 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/comment_ghidra.hh @@ -47,7 +47,7 @@ public: virtual CommentSet::const_iterator endComment(const Address &fad) const; virtual void encode(Encoder &encoder) const { throw LowlevelError("commentdb::encode unimplemented"); } - virtual void decode(Decoder &decoder,const AddrSpaceManager *trans) { + virtual void decode(Decoder &decoder) { throw LowlevelError("CommentDatabaseGhidra::decode unimplemented"); } }; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/cpool_ghidra.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/cpool_ghidra.cc index e57c070796..f8a82d2f7e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/cpool_ghidra.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/cpool_ghidra.cc @@ -32,7 +32,7 @@ const CPoolRecord *ConstantPoolGhidra::getRecord(const vector &refs) cons { const CPoolRecord *rec = cache.getRecord(refs); if (rec == (const CPoolRecord *)0) { - XmlDecode decoder; + XmlDecode decoder(ghidra); bool success; try { success = ghidra->getCPoolRef(refs,decoder); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/database.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/database.cc index 2a7a6dfb8a..c63556de9c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/database.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/database.cc @@ -211,9 +211,8 @@ void SymbolEntry::encode(Encoder &encoder) const /// if the symbol is dynamic. Then parse the \b uselimit describing the valid /// range of code addresses. /// \param decoder is the stream decoder -/// \param manage is an address space manager for constructing Address objects /// \return the advanced iterator -void SymbolEntry::decode(Decoder &decoder,const AddrSpaceManager *manage) +void SymbolEntry::decode(Decoder &decoder) { uint4 elemId = decoder.peekElement(); @@ -224,10 +223,10 @@ void SymbolEntry::decode(Decoder &decoder,const AddrSpaceManager *manage) decoder.closeElement(elemId); } else { - addr = Address::decode(decoder,manage); + addr = Address::decode(decoder); hash = 0; } - uselimit.decode(decoder,manage); + uselimit.decode(decoder); } /// Examine the data-type to decide if the Symbol has the special property @@ -809,7 +808,7 @@ void ExternRefSymbol::decode(Decoder &decoder) if (attribId == ATTRIB_NAME) // Unless we see it explicitly name = decoder.readString(); } - refaddr = Address::decode(decoder,scope->getArch()); + refaddr = Address::decode(decoder); decoder.closeElement(elemId); buildNameType(); } @@ -1583,7 +1582,7 @@ Symbol *Scope::addMapSym(Decoder &decoder) addSymbolInternal(sym); // This routine may throw, but it will delete sym in this case while(decoder.peekElement() != 0) { SymbolEntry entry(sym); - entry.decode(decoder,glb); + entry.decode(decoder); if (entry.isInvalid()) { glb->printMessage("WARNING: Throwing out symbol with invalid mapping: "+sym->getName()); removeSymbol(sym); @@ -2632,7 +2631,7 @@ void ScopeInternal::decodeHole(Decoder &decoder) uint4 elemId = decoder.openElement(ELEM_HOLE); uint4 flags = 0; Range range; - range.decodeFromAttributes(decoder, glb); + range.decodeFromAttributes(decoder); decoder.rewindAttributes(); for(;;) { uint4 attribId = decoder.getNextAttributeId(); @@ -2717,7 +2716,7 @@ void ScopeInternal::decode(Decoder &decoder) } if (subId== ELEM_RANGELIST) { RangeList newrangetree; - newrangetree.decode(decoder,glb); + newrangetree.decode(decoder); glb->symboltab->setRange(this,newrangetree); } else if (subId == ELEM_RANGEEQUALSSYMBOLS) { @@ -3262,7 +3261,7 @@ void Database::decode(Decoder &decoder) decoder.openElement(); uint4 val = decoder.readUnsignedInteger(ATTRIB_VAL); VarnodeData vData; - vData.decodeFromAttributes(decoder, glb); + vData.decodeFromAttributes(decoder); Address addr = vData.getAddr(); decoder.closeElement(subId); flagbase.split(addr) = val; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/database.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/database.hh index a47b6219ea..df0dfdec00 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/database.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/database.hh @@ -157,7 +157,7 @@ public: Datatype *getSizedType(const Address &addr,int4 sz) const; ///< Get the data-type associated with (a piece of) \b this void printEntry(ostream &s) const; ///< Dump a description of \b this to a stream void encode(Encoder &encoder) const; ///< Encode \b this to a stream - void decode(Decoder &decoder,const AddrSpaceManager *manage); ///< Decode \b this from a stream + void decode(Decoder &decoder); ///< Decode \b this from a stream }; typedef rangemap EntryMap; ///< A rangemap of SymbolEntry diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/database_ghidra.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/database_ghidra.cc index d6c8a6f8d5..e55c936f29 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/database_ghidra.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/database_ghidra.cc @@ -52,7 +52,7 @@ Scope *ScopeGhidra::reresolveScope(uint8 id) const if (cacheScope != (Scope *)0) return cacheScope; // Scope was previously cached - XmlDecode decoder; + XmlDecode decoder(ghidra); if (!ghidra->getNamespacePath(id,decoder)) throw LowlevelError("Could not get namespace info"); @@ -85,7 +85,7 @@ void ScopeGhidra::decodeHole(Decoder &decoder) const uint4 elemId = decoder.openElement(ELEM_HOLE); uint4 flags = 0; Range range; - range.decodeFromAttributes(decoder,ghidra); + range.decodeFromAttributes(decoder); decoder.rewindAttributes(); for(;;) { uint4 attribId = decoder.getNextAttributeId(); @@ -212,7 +212,7 @@ Symbol *ScopeGhidra::removeQuery(const Address &addr) const // Have we queried this address before if (holes.inRange(addr,1)) return (Symbol *)0; - XmlDecode decoder; + XmlDecode decoder(ghidra); if (ghidra->getMappedSymbolsXML(addr,decoder)) { // Query GHIDRA about this address sym = dump2Cache(decoder); // Add it to the cache } @@ -350,7 +350,7 @@ Funcdata *ScopeGhidra::resolveExternalRefFunction(ExternRefSymbol *sym) const // If the function isn't in cache, we use the special // getExternalRefXML interface to recover the external function SymbolEntry *entry = sym->getFirstWholeMap(); - XmlDecode decoder; + XmlDecode decoder(ghidra); if (ghidra->getExternalRefXML(entry->getAddr(),decoder)) { FunctionSymbol *funcSym; // Make sure referenced function is cached diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc index 0ee8c6c265..528fce09ab 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc @@ -445,11 +445,10 @@ Address ParamEntry::getAddrBySlot(int4 &slotnum,int4 sz) const /// \brief Decode a \ element into \b this object /// /// \param decoder is the stream decoder -/// \param manage is a manager to resolve address space references /// \param normalstack is \b true if the parameters should be allocated from the front of the range /// \param grouped is \b true if \b this will be grouped with other entries /// \param curList is the list of ParamEntry defined up to this point -void ParamEntry::decode(Decoder &decoder,const AddrSpaceManager *manage,bool normalstack,bool grouped,list &curList) +void ParamEntry::decode(Decoder &decoder,bool normalstack,bool grouped,list &curList) { flags = 0; @@ -499,7 +498,7 @@ void ParamEntry::decode(Decoder &decoder,const AddrSpaceManager *manage,bool nor if (alignment == size) alignment = 0; Address addr; - addr = Address::decode(decoder,manage); + addr = Address::decode(decoder); decoder.closeElement(elemId); spaceid = addr.getSpace(); addressbase = addr.getOffset(); @@ -1107,18 +1106,17 @@ void ParamListStandard::populateResolver(void) /// \brief Parse a \ element and add it to \b this list /// /// \param decoder is the stream decoder -/// \param manage is manager for parsing address spaces /// \param effectlist holds any passed back effect records /// \param groupid is the group to which the new ParamEntry is assigned /// \param normalstack is \b true if the parameters should be allocated from the front of the range /// \param autokill is \b true if parameters are automatically added to the killedbycall list /// \param splitFloat is \b true if floating-point parameters are in their own resource section /// \param grouped is \b true if the new ParamEntry is grouped with other entries -void ParamListStandard::parsePentry(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist, +void ParamListStandard::parsePentry(Decoder &decoder,vector &effectlist, int4 groupid,bool normalstack,bool autokill,bool splitFloat,bool grouped) { entry.emplace_back(groupid); - entry.back().decode(decoder,manage,normalstack,grouped,entry); + entry.back().decode(decoder,normalstack,grouped,entry); if (splitFloat) { if (!grouped && entry.back().getType() == TYPE_FLOAT) { if (resourceTwoStart >= 0) @@ -1142,13 +1140,12 @@ void ParamListStandard::parsePentry(Decoder &decoder,const AddrSpaceManager *man /// /// All ParamEntry objects will share the same \b group id. /// \param decoder is the stream decoder -/// \param manage is manager for parsing address spaces /// \param effectlist holds any passed back effect records /// \param groupid is the group to which all ParamEntry elements are assigned /// \param normalstack is \b true if the parameters should be allocated from the front of the range /// \param autokill is \b true if parameters are automatically added to the killedbycall list /// \param splitFloat is \b true if floating-point parameters are in their own resource section -void ParamListStandard::parseGroup(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist, +void ParamListStandard::parseGroup(Decoder &decoder,vector &effectlist, int4 groupid,bool normalstack,bool autokill,bool splitFloat) { int4 basegroup = numgroup; @@ -1156,7 +1153,7 @@ void ParamListStandard::parseGroup(Decoder &decoder,const AddrSpaceManager *mana ParamEntry *previous2 = (ParamEntry *)0; uint4 elemId = decoder.openElement(ELEM_GROUP); while(decoder.peekElement() != 0) { - parsePentry(decoder, manage, effectlist, basegroup, normalstack, autokill, splitFloat, true); + parsePentry(decoder, effectlist, basegroup, normalstack, autokill, splitFloat, true); ParamEntry &pentry( entry.back() ); if (pentry.getSpace()->getType() == IPTR_JOIN) throw LowlevelError(" in the join space not allowed in tag"); @@ -1330,8 +1327,7 @@ void ParamListStandard::getRangeList(AddrSpace *spc,RangeList &res) const } } -void ParamListStandard::decode(Decoder &decoder,const AddrSpaceManager *manage, - vector &effectlist,bool normalstack) +void ParamListStandard::decode(Decoder &decoder,vector &effectlist,bool normalstack) { numgroup = 0; @@ -1362,10 +1358,10 @@ void ParamListStandard::decode(Decoder &decoder,const AddrSpaceManager *manage, uint4 subId = decoder.peekElement(); if (subId == 0) break; if (subId == ELEM_PENTRY) { - parsePentry(decoder, manage, effectlist, numgroup, normalstack, autokilledbycall, splitFloat, false); + parsePentry(decoder, effectlist, numgroup, normalstack, autokilledbycall, splitFloat, false); } else if (subId == ELEM_GROUP) { - parseGroup(decoder, manage, effectlist, numgroup, normalstack, autokilledbycall, splitFloat); + parseGroup(decoder, effectlist, numgroup, normalstack, autokilledbycall, splitFloat); } } decoder.closeElement(elemId); @@ -1552,10 +1548,10 @@ void ParamListStandardOut::assignMap(const vector &proto,TypeFactory } } -void ParamListStandardOut::decode(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist,bool normalstack) +void ParamListStandardOut::decode(Decoder &decoder,vector &effectlist,bool normalstack) { - ParamListRegisterOut::decode(decoder,manage,effectlist,normalstack); + ParamListRegisterOut::decode(decoder,effectlist,normalstack); // Check for double precision entries list::iterator iter; ParamEntry *previous1 = (ParamEntry *)0; @@ -1901,7 +1897,7 @@ void FspecSpace::encodeAttributes(Encoder &encoder,uintb offset) const encoder.writeString(ATTRIB_SPACE, "fspec"); else { AddrSpace *id = fc->getEntryAddress().getSpace(); - encoder.writeString(ATTRIB_SPACE, id->getName()); + encoder.writeSpace(ATTRIB_SPACE, id); encoder.writeUnsignedInteger(ATTRIB_OFFSET, fc->getEntryAddress().getOffset()); } } @@ -1915,7 +1911,7 @@ void FspecSpace::encodeAttributes(Encoder &encoder,uintb offset,int4 size) const encoder.writeString(ATTRIB_SPACE, "fspec"); else { AddrSpace *id = fc->getEntryAddress().getSpace(); - encoder.writeString(ATTRIB_SPACE, id->getName()); + encoder.writeSpace(ATTRIB_SPACE, id); encoder.writeUnsignedInteger(ATTRIB_OFFSET, fc->getEntryAddress().getOffset()); encoder.writeSignedInteger(ATTRIB_SIZE, size); } @@ -1993,12 +1989,11 @@ void EffectRecord::encode(Encoder &encoder) const /// Parse an \ element to get the memory range. The effect type is inherited from the parent. /// \param grouptype is the effect inherited from the parent /// \param decoder is the stream decoder -/// \param manage is a manager to resolve address space references -void EffectRecord::decode(uint4 grouptype,Decoder &decoder,const AddrSpaceManager *manage) +void EffectRecord::decode(uint4 grouptype,Decoder &decoder) { type = grouptype; - range.decode(decoder,manage); + range.decode(decoder); } void ProtoModel::defaultLocalRange(void) @@ -2333,7 +2328,7 @@ void ProtoModel::decode(Decoder &decoder) uint4 subId = decoder.peekElement(); if (subId == 0) break; if (subId == ELEM_INPUT) { - input->decode(decoder,glb,effectlist,stackgrowsnegative); + input->decode(decoder,effectlist,stackgrowsnegative); if (stackspc != (AddrSpace *)0) { input->getRangeList(stackspc,paramrange); if (!paramrange.empty()) @@ -2341,13 +2336,13 @@ void ProtoModel::decode(Decoder &decoder) } } else if (subId == ELEM_OUTPUT) { - output->decode(decoder,glb,effectlist,stackgrowsnegative); + output->decode(decoder,effectlist,stackgrowsnegative); } else if (subId == ELEM_UNAFFECTED) { decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::unaffected,decoder,glb); + effectlist.back().decode(EffectRecord::unaffected,decoder); } decoder.closeElement(subId); } @@ -2355,7 +2350,7 @@ void ProtoModel::decode(Decoder &decoder) decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::killedbycall,decoder,glb); + effectlist.back().decode(EffectRecord::killedbycall,decoder); } decoder.closeElement(subId); } @@ -2363,7 +2358,7 @@ void ProtoModel::decode(Decoder &decoder) decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::return_address,decoder,glb); + effectlist.back().decode(EffectRecord::return_address,decoder); } decoder.closeElement(subId); sawretaddr = true; @@ -2373,7 +2368,7 @@ void ProtoModel::decode(Decoder &decoder) decoder.openElement(); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,glb); + range.decode(decoder); localrange.insertRange(range.getSpace(),range.getFirst(),range.getLast()); } decoder.closeElement(subId); @@ -2383,7 +2378,7 @@ void ProtoModel::decode(Decoder &decoder) decoder.openElement(); while(decoder.peekElement() != 0) { Range range; - range.decode(decoder,glb); + range.decode(decoder); paramrange.insertRange(range.getSpace(),range.getFirst(),range.getLast()); } decoder.closeElement(subId); @@ -2392,13 +2387,13 @@ void ProtoModel::decode(Decoder &decoder) decoder.openElement(); while(decoder.peekElement() != 0) { likelytrash.emplace_back(); - likelytrash.back().decode(decoder,glb); + likelytrash.back().decode(decoder); } decoder.closeElement(subId); } else if (subId == ELEM_PCODE) { int4 injectId = glb->pcodeinjectlib->decodeInject("Protomodel : "+name, name, - InjectPayload::CALLMECHANISM_TYPE,decoder); + InjectPayload::CALLMECHANISM_TYPE,decoder); InjectPayload *payload = glb->pcodeinjectlib->getPayload(injectId); if (payload->getName().find("uponentry") != string::npos) injectUponEntry = injectId; @@ -3219,7 +3214,7 @@ void ProtoStoreInternal::decode(Decoder &decoder,ProtoModel *model) namelist.push_back(name); pieces.emplace_back(); ParameterPieces &curparam( pieces.back() ); - curparam.addr = Address::decode(decoder,glb); + curparam.addr = Address::decode(decoder); curparam.type = glb->types->decodeType(decoder); curparam.flags = flags; if (curparam.addr.isInvalid()) @@ -4422,14 +4417,14 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb) outputlock = decoder.readBool(); } int4 tmpsize; - outpieces.addr = Address::decode(decoder,glb,tmpsize); + outpieces.addr = Address::decode(decoder,tmpsize); outpieces.type = glb->types->decodeType(decoder); outpieces.flags = 0; decoder.closeElement(subId); } else if (subId == ELEM_ADDR) { // Old-style specification of return (supported partially for backward compat) int4 tmpsize; - outpieces.addr = Address::decode(decoder,glb,tmpsize); + outpieces.addr = Address::decode(decoder,tmpsize); outpieces.type = glb->types->decodeType(decoder); outpieces.flags = 0; } @@ -4452,7 +4447,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb) decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::unaffected,decoder,glb); + effectlist.back().decode(EffectRecord::unaffected,decoder); } decoder.closeElement(subId); } @@ -4460,7 +4455,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb) decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::killedbycall,decoder,glb); + effectlist.back().decode(EffectRecord::killedbycall,decoder); } decoder.closeElement(subId); } @@ -4468,7 +4463,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb) decoder.openElement(); while(decoder.peekElement() != 0) { effectlist.emplace_back(); - effectlist.back().decode(EffectRecord::return_address,decoder,glb); + effectlist.back().decode(EffectRecord::return_address,decoder); } decoder.closeElement(subId); } @@ -4476,7 +4471,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb) decoder.openElement(); while(decoder.peekElement() != 0) { likelytrash.emplace_back(); - likelytrash.back().decode(decoder,glb); + likelytrash.back().decode(decoder); } decoder.closeElement(subId); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh index d46535dab8..9368572a18 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh @@ -140,7 +140,7 @@ public: AddrSpace *getSpace(void) const { return spaceid; } ///< Get the address space containing \b this entry uintb getBase(void) const { return addressbase; } ///< Get the starting offset of \b this entry Address getAddrBySlot(int4 &slot,int4 sz) const; - void decode(Decoder &decoder,const AddrSpaceManager *manage,bool normalstack,bool grouped,list &curList); + void decode(Decoder &decoder,bool normalstack,bool grouped,list &curList); bool isParamCheckHigh(void) const { return ((flags & extracheck_high)!=0); } ///< Return \b true if there is a high overlap bool isParamCheckLow(void) const { return ((flags & extracheck_low)!=0); } ///< Return \b true if there is a low overlap static void orderWithinGroup(const ParamEntry &entry1,const ParamEntry &entry2); ///< Enforce ParamEntry group ordering rules @@ -385,7 +385,7 @@ public: bool operator==(const EffectRecord &op2) const; ///< Equality operator bool operator!=(const EffectRecord &op2) const; ///< Inequality operator void encode(Encoder &encoder) const; ///< Encode the record to a stream - void decode(uint4 grouptype,Decoder &decoder,const AddrSpaceManager *manage); ///< Decode the record from a stream + void decode(uint4 grouptype,Decoder &decoder); ///< Decode the record from a stream static bool compareByAddress(const EffectRecord &op1,const EffectRecord &op2); }; @@ -531,10 +531,9 @@ public: /// \brief Restore the model from an \ or \ element in the stream /// /// \param decoder is the stream decoder - /// \param manage is used to resolve references to address spaces /// \param effectlist is a container collecting EffectRecords across all parameters /// \param normalstack is \b true if parameters are pushed on the stack in the normal order - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist,bool normalstack)=0; + virtual void decode(Decoder &decoder,vector &effectlist,bool normalstack)=0; virtual ParamList *clone(void) const=0; ///< Clone this parameter list model }; @@ -571,9 +570,9 @@ protected: void calcDelay(void); ///< Calculate the maximum heritage delay for any potential parameter in this list void addResolverRange(AddrSpace *spc,uintb first,uintb last,ParamEntry *paramEntry,int4 position); void populateResolver(void); ///< Build the ParamEntry resolver maps - void parsePentry(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist, + void parsePentry(Decoder &decoder,vector &effectlist, int4 groupid,bool normalstack,bool autokill,bool splitFloat,bool grouped); - void parseGroup(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist, + void parseGroup(Decoder &decoder,vector &effectlist, int4 groupid,bool normalstack,bool autokill,bool splitFloat); public: ParamListStandard(void) {} ///< Construct for use with decode() @@ -594,7 +593,7 @@ public: virtual AddrSpace *getSpacebase(void) const { return spacebase; } virtual void getRangeList(AddrSpace *spc,RangeList &res) const; virtual int4 getMaxDelay(void) const { return maxdelay; } - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist,bool normalstack); + virtual void decode(Decoder &decoder,vector &effectlist,bool normalstack); virtual ParamList *clone(void) const; }; @@ -646,7 +645,7 @@ public: ParamListStandardOut(const ParamListStandardOut &op2) : ParamListRegisterOut(op2) {} ///< Copy constructor virtual uint4 getType(void) const { return p_standard_out; } virtual void assignMap(const vector &proto,TypeFactory &typefactory,vector &res) const; - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage,vector &effectlist,bool normalstack); + virtual void decode(Decoder &decoder,vector &effectlist,bool normalstack); virtual ParamList *clone(void) const; }; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index c266c34071..13dbbc7cf1 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -735,7 +735,7 @@ uint8 Funcdata::decode(Decoder &decoder) throw LowlevelError("Missing function name"); if (size == -1) throw LowlevelError("Missing function size"); - baseaddr = Address::decode( decoder, glb ); + baseaddr = Address::decode( decoder ); for(;;) { uint4 subId = decoder.peekElement(); if (subId == 0) break; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc index 9353ae8f45..2356581ace 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc @@ -343,7 +343,7 @@ void ArchitectureGhidra::buildTypegrp(DocumentStorage &store) const Element *el = store.getTag("coretypes"); types = new TypeFactoryGhidra(this); if (el != (const Element *)0) { - XmlDecode decoder(el); + XmlDecode decoder(this,el); types->decodeCoreTypes(decoder); } else { @@ -864,7 +864,7 @@ ArchitectureGhidra::ArchitectureGhidra(const string &pspec,const string &cspec,c : Architecture(), sin(i), sout(o), encoder(sout) { - print->setXML(true); + print->setMarkup(true); print->setOutputStream(&sout); pspecxml = pspec; cspecxml = cspec; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.cc index 57704c8107..4aba8fe4d8 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.cc @@ -19,22 +19,22 @@ const TrackedSet &ContextGhidra::getTrackedSet(const Address &addr) const { cache.clear(); - XmlDecode decoder; - ((ArchitectureGhidra *)glb)->getTrackedRegisters(addr,decoder); + XmlDecode decoder(glb); + glb->getTrackedRegisters(addr,decoder); uint4 elemId = decoder.openElement(ELEM_TRACKED_POINTSET); - decodeTracked(decoder,glb,cache); + decodeTracked(decoder,cache); decoder.closeElement(elemId); return cache; } -void ContextGhidra::decode(Decoder &decoder,const AddrSpaceManager *manage) +void ContextGhidra::decode(Decoder &decoder) { decoder.skipElement(); // Ignore details handled by ghidra } -void ContextGhidra::decodeFromSpec(Decoder &decoder,const AddrSpaceManager *manage) +void ContextGhidra::decodeFromSpec(Decoder &decoder) { decoder.skipElement(); // Ignore details handled by ghidra diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.hh index 6c4d45126a..68c201a334 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_context.hh @@ -51,8 +51,8 @@ public: virtual const TrackedSet &getTrackedSet(const Address &addr) const; // Ignored routines (taken care of by GHIDRA) - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage); - virtual void decodeFromSpec(Decoder &decoder,const AddrSpaceManager *manage); + virtual void decode(Decoder &decoder); + virtual void decodeFromSpec(Decoder &decoder); // Unimplemented routines (should never be called) virtual int getContextSize(void) const { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc index 4290fdd452..3717e3fa3a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc @@ -47,15 +47,15 @@ void connect_to_console(Funcdata *fd) decomp_data->fd = fd; decomp_data->conf = fd->getArch(); ostream *oldPrintStream = decomp_data->conf->print->getOutputStream(); - bool emitXml = decomp_data->conf->print->emitsXml(); + bool emitMarkup = decomp_data->conf->print->emitsMarkup(); decomp_data->conf->setDebugStream(remote->getOutputStream()); decomp_data->conf->print->setOutputStream(remote->getOutputStream()); - decomp_data->conf->print->setXML(false); + decomp_data->conf->print->setMarkup(false); ghidra_dcp->reset(); mainloop(ghidra_dcp); decomp_data->conf->clearAnalysis(fd); decomp_data->conf->print->setOutputStream(oldPrintStream); - decomp_data->conf->print->setXML(emitXml); + decomp_data->conf->print->setMarkup(emitMarkup); fd->debugDisable(); decomp_data->conf->allacts.getCurrent()->clearBreakPoints(); } @@ -274,9 +274,9 @@ void DecompileAt::loadParameters(void) { GhidraCommand::loadParameters(); - XmlDecode decoder; + XmlDecode decoder(ghidra); ArchitectureGhidra::readStream(sin,decoder); // Read encoded address directly from in stream - addr = Address::decode(decoder,ghidra); // Decode for functions address + addr = Address::decode(decoder); // Decode for functions address } void DecompileAt::rawAction(void) @@ -328,9 +328,9 @@ void StructureGraph::loadParameters(void) { GhidraCommand::loadParameters(); - XmlDecode decoder; + XmlDecode decoder(ghidra); ArchitectureGhidra::readStream(sin,decoder); - ingraph.decode(decoder,ghidra); + ingraph.decode(decoder); } void StructureGraph::rawAction(void) @@ -408,8 +408,8 @@ void SetOptions::loadParameters(void) { GhidraCommand::loadParameters(); - decoder.clear(); - ArchitectureGhidra::readStream(sin,decoder); + optionsListTag.clear(); + ArchitectureGhidra::readStringStream(sin, optionsListTag); } void SetOptions::rawAction(void) @@ -418,8 +418,12 @@ void SetOptions::rawAction(void) res = false; ghidra->resetDefaults(); + DocumentStorage storage; + istringstream s(optionsListTag); + Document *doc = storage.parseDocument(s); + XmlDecode decoder(ghidra,doc->getRoot()); ghidra->options->decode(decoder); - decoder.clear(); + optionsListTag.clear(); res = true; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.hh index 6a813b926b..97a46ec266 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.hh @@ -220,7 +220,7 @@ public: /// The command returns a single character message, 't' or 'f', indicating whether the /// configuration succeeded. class SetOptions : public GhidraCommand { - XmlDecode decoder; ///< The XML option document + string optionsListTag; ///< The XML tag virtual void loadParameters(void); virtual void sendResult(void); public: diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_translate.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_translate.cc index c2e4b96b4c..c516bd35d0 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_translate.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_translate.cc @@ -36,7 +36,7 @@ void GhidraTranslate::initialize(DocumentStorage &store) const Element *el = store.getTag("sleigh"); if (el == (const Element *)0) throw LowlevelError("Could not find ghidra sleigh tag"); - XmlDecode decoder(el); + XmlDecode decoder(this,el); decode(decoder); } @@ -46,7 +46,7 @@ const VarnodeData &GhidraTranslate::getRegister(const string &nm) const map::const_iterator iter = nm2addr.find(nm); if (iter != nm2addr.end()) return (*iter).second; - XmlDecode decoder; + XmlDecode decoder(glb); try { if (!glb->getRegister(nm,decoder)) // Ask Ghidra client about the register throw LowlevelError("No register named "+nm); @@ -59,7 +59,7 @@ const VarnodeData &GhidraTranslate::getRegister(const string &nm) const } Address regaddr; int4 regsize; - regaddr = Address::decode( decoder, this, regsize); + regaddr = Address::decode( decoder, regsize); VarnodeData vndata; vndata.space = regaddr.getSpace(); vndata.offset = regaddr.getOffset(); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.cc index 67e694d344..3794724fdd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.cc @@ -51,12 +51,11 @@ void TrackedContext::encode(Encoder &encoder) const /// Parse a \ element to fill in the storage and value details. /// \param decoder is the stream decoder -/// \param manage is the manager used to decode address references -void TrackedContext::decode(Decoder &decoder,const AddrSpaceManager *manage) +void TrackedContext::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_SET); - loc.decodeFromAttributes(decoder, manage); + loc.decodeFromAttributes(decoder); val = decoder.readUnsignedInteger(ATTRIB_VAL); decoder.closeElement(elemId); @@ -86,16 +85,14 @@ void ContextDatabase::encodeTracked(Encoder &encoder,const Address &addr,const T /// Parse a \ element, decoding each child in turn to populate a list of /// TrackedContext objects. /// \param decoder is the given stream decoder -/// \param manage is used to resolve address space references /// \param vec is the container that will hold the new TrackedContext objects -void ContextDatabase::decodeTracked(Decoder &decoder,const AddrSpaceManager *manage, - TrackedSet &vec) +void ContextDatabase::decodeTracked(Decoder &decoder,TrackedSet &vec) { vec.clear(); // Clear out any old stuff while(decoder.peekElement() != 0) { vec.emplace_back(); - vec.back().decode(decoder,manage); + vec.back().decode(decoder); } } @@ -498,7 +495,7 @@ void ContextInternal::encode(Encoder &encoder) const encoder.closeElement(ELEM_CONTEXT_POINTS); } -void ContextInternal::decode(Decoder &decoder,const AddrSpaceManager *manage) +void ContextInternal::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_CONTEXT_POINTS); @@ -513,14 +510,14 @@ void ContextInternal::decode(Decoder &decoder,const AddrSpaceManager *manage) } else { VarnodeData vData; - vData.decodeFromAttributes(decoder, manage); + vData.decodeFromAttributes(decoder); decodeContext(decoder,vData.getAddr(),Address()); } } else if (subId == ELEM_TRACKED_POINTSET) { VarnodeData vData; - vData.decodeFromAttributes(decoder, manage); - decodeTracked(decoder,manage,trackbase.split(vData.getAddr()) ); + vData.decodeFromAttributes(decoder); + decodeTracked(decoder,trackbase.split(vData.getAddr()) ); } else throw LowlevelError("Bad tag"); @@ -529,7 +526,7 @@ void ContextInternal::decode(Decoder &decoder,const AddrSpaceManager *manage) decoder.closeElement(elemId); } -void ContextInternal::decodeFromSpec(Decoder &decoder,const AddrSpaceManager *manage) +void ContextInternal::decodeFromSpec(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_CONTEXT_DATA); @@ -537,14 +534,14 @@ void ContextInternal::decodeFromSpec(Decoder &decoder,const AddrSpaceManager *ma uint4 subId = decoder.openElement(); if (subId == 0) break; Range range; - range.decodeFromAttributes(decoder, manage); // There MUST be a range + range.decodeFromAttributes(decoder); // There MUST be a range Address addr1 = range.getFirstAddr(); - Address addr2 = range.getLastAddrOpen(manage); + Address addr2 = range.getLastAddrOpen(decoder.getAddrSpaceManager()); if (subId == ELEM_CONTEXT_SET) { decodeContext(decoder,addr1,addr2); } else if (subId == ELEM_TRACKED_SET) { - decodeTracked(decoder,manage,createSet(addr1,addr2)); + decodeTracked(decoder,createSet(addr1,addr2)); } else throw LowlevelError("Bad tag"); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.hh index e104a408f0..6bf5ae0fe6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/globalcontext.hh @@ -76,8 +76,8 @@ public: struct TrackedContext { VarnodeData loc; ///< Storage details of the register being tracked uintb val; ///< The value of the register - void decode(Decoder &decoder,const AddrSpaceManager *manage); ///< Decode \b this from a stream - void encode(Encoder &encoder) const; ///< Encode \b this to a stream + void decode(Decoder &decoder); ///< Decode \b this from a stream + void encode(Encoder &encoder) const; ///< Encode \b this to a stream }; typedef vector TrackedSet; ///< A set of tracked registers and their values (at one code point) @@ -116,7 +116,7 @@ typedef vector TrackedSet; ///< A set of tracked registers and class ContextDatabase { protected: static void encodeTracked(Encoder &encoder,const Address &addr,const TrackedSet &vec); - static void decodeTracked(Decoder &decoder,const AddrSpaceManager *manage,TrackedSet &vec); + static void decodeTracked(Decoder &decoder,TrackedSet &vec); /// \brief Retrieve the context variable description object by name /// @@ -234,16 +234,14 @@ public: /// \brief Restore the state of \b this database object from the given stream decoder /// /// \param decoder is the given stream decoder - /// \param manage is used to resolve address space references - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage)=0; + virtual void decode(Decoder &decoder)=0; /// \brief Add initial context state from elements in the compiler/processor specifications /// /// Parse a \ element from the given stream decoder from either the compiler /// or processor specification file for the architecture, initializing this database. /// \param decoder is the given stream decoder - /// \param manage is used to resolve address space references - virtual void decodeFromSpec(Decoder &decoder,const AddrSpaceManager *manage)=0; + virtual void decodeFromSpec(Decoder &decoder)=0; void setVariableDefault(const string &nm,uintm val); ///< Provide a default value for a context variable uintm getDefaultValue(const string &nm) const; ///< Retrieve the default value for a context variable @@ -305,8 +303,8 @@ public: virtual TrackedSet &createSet(const Address &addr1,const Address &addr2); virtual void encode(Encoder &encoder) const; - virtual void decode(Decoder &decoder,const AddrSpaceManager *manage); - virtual void decodeFromSpec(Decoder &decoder,const AddrSpaceManager *manage); + virtual void decode(Decoder &decoder); + virtual void decodeFromSpec(Decoder &decoder); }; /// \brief A helper class for caching the active context blob to minimize database lookups diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc index 65bbc74458..3f1c8ee531 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ifacedecomp.cc @@ -880,9 +880,9 @@ void IfcPrintCXml::execute(istream &s) throw IfaceExecutionError("No function selected"); dcp->conf->print->setOutputStream(status->fileoptr); - dcp->conf->print->setXML(true); + dcp->conf->print->setMarkup(true); dcp->conf->print->docFunction(dcp->fd); - dcp->conf->print->setXML(false); + dcp->conf->print->setMarkup(false); } /// \class IfcPrintCStruct @@ -2724,7 +2724,7 @@ void IfcCallGraphLoad::execute(istream &s) Document *doc = store.parseDocument(is); dcp->allocateCallGraph(); - XmlDecode decoder(doc->getRoot()); + XmlDecode decoder(dcp->conf,doc->getRoot()); dcp->cgraph->decoder(decoder); *status->optr << "Successfully read in callgraph" << endl; @@ -3016,8 +3016,8 @@ void IfcStructureBlocks::execute(istream &s) try { BlockGraph ingraph; - XmlDecode decoder(doc->getRoot()); - ingraph.decode(decoder,dcp->conf); + XmlDecode decoder(dcp->conf,doc->getRoot()); + ingraph.decode(decoder); BlockGraph resultgraph; vector rootlist; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_ghidra.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_ghidra.cc index 0f22c64802..f9449b87b1 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_ghidra.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_ghidra.cc @@ -48,7 +48,7 @@ void InjectPayloadGhidra::inject(InjectContext &con,PcodeEmit &emit) const { ArchitectureGhidra *ghidra = (ArchitectureGhidra *)con.glb; - XmlDecode decoder; + XmlDecode decoder(ghidra); try { if (!ghidra->getPcodeInject(name,type,con,decoder)) throw LowlevelError("Could not retrieve pcode snippet: "+name); @@ -61,7 +61,7 @@ void InjectPayloadGhidra::inject(InjectContext &con,PcodeEmit &emit) const } uint4 elemId = decoder.openElement(); while(decoder.peekElement() != 0) - emit.decodeOp(decoder,ghidra->translate); + emit.decodeOp(decoder); decoder.closeElement(elemId); } @@ -121,7 +121,7 @@ void ExecutablePcodeGhidra::inject(InjectContext &con,PcodeEmit &emit) const { ArchitectureGhidra *ghidra = (ArchitectureGhidra *)con.glb; - XmlDecode decoder; + XmlDecode decoder(ghidra); try { if (!ghidra->getPcodeInject(name,type,con,decoder)) throw LowlevelError("Could not retrieve pcode snippet: "+name); @@ -134,7 +134,7 @@ void ExecutablePcodeGhidra::inject(InjectContext &con,PcodeEmit &emit) const } uint4 elemId = decoder.openElement(); while(decoder.peekElement() != 0) - emit.decodeOp(decoder,ghidra->translate); + emit.decodeOp(decoder); decoder.closeElement(elemId); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc index 81ccb11596..9d8951e9d1 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc @@ -259,7 +259,7 @@ InjectPayloadDynamic::~InjectPayloadDynamic(void) void InjectPayloadDynamic::decodeEntry(Decoder &decoder) { - Address addr = Address::decode(decoder,glb); + Address addr = Address::decode(decoder); uint4 subId = decoder.openElement(ELEM_PAYLOAD); istringstream s(decoder.readString(ATTRIB_CONTENT)); try { @@ -282,10 +282,10 @@ void InjectPayloadDynamic::inject(InjectContext &context,PcodeEmit &emit) const if (eiter == addrMap.end()) throw LowlevelError("Missing dynamic inject"); const Element *el = (*eiter).second->getRoot(); - XmlDecode decoder(el); + XmlDecode decoder(glb->translate,el); uint4 rootId = decoder.openElement(ELEM_INST); while(decoder.peekElement() != 0) - emit.decodeOp(decoder,glb->translate); + emit.decodeOp(decoder); decoder.closeElement(rootId); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.cc index 0b5151f2bf..919bb14206 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.cc @@ -40,14 +40,13 @@ void LoadTable::encode(Encoder &encoder) const } /// \param decoder is the stream decoder -/// \param glb is the architecture for resolving address space tags -void LoadTable::decode(Decoder &decoder,Architecture *glb) +void LoadTable::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_LOADTABLE); size = decoder.readSignedInteger(ATTRIB_SIZE); num = decoder.readSignedInteger(ATTRIB_NUM); - addr = Address::decode( decoder, glb); + addr = Address::decode( decoder ); decoder.closeElement(elemId); } @@ -1934,7 +1933,7 @@ void JumpBasicOverride::encode(Encoder &encoder) const encoder.closeElement(ELEM_BASICOVERRIDE); } -void JumpBasicOverride::decode(Decoder &decoder,Architecture *glb) +void JumpBasicOverride::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_BASICOVERRIDE); @@ -1943,12 +1942,12 @@ void JumpBasicOverride::decode(Decoder &decoder,Architecture *glb) if (subId == 0) break; if (subId == ELEM_DEST) { VarnodeData vData; - vData.decodeFromAttributes(decoder, glb); + vData.decodeFromAttributes(decoder); adset.insert( vData.getAddr() ); } else if (subId == ELEM_NORMADDR) { VarnodeData vData; - vData.decodeFromAttributes(decoder, glb); + vData.decodeFromAttributes(decoder); normaddress = vData.getAddr(); } else if (subId == ELEM_NORMHASH) { @@ -2645,7 +2644,7 @@ void JumpTable::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_JUMPTABLE); - opaddress = Address::decode( decoder, glb); + opaddress = Address::decode( decoder ); bool missedlabel = false; for(;;) { uint4 subId = decoder.peekElement(); @@ -2667,17 +2666,17 @@ void JumpTable::decode(Decoder &decoder) } if (!foundlabel) // No label attribute missedlabel = true; // No following entries are allowed to have a label attribute - addresstable.push_back( Address::decode( decoder, glb) ); + addresstable.push_back( Address::decode( decoder ) ); } else if (subId == ELEM_LOADTABLE) { loadpoints.emplace_back(); - loadpoints.back().decode(decoder,glb); + loadpoints.back().decode(decoder); } else if (subId == ELEM_BASICOVERRIDE) { if (jmodel != (JumpModel *)0) throw LowlevelError("Duplicate jumptable override specs"); jmodel = new JumpBasicOverride(this); - jmodel->decode(decoder,glb); + jmodel->decode(decoder); } } decoder.closeElement(elemId); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.hh index 4ab0d990fe..eafb098972 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/jumptable.hh @@ -60,7 +60,7 @@ public: LoadTable(const Address &ad,int4 sz,int4 nm) { addr = ad; size = sz; num = nm; } ///< Construct a full table bool operator<(const LoadTable &op2) const { return (addr < op2.addr); } ///< Compare \b this with another table by address void encode(Encoder &encoder) const; ///< Encode a description of \b this as an \ element - void decode(Decoder &decoder,Architecture *glb); ///< Decode \b this table from a \ element + void decode(Decoder &decoder); ///< Decode \b this table from a \ element static void collapseTable(vector &table); ///< Collapse a sequence of table descriptions }; @@ -321,7 +321,7 @@ public: virtual JumpModel *clone(JumpTable *jt) const=0; ///< Clone \b this model virtual void clear(void) {} ///< Clear any non-permanent aspects of the model virtual void encode(Encoder &encoder) const {} ///< Encode this model to a stream - virtual void decode(Decoder &decoder,Architecture *glb) {} ///< Decode \b this model from a stream + virtual void decode(Decoder &decoder) {} ///< Decode \b this model from a stream }; /// \brief A trivial jump-table model, where the BRANCHIND input Varnode is the switch variable @@ -463,7 +463,7 @@ public: virtual JumpModel *clone(JumpTable *jt) const; virtual void clear(void); virtual void encode(Encoder &encoder) const; - virtual void decode(Decoder &decoder,Architecture *glb); + virtual void decode(Decoder &decoder); }; class JumpAssistOp; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/loadimage_xml.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/loadimage_xml.cc index 1fbfd4b0e4..de62d2d341 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/loadimage_xml.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/loadimage_xml.cc @@ -81,27 +81,19 @@ void LoadImageXml::open(const AddrSpaceManager *m) uint4 sz; // unused size // Read parsed xml file - XmlDecode decoder(rootel); + XmlDecode decoder(m,rootel); uint4 elemId = decoder.openElement(ELEM_BINARYIMAGE); for(;;) { uint4 subId = decoder.openElement(); if (subId == 0) break; if (subId==ELEM_SYMBOL) { - AddrSpace *base = (AddrSpace *)0; - string spaceName = decoder.readString(ATTRIB_SPACE); - base = manage->getSpaceByName(spaceName); - if (base == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+spaceName); + AddrSpace *base = decoder.readSpace(ATTRIB_SPACE); Address addr(base,base->decodeAttributes(decoder,sz)); string nm = decoder.readString(ATTRIB_NAME); addrtosymbol[addr] = nm; } else if (subId == ELEM_BYTECHUNK) { - AddrSpace *base = (AddrSpace *)0; - string spaceName = decoder.readString(ATTRIB_SPACE); - base = manage->getSpaceByName(spaceName); - if (base == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+spaceName); + AddrSpace *base = decoder.readSpace(ATTRIB_SPACE); Address addr(base,base->decodeAttributes(decoder,sz)); map >::iterator chnkiter; vector &vec( chunk[addr] ); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc index 0616ede2be..cc87ce40bd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc @@ -14,7 +14,7 @@ * limitations under the License. */ #include "marshal.hh" -#include +#include "translate.hh" unordered_map AttributeId::lookupAttributeId; @@ -348,6 +348,35 @@ string XmlDecode::readString(const AttributeId &attribId) return el->getAttributeValue(index); } +AddrSpace *XmlDecode::readSpace(void) + +{ + const Element *el = elStack.back(); + string nm = el->getAttributeValue(attributeIndex); + AddrSpace *res = spcManager->getSpaceByName(nm); + if (res == (AddrSpace *)0) + throw XmlError("Unknown address space name: "+nm); + return res; +} + +AddrSpace *XmlDecode::readSpace(const AttributeId &attribId) + +{ + const Element *el = elStack.back(); + string nm; + if (attribId == ATTRIB_CONTENT) { + nm = el->getContent(); + } + else { + int4 index = findMatchingAttribute(el, attribId.getName()); + nm = el->getAttributeValue(index); + } + AddrSpace *res = spcManager->getSpaceByName(nm); + if (res == (AddrSpace *)0) + throw XmlError("Unknown address space name: "+nm); + return res; +} + void XmlEncode::openElement(const ElementId &elemId) { @@ -429,6 +458,20 @@ void XmlEncode::writeString(const AttributeId &attribId,const string &val) a_v(outStream,attribId.getName(),val); } +void XmlEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc) + +{ + if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value + if (elementTagIsOpen) { + outStream << '>'; + elementTagIsOpen = false; + } + xml_escape(outStream, spc->getName().c_str()); + return; + } + a_v(outStream,attribId.getName(),spc->getName()); +} + // Common attributes. Attributes with multiple uses AttributeId ATTRIB_CONTENT = AttributeId("XMLcontent",1); AttributeId ATTRIB_ALIGN = AttributeId("align",2); @@ -457,7 +500,7 @@ AttributeId ATTRIB_VAL = AttributeId("val",24); AttributeId ATTRIB_VALUE = AttributeId("value",25); AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize",26); -AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",136); // Number serves as next open index +AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",144); // Number serves as next open index ElementId ELEM_DATA = ElementId("data",1); ElementId ELEM_INPUT = ElementId("input",2); @@ -470,4 +513,4 @@ ElementId ELEM_VAL = ElementId("val",8); ElementId ELEM_VALUE = ElementId("value",9); ElementId ELEM_VOID = ElementId("void",10); -ElementId ELEM_UNKNOWN = ElementId("XMLunknown",208); // Number serves as next open index +ElementId ELEM_UNKNOWN = ElementId("XMLunknown",218); // Number serves as next open index diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh index 11c7548e17..030afdaa03 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh @@ -75,6 +75,9 @@ public: friend bool operator!=(const ElementId &op1,uint4 id) { return (op1.id != id); } ///< Test inequality of an ElementId with a raw integer id }; +class AddrSpace; +class AddrSpaceManager; + /// \brief A class for reading structured data from a stream /// /// All data is loosely structured as with an XML document. A document contains a nested set @@ -89,7 +92,12 @@ public: /// whose data can be extracted using a read*(AttributeId) call that is passed the special ATTRIB_CONTENT id. /// This attribute will not be traversed by getNextAttribute(). class Decoder { +protected: + const AddrSpaceManager *spcManager; ///< Manager for decoding address space attributes public: + Decoder(const AddrSpaceManager *spc) { spcManager = spc; } ///< Base constructor + + const AddrSpaceManager *getAddrSpaceManager(void) const { return spcManager; } ///< Get the manager used for address space decoding virtual ~Decoder(void) {} ///< Destructor /// \brief Clear any current decoding state @@ -215,6 +223,21 @@ public: /// \return the string associated with the attribute virtual string readString(const AttributeId &attribId)=0; + /// \brief Parse the current attribute as an address space + /// + /// The last attribute, as returned by getNextAttributeId, is returned as an address space. + /// \return the address space associated with the current attribute. + virtual AddrSpace *readSpace(void)=0; + + /// \brief Find the specific attribute in the current element and return it as an address space + /// + /// Search attributes from the current element for a match to the given attribute id. + /// Return this attribute as an address space. If there is no attribute matching the id, an exception is throw. + /// Parse via getNextAttributeId is reset. + /// \param attribId is the specific attribute id to match + /// \return the address space associated with the attribute + virtual AddrSpace *readSpace(const AttributeId &attribId)=0; + /// \brief Skip parsing of the next element /// /// The element skipped is the one that would be opened by the next call to openElement. @@ -283,6 +306,13 @@ public: /// \param attribId is the given AttributeId annotation /// \param val is the string to encode virtual void writeString(const AttributeId &attribId,const string &val)=0; + + /// \brief Write an address space reference into the encoding + /// + /// The address space is associated with the given AttributeId annotation and the current open element. + /// \param attribId is the given AttributeId annotation + /// \param spc is the address space to encode + virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc)=0; }; /// \brief An XML based decoder @@ -298,8 +328,10 @@ class XmlDecode : public Decoder { int4 attributeIndex; ///< Position of \e current attribute to parse (in \e current element) int4 findMatchingAttribute(const Element *el,const string &attribName); public: - XmlDecode(const Element *root) { document = (Document *)0; rootElement = root; attributeIndex = -1; } ///< Constructor with preparsed root - XmlDecode(void) { document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; } ///< Constructor for use with ingestStream + XmlDecode(const AddrSpaceManager *spc,const Element *root) : Decoder(spc) { + document = (Document *)0; rootElement = root; attributeIndex = -1; } ///< Constructor with preparsed root + XmlDecode(const AddrSpaceManager *spc) : Decoder(spc) { + document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; } ///< Constructor for use with ingestStream virtual ~XmlDecode(void); virtual void clear(void); virtual void ingestStream(istream &s); @@ -318,6 +350,8 @@ public: virtual uintb readUnsignedInteger(const AttributeId &attribId); virtual string readString(void); virtual string readString(const AttributeId &attribId); + virtual AddrSpace *readSpace(void); + virtual AddrSpace *readSpace(const AttributeId &attribId); }; /// \brief An XML based encoder @@ -337,6 +371,7 @@ public: virtual void writeSignedInteger(const AttributeId &attribId,intb val); virtual void writeUnsignedInteger(const AttributeId &attribId,uintb val); virtual void writeString(const AttributeId &attribId,const string &val); + virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc); }; extern ElementId ELEM_UNKNOWN; ///< Special element to represent an element with an unrecognized name diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc index 755704dec6..e77a415603 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc @@ -427,7 +427,7 @@ void PcodeOp::encode(Encoder &encoder) const if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) { AddrSpace *spc = vn->getSpaceFromConst(); encoder.openElement(ELEM_SPACEID); - encoder.writeString(ATTRIB_NAME, spc->getName()); + encoder.writeSpace(ATTRIB_NAME, spc); encoder.closeElement(ELEM_SPACEID); } else { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc index f677330aa9..e1fb09aca5 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc @@ -310,7 +310,7 @@ void Override::encode(Encoder &encoder,Architecture *glb) const if (deadcodedelay[i] < 0) continue; AddrSpace *spc = glb->getSpace(i); encoder.openElement(ELEM_DEADCODEDELAY); - encoder.writeString(ATTRIB_SPACE, spc->getName()); + encoder.writeSpace(ATTRIB_SPACE, spc); encoder.writeSignedInteger(ATTRIB_DELAY, deadcodedelay[i]); encoder.closeElement(ELEM_DEADCODEDELAY); } @@ -359,36 +359,36 @@ void Override::decode(Decoder &decoder,Architecture *glb) uint4 subId = decoder.openElement(); if (subId == 0) break; if (subId == ELEM_INDIRECTOVERRIDE) { - Address callpoint = Address::decode(decoder,glb); - Address directcall = Address::decode(decoder,glb); + Address callpoint = Address::decode(decoder); + Address directcall = Address::decode(decoder); insertIndirectOverride(callpoint,directcall); } else if (subId == ELEM_PROTOOVERRIDE) { - Address callpoint = Address::decode(decoder,glb); + Address callpoint = Address::decode(decoder); FuncProto *fp = new FuncProto(); fp->setInternal(glb->defaultfp,glb->types->getTypeVoid()); fp->decode(decoder,glb); insertProtoOverride(callpoint,fp); } else if (subId == ELEM_FORCEGOTO) { - Address targetpc = Address::decode(decoder,glb); - Address destpc = Address::decode(decoder,glb); + Address targetpc = Address::decode(decoder); + Address destpc = Address::decode(decoder); insertForceGoto(targetpc,destpc); } else if (subId == ELEM_DEADCODEDELAY) { int4 delay = decoder.readSignedInteger(ATTRIB_DELAY); - AddrSpace *spc = glb->getSpaceByName( decoder.readString(ATTRIB_SPACE)); - if ((spc == (AddrSpace *)0)||(delay < 0)) + AddrSpace *spc = decoder.readSpace(ATTRIB_SPACE); + if (delay < 0) throw LowlevelError("Bad deadcodedelay tag"); insertDeadcodeDelay(spc,delay); } else if (subId == ELEM_MULTISTAGEJUMP) { - Address callpoint = Address::decode(decoder,glb); + Address callpoint = Address::decode(decoder); insertMultistageJump(callpoint); } else if (subId == ELEM_FLOW) { uint4 type = stringToType(decoder.readString(ATTRIB_TYPE)); - Address addr = Address::decode(decoder,glb); + Address addr = Address::decode(decoder); if ((type == Override::NONE)||(addr.isInvalid())) throw LowlevelError("Bad flowoverride tag"); insertFlowOverride(addr,type); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.cc index d9d9266b0f..5856d7b096 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.cc @@ -18,19 +18,17 @@ /// Build this VarnodeData from an \, \, or \ element. /// \param decoder is the stream decoder -/// \param manage is the address space manager -void VarnodeData::decode(Decoder &decoder,const AddrSpaceManager *manage) +void VarnodeData::decode(Decoder &decoder) { uint4 elemId = decoder.openElement(); - decodeFromAttributes(decoder,manage); + decodeFromAttributes(decoder); decoder.closeElement(elemId); } /// Collect attributes for the VarnodeData possibly from amidst other attributes /// \param decoder is the stream decoder -/// \param manage is the address space manager -void VarnodeData::decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage) +void VarnodeData::decodeFromAttributes(Decoder &decoder) { space = (AddrSpace *)0; @@ -40,16 +38,13 @@ void VarnodeData::decodeFromAttributes(Decoder &decoder,const AddrSpaceManager * if (attribId == 0) break; // Its possible to have no attributes in an tag if (attribId == ATTRIB_SPACE) { - string nm = decoder.readString(); - space = manage->getSpaceByName(nm); - if (space == (AddrSpace *)0) - throw LowlevelError("Unknown space name: "+nm); + space = decoder.readSpace(); decoder.rewindAttributes(); offset = space->decodeAttributes(decoder,size); break; } else if (attribId == ATTRIB_NAME) { - const Translate *trans = manage->getDefaultCodeSpace()->getTrans(); + const Translate *trans = decoder.getAddrSpaceManager()->getDefaultCodeSpace()->getTrans(); const VarnodeData &point(trans->getRegister(decoder.readString())); *this = point; break; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.hh index d254993924..78db818b14 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcoderaw.hh @@ -45,10 +45,10 @@ struct VarnodeData { AddrSpace *getSpaceFromConst(void) const; /// Recover this object from a stream - void decode(Decoder &decoder,const AddrSpaceManager *manage); + void decode(Decoder &decoder); /// Recover \b this object from attributes of the current open element - void decodeFromAttributes(Decoder &decoder,const AddrSpaceManager *manage); + void decodeFromAttributes(Decoder &decoder); /// Does \b this container another given VarnodeData bool contains(const VarnodeData &op2) const; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.cc index 20e3953e08..90fd8c14fd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.cc @@ -16,345 +16,278 @@ #include "prettyprint.hh" #include "funcdata.hh" -const char *EmitXml::highlight[] = { "color=\"keyword\"", - "color=\"comment\"", - "color=\"type\"", - "color=\"funcname\"", - "color=\"var\"", - "color=\"const\"", - "color=\"param\"", - "color=\"global\"", - "" }; +AttributeId ATTRIB_BLOCKREF = AttributeId("blockref",136); +AttributeId ATTRIB_CLOSE = AttributeId("close",137); +AttributeId ATTRIB_COLOR = AttributeId("color",138); +AttributeId ATTRIB_INDENT = AttributeId("indent",139); +AttributeId ATTRIB_OFF = AttributeId("off",140); +AttributeId ATTRIB_OPEN = AttributeId("open",141); +AttributeId ATTRIB_OPREF = AttributeId("opref",142); +AttributeId ATTRIB_VARREF = AttributeId("varref",143); +ElementId ELEM_BREAK = ElementId("break",208); +ElementId ELEM_CLANG_DOCUMENT = ElementId("clang_document",209); +ElementId ELEM_FUNCNAME = ElementId("funcname",210); +ElementId ELEM_FUNCPROTO = ElementId("funcproto",211); +ElementId ELEM_LABEL = ElementId("label",212); +ElementId ELEM_RETURN_TYPE = ElementId("return_type",213); +ElementId ELEM_STATEMENT = ElementId("statement",214); +ElementId ELEM_SYNTAX = ElementId("syntax",215); +ElementId ELEM_VARDECL = ElementId("vardecl",216); +ElementId ELEM_VARIABLE = ElementId("variable",217); -/// Inform the emitter that generation of the source code document has begun -/// \return an id associated with the document -int4 EmitXml::beginDocument(void) { - *s << "'; - return 0; -} +const string Emit::EMPTY_STRING = ""; -/// Inform the emitter that generation of the source code document is finished -/// \param id is the id associated with the document (as returned by beginDocument) -void EmitXml::endDocument(int4 id) { - *s << ""; -} - -/// Inform the emitter that generation of a function body has begun -/// \return an id associated with the function body -int4 EmitXml::beginFunction(const Funcdata *fd) { - *s << "'; - return 0; -} - -/// Inform the emitter that generation of a function body has ended -/// \param id is the id associated with the function body (as returned by beginFunction) -void EmitXml::endFunction(int4 id) { - *s << ""; -} - -/// Inform the emitter that a new control-flow section is starting. This is a source code unit -/// usually surrounded with curly braces '{' and '}'. -/// \param bl is the block structure object associated with the section -/// \return an id associated with the section -int4 EmitXml::beginBlock(const FlowBlock *bl) { - *s << "getIndex() << "\">"; - return 0; -} - -/// Inform the emitter that a control-flow section is ending. -/// \param id is the id associated with the section (as returned by beginBlock) -void EmitXml::endBlock(int4 id) { - *s << ""; -} - -/// Tell the emitter that a new line is desired at the current indent level -void EmitXml::tagLine(void) { - emitPending(); - *s << ""; -} - -/// Tell the emitter that a new line is desired at a specific indent level. The indent level -/// is overridden only for the line, then it returns to its previous value. -/// \param indent is the desired indent level for the new line -void EmitXml::tagLine(int4 indent) { - emitPending(); - *s << ""; -} - -/// Inform the emitter that generation of a function's return type is starting. -/// \param vn (if non-null) is the storage location for the return value -/// \return an id associated with the return type -int4 EmitXml::beginReturnType(const Varnode *vn) { - *s << "getCreateIndex() << "\">"; - else - *s << '>'; - return 0; -} - -/// Inform the emitter that generation of a function's return type is ending. -/// \param id is the id associated with the return type (as returned by beginReturnType) -void EmitXml::endReturnType(int4 id) { - *s << ""; -} - -/// Inform the emitter that a variable declaration has started. -/// \param sym is the symbol being declared -/// \return an id associated with the declaration -int4 EmitXml::beginVarDecl(const Symbol *sym) { - *s << "getId() << "\">"; - return 0; -} - -/// Inform the emitter that a variable declaration has ended. -/// \param id is the id associated with the declaration (as returned by beginVarDecl) -void EmitXml::endVarDecl(int4 id) { - *s << ""; -} - -/// Inform the emitter that a source code statement is beginning. -/// \param op is the root p-code operation of the statement -/// \return an id associated with the statement -int4 EmitXml::beginStatement(const PcodeOp *op) { - *s << "getTime() << "\">"; - else - *s << '>'; - return 0; -} - -/// Inform the emitter that a source code statement is ending. -/// \param id is the id associated with the statement (as returned by beginStatement) -void EmitXml::endStatement(int4 id) { - *s << ""; -} - -/// Inform the emitter that a function prototype is starting. -/// \return an id associated with the prototype -int4 EmitXml::beginFuncProto(void) { - *s << "'; - return 0; -} - -/// Inform the emitter that a function prototype is ending. -/// \param id is the id associated with the prototype (as returned by beginFuncProto) -void EmitXml::endFuncProto(int4 id) { - *s << ""; -} - -/// \brief Emit a variable token -/// -/// An identifier string representing the variable is output, possibly with additional markup. -/// \param ptr is the character data for the identifier -/// \param hl indicates how the identifier should be highlighted -/// \param vn is the Varnode representing the variable within the syntax tree -/// \param op is a p-code operation related to the use of the variable (may be null) -void EmitXml::tagVariable(const char *ptr,syntax_highlight hl, - const Varnode *vn,const PcodeOp *op) -{ - *s << "getCreateIndex() << '\"'; - if (op != (const PcodeOp *)0) - *s << " opref=\"0x" << hex << op->getTime() << '\"'; - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit an operation token -/// -/// The string representing the operation as appropriate for the source language is emitted, -/// possibly with additional markup. -/// \param ptr is the character data for the emitted representation -/// \param hl indicates how the token should be highlighted -/// \param op is the PcodeOp object associated with the operation with the syntax tree -void EmitXml::tagOp(const char *ptr,syntax_highlight hl, - const PcodeOp *op) -{ - *s << "getTime() << "\">"; - else - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit a function identifier -/// -/// An identifier string representing the symbol name of the function is emitted, possible -/// with additional markup. -/// \param ptr is the character data for the identifier -/// \param hl indicates how the identifier should be highlighted -/// \param fd is the function -/// \param op is the CALL operation associated within the syntax tree or null for a declaration -void EmitXml::tagFuncName(const char *ptr,syntax_highlight hl, - const Funcdata *fd,const PcodeOp *op) -{ - *s << "getTime() << "\">"; - else - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit a data-type identifier -/// -/// A string representing the name of a data-type, as appropriate for the source language -/// is emitted, possibly with additional markup. -/// \param ptr is the character data for the identifier -/// \param hl indicates how the identifier should be highlighted -/// \param ct is the data-type description object -void EmitXml::tagType(const char *ptr,syntax_highlight hl,const Datatype *ct) { - *s << "getId() != 0) { - *s << " id=\"0x" << hex << ct->getId() << '\"'; - } - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit an identifier for a field within a structured data-type -/// -/// A string representing an individual component of a structured data-type is emitted, -/// possibly with additional markup. -/// \param ptr is the character data for the identifier -/// \param hl indicates how the identifier should be highlighted -/// \param ct is the data-type associated with the field -/// \param o is the (byte) offset of the field within its structured data-type -/// \param op is the PcodeOp associated with the field (usually PTRSUB or SUBPIECE) -void EmitXml::tagField(const char *ptr,syntax_highlight hl,const Datatype *ct,int4 o,const PcodeOp *op) { - *s << "getName().c_str()); - if (ct->getId() != 0) { - *s << "\" id=\"0x" << hex << ct->getId(); - } - - *s << "\" off=\"" << dec << o << '\"'; - if (op != (const PcodeOp *)0) - *s << " opref=\"0x" << hex << op->getTime() << "\""; - } - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit a comment string as part of the generated source code -/// -/// Individual comments can be broken up and emitted using multiple calls to this method, -/// but ultimately the comment delimiters and the body of the comment are both emitted with -/// this method, which may provide addition markup. -/// \param ptr is the character data for the comment -/// \param hl indicates how the comment should be highlighted -/// \param spc is the address space of the address where the comment is attached -/// \param off is the offset of the address where the comment is attached -void EmitXml::tagComment(const char *ptr,syntax_highlight hl, - const AddrSpace *spc,uintb off) { - *s << "getName()); - a_v_u(*s,"off",off); - *s << '>'; - xml_escape(*s,ptr); - *s << ""; -} - -/// \brief Emit a code label identifier -/// -/// A string describing a control-flow destination, as appropriate for the source language -/// is output, possibly with additional markup. -/// \param ptr is the character data of the label -/// \param hl indicates how the label should be highlighted -/// \param spc is the address space of the code address being labeled -/// \param off is the offset of the code address being labeled -void EmitXml::tagLabel(const char *ptr,syntax_highlight hl, - const AddrSpace *spc,uintb off) { - *s << ""; -} - -/// \brief Emit other (more unusual) syntax as part of source code generation -/// -/// This method is used to emit syntax not covered by the other methods, such as -/// spaces, semi-colons, braces, and other punctuation. -/// \param str is the character data of the syntax being emitted -/// \param hl indicates how the syntax should be highlighted -void EmitXml::print(const char *str,syntax_highlight hl) - -{ - *s << "'; - xml_escape(*s,str); - *s << ""; -} - -/// This method emits the parenthesis character itself and also starts a printing unit -/// of the source code being surrounded by the parentheses. -/// \param o is the open parenthesis character to emit -/// \param id is an id to associate with the parenthesis -/// \return an id associated with the parenthesis -int4 EmitXml::openParen(char o,int4 id) - -{ - *s << ""; - *s << o; - *s << ""; - parenlevel += 1; - return 0; -} - -/// This method emits the parenthesis character itself and ends the printing unit that -/// was started by the matching open parenthesis. -/// \param c is the close parenthesis character to emit -/// \param id is the id associated with the matching open parenthesis (as returned by openParen) -void EmitXml::closeParen(char c,int4 id) - -{ - *s << ""; - *s << c; - *s << ""; - parenlevel -= 1; -} +const string EmitMarkup::highlight[] = { "keyword", + "comment", + "type", + "funcname", + "var", + "const", + "param", + "global", + "" }; /// \brief Emit a sequence of space characters as part of source code /// /// \param num is the number of space characters to emit /// \param bump is the number of characters to indent if the spaces force a line break -void EmitXml::spaces(int4 num,int4 bump) +void Emit::spaces(int4 num,int4 bump) { - const char *tenspaces = " "; + static const string spacearray[] = { "", " ", " ", " ", " ", " ", " ", " ", + " ", " ", " " }; if (num <= 10) - print(tenspaces+(10-num)); + print(spacearray[num]); else { string spc; for(int4 i=0;iopenElement(ELEM_CLANG_DOCUMENT); + return 0; +} + +void EmitMarkup::endDocument(int4 id) { + encoder->closeElement(ELEM_CLANG_DOCUMENT); +} + +int4 EmitMarkup::beginFunction(const Funcdata *fd) { + encoder->openElement(ELEM_FUNCTION); + return 0; +} + +void EmitMarkup::endFunction(int4 id) { + encoder->closeElement(ELEM_FUNCTION); +} + +int4 EmitMarkup::beginBlock(const FlowBlock *bl) { + encoder->openElement(ELEM_BLOCK); + encoder->writeSignedInteger(ATTRIB_BLOCKREF, bl->getIndex()); + return 0; +} + +void EmitMarkup::endBlock(int4 id) { + encoder->closeElement(ELEM_BLOCK); +} + +void EmitMarkup::tagLine(void) { + emitPending(); + encoder->openElement(ELEM_BREAK); + encoder->writeSignedInteger(ATTRIB_INDENT, indentlevel); + encoder->closeElement(ELEM_BREAK); +} + +void EmitMarkup::tagLine(int4 indent) { + emitPending(); + encoder->openElement(ELEM_BREAK); + encoder->writeSignedInteger(ATTRIB_INDENT, indent); + encoder->closeElement(ELEM_BREAK); +} + +int4 EmitMarkup::beginReturnType(const Varnode *vn) { + encoder->openElement(ELEM_RETURN_TYPE); + if (vn != (const Varnode *)0) + encoder->writeUnsignedInteger(ATTRIB_VARREF, vn->getCreateIndex()); + return 0; +} + +void EmitMarkup::endReturnType(int4 id) { + encoder->closeElement(ELEM_RETURN_TYPE); +} + +int4 EmitMarkup::beginVarDecl(const Symbol *sym) { + encoder->openElement(ELEM_VARDECL); + encoder->writeUnsignedInteger(ATTRIB_SYMREF, sym->getId()); + return 0; +} + +void EmitMarkup::endVarDecl(int4 id) { + encoder->closeElement(ELEM_VARDECL); +} + +int4 EmitMarkup::beginStatement(const PcodeOp *op) { + encoder->openElement(ELEM_STATEMENT); + if (op != (const PcodeOp *)0) + encoder->writeUnsignedInteger(ATTRIB_OPREF, op->getTime()); + return 0; +} + +void EmitMarkup::endStatement(int4 id) { + encoder->closeElement(ELEM_STATEMENT); +} + +int4 EmitMarkup::beginFuncProto(void) { + encoder->openElement(ELEM_FUNCPROTO); + return 0; +} + +void EmitMarkup::endFuncProto(int4 id) { + encoder->closeElement(ELEM_FUNCPROTO); +} + +void EmitMarkup::tagVariable(const string &name,syntax_highlight hl,const Varnode *vn,const PcodeOp *op) + +{ + encoder->openElement(ELEM_VARIABLE); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR, highlight[(int4)hl]); + if (vn != (const Varnode *)0) + encoder->writeUnsignedInteger(ATTRIB_VARREF, vn->getCreateIndex()); + if (op != (const PcodeOp *)0) + encoder->writeUnsignedInteger(ATTRIB_OPREF, op->getTime()); + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_VARIABLE); +} + +void EmitMarkup::tagOp(const string &name,syntax_highlight hl,const PcodeOp *op) + +{ + encoder->openElement(ELEM_OP); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + if (op != (const PcodeOp *)0) + encoder->writeUnsignedInteger(ATTRIB_OPREF, op->getTime()); + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_OP); +} + +void EmitMarkup::tagFuncName(const string &name,syntax_highlight hl,const Funcdata *fd,const PcodeOp *op) + +{ + encoder->openElement(ELEM_FUNCNAME); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + if (op != (const PcodeOp *)0) + encoder->writeUnsignedInteger(ATTRIB_OPREF, op->getTime()); + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_FUNCNAME); +} + +void EmitMarkup::tagType(const string &name,syntax_highlight hl,const Datatype *ct) + +{ + encoder->openElement(ELEM_TYPE); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + if (ct->getId() != 0) { + encoder->writeUnsignedInteger(ATTRIB_ID, ct->getId()); + } + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_TYPE); +} + +void EmitMarkup::tagField(const string &name,syntax_highlight hl,const Datatype *ct,int4 o,const PcodeOp *op) + +{ + encoder->openElement(ELEM_FIELD); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + if (ct != (const Datatype *)0) { + encoder->writeString(ATTRIB_NAME,ct->getName()); + if (ct->getId() != 0) { + encoder->writeUnsignedInteger(ATTRIB_ID, ct->getId()); + } + encoder->writeSignedInteger(ATTRIB_OFF, o); + if (op != (const PcodeOp *)0) + encoder->writeUnsignedInteger(ATTRIB_OPREF, op->getTime()); + } + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_FIELD); +} + +void EmitMarkup::tagComment(const string &name,syntax_highlight hl,const AddrSpace *spc,uintb off) + +{ + encoder->openElement(ELEM_COMMENT); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + encoder->writeSpace(ATTRIB_SPACE, spc); + encoder->writeUnsignedInteger(ATTRIB_OFF, off); + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_COMMENT); +} + +void EmitMarkup::tagLabel(const string &name,syntax_highlight hl,const AddrSpace *spc,uintb off) + +{ + encoder->openElement(ELEM_LABEL); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + encoder->writeSpace(ATTRIB_SPACE,spc); + encoder->writeUnsignedInteger(ATTRIB_OFF, off); + encoder->writeString(ATTRIB_CONTENT,name); + encoder->closeElement(ELEM_LABEL); +} + +void EmitMarkup::print(const string &data,syntax_highlight hl) + +{ + encoder->openElement(ELEM_SYNTAX); + if (hl != no_color) + encoder->writeString(ATTRIB_COLOR,highlight[(int4)hl]); + encoder->writeString(ATTRIB_CONTENT,data); + encoder->closeElement(ELEM_SYNTAX); +} + +int4 EmitMarkup::openParen(const string &paren,int4 id) + +{ + encoder->openElement(ELEM_SYNTAX); + encoder->writeSignedInteger(ATTRIB_OPEN, id); + encoder->writeString(ATTRIB_CONTENT,paren); + encoder->closeElement(ELEM_SYNTAX); + parenlevel += 1; + return 0; +} + +void EmitMarkup::closeParen(const string &paren,int4 id) + +{ + encoder->openElement(ELEM_SYNTAX); + encoder->writeSignedInteger(ATTRIB_CLOSE, id); + encoder->writeString(ATTRIB_CONTENT,paren); + encoder->closeElement(ELEM_SYNTAX); + parenlevel -= 1; +} + +void EmitMarkup::setOutputStream(ostream *t) + +{ + if (encoder != (Encoder *)0) + delete encoder; + s = t; + encoder = new XmlEncode(*s); } int4 TokenSplit::countbase = 0; @@ -363,7 +296,7 @@ int4 TokenSplit::countbase = 0; /// The API method matching the token type is called, feeding it content contained in /// the object. /// \param emit is the low-level emitter to output to -void TokenSplit::print(EmitXml *emit) const +void TokenSplit::print(Emit *emit) const { switch(tagtype) { @@ -410,34 +343,34 @@ void TokenSplit::print(EmitXml *emit) const emit->endFuncProto(count); break; case vari_t: // tagVariable - emit->tagVariable(tok.c_str(),hl,ptr_second.vn,op); + emit->tagVariable(tok,hl,ptr_second.vn,op); break; case op_t: // tagOp - emit->tagOp(tok.c_str(),hl,op); + emit->tagOp(tok,hl,op); break; case fnam_t: // tagFuncName - emit->tagFuncName(tok.c_str(),hl,ptr_second.fd,op); + emit->tagFuncName(tok,hl,ptr_second.fd,op); break; case type_t: // tagType - emit->tagType(tok.c_str(),hl,ptr_second.ct); + emit->tagType(tok,hl,ptr_second.ct); break; case field_t: // tagField - emit->tagField(tok.c_str(),hl,ptr_second.ct,(int4)off,op); + emit->tagField(tok,hl,ptr_second.ct,(int4)off,op); break; case comm_t: // tagComment - emit->tagComment(tok.c_str(),hl,ptr_second.spc,off); + emit->tagComment(tok,hl,ptr_second.spc,off); break; case label_t: // tagLabel - emit->tagLabel(tok.c_str(),hl,ptr_second.spc,off); + emit->tagLabel(tok,hl,ptr_second.spc,off); break; case synt_t: // print - emit->print(tok.c_str(),hl); + emit->print(tok,hl); break; case opar_t: // openParen - emit->openParen(tok[0],count); + emit->openParen(tok,count); break; case cpar_t: // closeParen - emit->closeParen(tok[0],count); + emit->closeParen(tok,count); break; case oinv_t: // Invisible open break; @@ -550,10 +483,10 @@ void TokenSplit::printDebug(ostream &s) const #endif EmitPrettyPrint::EmitPrettyPrint(void) - : EmitXml(), scanqueue( 3*100 ), tokqueue( 3*100 ) + : Emit(), scanqueue( 3*100 ), tokqueue( 3*100 ) { - lowlevel = new EmitNoXml(); // Do not emit xml by default + lowlevel = new EmitNoMarkup(); // Do not emit xml by default spaceremain = maxlinesize; needbreak = false; commentmode = false; @@ -614,7 +547,7 @@ void EmitPrettyPrint::overflow(void) spaceremain = newspaceremain; lowlevel->tagLine(maxlinesize-spaceremain); if (commentmode &&(commentfill.size() != 0)) { - lowlevel->print(commentfill.c_str(),EmitXml::comment_color); + lowlevel->print(commentfill,EmitMarkup::comment_color); spaceremain -= commentfill.size(); } } @@ -699,7 +632,7 @@ void EmitPrettyPrint::print(const TokenSplit &tok) } lowlevel->tagLine(maxlinesize-spaceremain); if (commentmode &&(commentfill.size() != 0)) { - lowlevel->print(commentfill.c_str(),EmitXml::comment_color); + lowlevel->print(commentfill,EmitMarkup::comment_color); spaceremain -= commentfill.size(); } } @@ -745,7 +678,7 @@ void EmitPrettyPrint::advanceleft(void) /// This is the heart of the pretty printing algorithm. The new token is assigned /// a size, the queue of open references and line breaks is updated. The amount /// of space currently available and the size of printing groups are updated. -/// If the current line is going to overflow, a decision is mode where in the uncommented +/// If the current line is going to overflow, a decision is made where in the uncommented /// tokens a line break needs to be inserted and what its indent level will be. If the /// leftmost print group closes without needing a line break, all the content it contains /// is \e committed and is sent to the low-level emitter. @@ -846,7 +779,7 @@ void EmitPrettyPrint::checkend(void) { if (!needbreak) { TokenSplit &tok( tokqueue.push() ); - tok.print("",EmitXml::no_color); // Add a blank string + tok.print(EMPTY_STRING,EmitMarkup::no_color); // Add a blank string scan(); } needbreak = true; @@ -860,7 +793,7 @@ void EmitPrettyPrint::checkbreak(void) { if (!needbreak) { TokenSplit &tok( tokqueue.push() ); - tok.print("",EmitXml::no_color); // Add a blank string + tok.print(EMPTY_STRING,EmitMarkup::no_color); // Add a blank string scan(); } needbreak = false; @@ -1021,95 +954,95 @@ void EmitPrettyPrint::endFuncProto(int4 id) scan(); } -void EmitPrettyPrint::tagVariable(const char *ptr,syntax_highlight hl, - const Varnode *vn,const PcodeOp *op) -{ - checkstring(); - TokenSplit &tok( tokqueue.push() ); - tok.tagVariable(ptr,hl,vn,op); - scan(); -} - -void EmitPrettyPrint::tagOp(const char *ptr,syntax_highlight hl,const PcodeOp *op) +void EmitPrettyPrint::tagVariable(const string &name,syntax_highlight hl,const Varnode *vn,const PcodeOp *op) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.tagOp(ptr,hl,op); + tok.tagVariable(name,hl,vn,op); scan(); } -void EmitPrettyPrint::tagFuncName(const char *ptr,syntax_highlight hl,const Funcdata *fd,const PcodeOp *op) +void EmitPrettyPrint::tagOp(const string &name,syntax_highlight hl,const PcodeOp *op) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.tagFuncName(ptr,hl,fd,op); + tok.tagOp(name,hl,op); scan(); } -void EmitPrettyPrint::tagType(const char *ptr,syntax_highlight hl,const Datatype *ct) +void EmitPrettyPrint::tagFuncName(const string &name,syntax_highlight hl,const Funcdata *fd,const PcodeOp *op) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.tagType(ptr,hl,ct); + tok.tagFuncName(name,hl,fd,op); scan(); } -void EmitPrettyPrint::tagField(const char *ptr,syntax_highlight hl,const Datatype *ct,int4 o,const PcodeOp *op) +void EmitPrettyPrint::tagType(const string &name,syntax_highlight hl,const Datatype *ct) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.tagField(ptr,hl,ct,o,op); + tok.tagType(name,hl,ct); scan(); } -void EmitPrettyPrint::tagComment(const char *ptr,syntax_highlight hl, - const AddrSpace *spc,uintb off) -{ - checkstring(); - TokenSplit &tok( tokqueue.push() ); - tok.tagComment(ptr,hl,spc,off); - scan(); -} - -void EmitPrettyPrint::tagLabel(const char *ptr,syntax_highlight hl, - const AddrSpace *spc,uintb off) -{ - checkstring(); - TokenSplit &tok( tokqueue.push() ); - tok.tagLabel(ptr,hl,spc,off); - scan(); -} - -void EmitPrettyPrint::print(const char *str,syntax_highlight hl) +void EmitPrettyPrint::tagField(const string &name,syntax_highlight hl,const Datatype *ct,int4 o,const PcodeOp *op) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.print(str,hl); + tok.tagField(name,hl,ct,o,op); scan(); } -int4 EmitPrettyPrint::openParen(char o,int4 id) +void EmitPrettyPrint::tagComment(const string &name,syntax_highlight hl,const AddrSpace *spc,uintb off) + +{ + checkstring(); + TokenSplit &tok( tokqueue.push() ); + tok.tagComment(name,hl,spc,off); + scan(); +} + +void EmitPrettyPrint::tagLabel(const string &name,syntax_highlight hl,const AddrSpace *spc,uintb off) + +{ + checkstring(); + TokenSplit &tok( tokqueue.push() ); + tok.tagLabel(name,hl,spc,off); + scan(); +} + +void EmitPrettyPrint::print(const string &data,syntax_highlight hl) + +{ + checkstring(); + TokenSplit &tok( tokqueue.push() ); + tok.print(data,hl); + scan(); +} + +int4 EmitPrettyPrint::openParen(const string &paren,int4 id) { id = openGroup(); // Open paren automatically opens group TokenSplit &tok( tokqueue.push() ); - tok.openParen(o,id); + tok.openParen(paren,id); scan(); needbreak = true; return id; } -void EmitPrettyPrint::closeParen(char c,int4 id) +void EmitPrettyPrint::closeParen(const string &paren,int4 id) { checkstring(); TokenSplit &tok( tokqueue.push() ); - tok.closeParen(c,id); + tok.closeParen(paren,id); scan(); closeGroup(id); } @@ -1155,7 +1088,7 @@ void EmitPrettyPrint::stopComment(int4 id) void EmitPrettyPrint::clear(void) { - EmitXml::clear(); + Emit::clear(); lowlevel->clear(); indentstack.clear(); scanqueue.clear(); @@ -1212,18 +1145,18 @@ void EmitPrettyPrint::flush(void) lowlevel->flush(); } -/// This method toggles the low-level emitter between EmitXml and EmitNoXml depending -/// on whether XML markup is desired. -/// \param val is \b true if XML markup is desired -void EmitPrettyPrint::setXML(bool val) +/// This method toggles the low-level emitter between EmitMarkup and EmitNoMarkup depending +/// on whether markup is desired. +/// \param val is \b true if markup is desired +void EmitPrettyPrint::setMarkup(bool val) { ostream *t = lowlevel->getOutputStream(); delete lowlevel; if (val) - lowlevel = new EmitXml; + lowlevel = new EmitMarkup; else - lowlevel = new EmitNoXml; + lowlevel = new EmitNoMarkup; lowlevel->setOutputStream(t); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.hh index 418e582da8..adabf2b255 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/prettyprint.hh @@ -28,11 +28,30 @@ class Funcdata; class Symbol; class PendPrint; -/// \brief Base class (and interface) for pretty printing and XML markup of tokens +extern AttributeId ATTRIB_BLOCKREF; ///< Marshaling attribute "blockref" +extern AttributeId ATTRIB_CLOSE; ///< Marshaling attribute "close" +extern AttributeId ATTRIB_COLOR; ///< Marshaling attribute "color" +extern AttributeId ATTRIB_INDENT; ///< Marshaling attribute "indent" +extern AttributeId ATTRIB_OFF; ///< Marshaling attribute "off" +extern AttributeId ATTRIB_OPEN; ///< Marshaling attribute "open" +extern AttributeId ATTRIB_OPREF; ///< Marshaling attribute "opref" +extern AttributeId ATTRIB_VARREF; ///< Marshaling attribute "varref" +extern ElementId ELEM_BREAK; ///< Marshaling element \ +extern ElementId ELEM_CLANG_DOCUMENT; ///< Marshaling element \ +extern ElementId ELEM_FUNCNAME; ///< Marshaling element \ +extern ElementId ELEM_FUNCPROTO; ///< Marshaling element \ +extern ElementId ELEM_LABEL; ///< Marshaling element \