GP-2262 Encoder

This commit is contained in:
caheckman 2022-07-12 19:07:37 -04:00
parent ae79857b42
commit aa038c3636
96 changed files with 2701 additions and 2484 deletions

View file

@ -29,46 +29,48 @@ vector<ArchitectureCapability *> ArchitectureCapability::thelist;
const uint4 ArchitectureCapability::majorversion = 4;
const uint4 ArchitectureCapability::minorversion = 1;
AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",30);
AttributeId ATTRIB_ENABLE = AttributeId("enable",31);
AttributeId ATTRIB_GROUP = AttributeId("group",32);
AttributeId ATTRIB_GROWTH = AttributeId("growth",33);
AttributeId ATTRIB_LOADERSYMBOLS = AttributeId("loadersymbols",34);
AttributeId ATTRIB_PARENT = AttributeId("parent",35);
AttributeId ATTRIB_REGISTER = AttributeId("register",36);
AttributeId ATTRIB_REVERSEJUSTIFY = AttributeId("reversejustify",37);
AttributeId ATTRIB_SIGNEXT = AttributeId("signext",38);
AttributeId ATTRIB_STYLE = AttributeId("style",39);
AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",103);
AttributeId ATTRIB_ENABLE = AttributeId("enable",104);
AttributeId ATTRIB_GROUP = AttributeId("group",105);
AttributeId ATTRIB_GROWTH = AttributeId("growth",106);
AttributeId ATTRIB_KEY = AttributeId("key",107);
AttributeId ATTRIB_LOADERSYMBOLS = AttributeId("loadersymbols",108);
AttributeId ATTRIB_PARENT = AttributeId("parent",109);
AttributeId ATTRIB_REGISTER = AttributeId("register",110);
AttributeId ATTRIB_REVERSEJUSTIFY = AttributeId("reversejustify",111);
AttributeId ATTRIB_SIGNEXT = AttributeId("signext",112);
AttributeId ATTRIB_STYLE = AttributeId("style",113);
ElementId ELEM_ADDRESS_SHIFT_AMOUNT = ElementId("address_shift_amount",17);
ElementId ELEM_AGGRESSIVETRIM = ElementId("aggressivetrim",18);
ElementId ELEM_COMPILER_SPEC = ElementId("compiler_spec",19);
ElementId ELEM_DATA_SPACE = ElementId("data_space",20);
ElementId ELEM_DEFAULT_MEMORY_BLOCKS = ElementId("default_memory_blocks",21);
ElementId ELEM_DEFAULT_PROTO = ElementId("default_proto",22);
ElementId ELEM_DEFAULT_SYMBOLS = ElementId("default_symbols",23);
ElementId ELEM_EVAL_CALLED_PROTOTYPE = ElementId("eval_called_prototype",24);
ElementId ELEM_EVAL_CURRENT_PROTOTYPE = ElementId("eval_current_prototype",25);
ElementId ELEM_EXPERIMENTAL_RULES = ElementId("experimental_rules",26);
ElementId ELEM_FLOWOVERRIDELIST = ElementId("flowoverridelist",27);
ElementId ELEM_FUNCPTR = ElementId("funcptr",28);
ElementId ELEM_GLOBAL = ElementId("global",29);
ElementId ELEM_INCIDENTALCOPY = ElementId("incidentalcopy",30);
ElementId ELEM_INFERPTRBOUNDS = ElementId("inferptrbounds",31);
ElementId ELEM_MODELALIAS = ElementId("modelalias",32);
ElementId ELEM_NOHIGHPTR = ElementId("nohighptr",33);
ElementId ELEM_PROCESSOR_SPEC = ElementId("processor_spec",34);
ElementId ELEM_PROGRAMCOUNTER = ElementId("programcounter",35);
ElementId ELEM_PROPERTIES = ElementId("properties",36);
ElementId ELEM_READONLY = ElementId("readonly",37);
ElementId ELEM_REGISTER_DATA = ElementId("register_data",38);
ElementId ELEM_RULE = ElementId("rule",39);
ElementId ELEM_SAVE_STATE = ElementId("save_state",40);
ElementId ELEM_SEGMENTED_ADDRESS = ElementId("segmented_address",41);
ElementId ELEM_SPACEBASE = ElementId("spacebase",42);
ElementId ELEM_SPECEXTENSIONS = ElementId("specextensions",43);
ElementId ELEM_STACKPOINTER = ElementId("stackpointer",44);
ElementId ELEM_VOLATILE = ElementId("volatile",45);
ElementId ELEM_ADDRESS_SHIFT_AMOUNT = ElementId("address_shift_amount",130);
ElementId ELEM_AGGRESSIVETRIM = ElementId("aggressivetrim",131);
ElementId ELEM_COMPILER_SPEC = ElementId("compiler_spec",132);
ElementId ELEM_DATA_SPACE = ElementId("data_space",133);
ElementId ELEM_DEFAULT_MEMORY_BLOCKS = ElementId("default_memory_blocks",134);
ElementId ELEM_DEFAULT_PROTO = ElementId("default_proto",135);
ElementId ELEM_DEFAULT_SYMBOLS = ElementId("default_symbols",136);
ElementId ELEM_EVAL_CALLED_PROTOTYPE = ElementId("eval_called_prototype",137);
ElementId ELEM_EVAL_CURRENT_PROTOTYPE = ElementId("eval_current_prototype",138);
ElementId ELEM_EXPERIMENTAL_RULES = ElementId("experimental_rules",139);
ElementId ELEM_FLOWOVERRIDELIST = ElementId("flowoverridelist",140);
ElementId ELEM_FUNCPTR = ElementId("funcptr",141);
ElementId ELEM_GLOBAL = ElementId("global",142);
ElementId ELEM_INCIDENTALCOPY = ElementId("incidentalcopy",143);
ElementId ELEM_INFERPTRBOUNDS = ElementId("inferptrbounds",144);
ElementId ELEM_MODELALIAS = ElementId("modelalias",145);
ElementId ELEM_NOHIGHPTR = ElementId("nohighptr",146);
ElementId ELEM_PROCESSOR_SPEC = ElementId("processor_spec",147);
ElementId ELEM_PROGRAMCOUNTER = ElementId("programcounter",148);
ElementId ELEM_PROPERTIES = ElementId("properties",149);
ElementId ELEM_PROPERTY = ElementId("property",150);
ElementId ELEM_READONLY = ElementId("readonly",151);
ElementId ELEM_REGISTER_DATA = ElementId("register_data",152);
ElementId ELEM_RULE = ElementId("rule",153);
ElementId ELEM_SAVE_STATE = ElementId("save_state",154);
ElementId ELEM_SEGMENTED_ADDRESS = ElementId("segmented_address",155);
ElementId ELEM_SPACEBASE = ElementId("spacebase",156);
ElementId ELEM_SPECEXTENSIONS = ElementId("specextensions",157);
ElementId ELEM_STACKPOINTER = ElementId("stackpointer",158);
ElementId ELEM_VOLATILE = ElementId("volatile",159);
/// This builds a list of just the ArchitectureCapability extensions
void ArchitectureCapability::initialize(void)

View file

@ -65,6 +65,7 @@ extern AttributeId ATTRIB_ADJUSTVMA; ///< Marshaling attribute "adjustvma"
extern AttributeId ATTRIB_ENABLE; ///< Marshaling attribute "enable"
extern AttributeId ATTRIB_GROUP; ///< Marshaling attribute "group"
extern AttributeId ATTRIB_GROWTH; ///< Marshaling attribute "growth"
extern AttributeId ATTRIB_KEY; ///< Marshaling attribute "key"
extern AttributeId ATTRIB_LOADERSYMBOLS; ///< Marshaling attribute "loadersymbols"
extern AttributeId ATTRIB_PARENT; ///< Marshaling attribute "parent"
extern AttributeId ATTRIB_REGISTER; ///< Marshaling attribute "register"
@ -92,6 +93,7 @@ extern ElementId ELEM_NOHIGHPTR; ///< Marshaling element \<nohighptr>
extern ElementId ELEM_PROCESSOR_SPEC; ///< Marshaling element \<processor_spec>
extern ElementId ELEM_PROGRAMCOUNTER; ///< Marshaling element \<programcounter>
extern ElementId ELEM_PROPERTIES; ///< Marshaling element \<properties>
extern ElementId ELEM_PROPERTY; ///< Marshaling element \<property>
extern ElementId ELEM_READONLY; ///< Marshaling element \<readonly>
extern ElementId ELEM_REGISTER_DATA; ///< Marshaling element \<register_data>
extern ElementId ELEM_RULE; ///< Marshaling element \<rule>

View file

@ -19,7 +19,7 @@
// Constructing this object registers capability
BfdArchitectureCapability BfdArchitectureCapability::bfdArchitectureCapability;
ElementId ELEM_BFD_SAVEFILE = ElementId("bfd_savefile",46);
ElementId ELEM_BFD_SAVEFILE = ElementId("bfd_savefile",238);
BfdArchitectureCapability::BfdArchitectureCapability(void)

View file

@ -17,16 +17,16 @@
#include "block.hh"
#include "funcdata.hh"
AttributeId ATTRIB_ALTINDEX = AttributeId("altindex",40);
AttributeId ATTRIB_DEPTH = AttributeId("depth",41);
AttributeId ATTRIB_END = AttributeId("end",42);
AttributeId ATTRIB_OPCODE = AttributeId("opcode",43);
AttributeId ATTRIB_REV = AttributeId("rev",44);
AttributeId ATTRIB_ALTINDEX = AttributeId("altindex",75);
AttributeId ATTRIB_DEPTH = AttributeId("depth",76);
AttributeId ATTRIB_END = AttributeId("end",77);
AttributeId ATTRIB_OPCODE = AttributeId("opcode",78);
AttributeId ATTRIB_REV = AttributeId("rev",79);
ElementId ELEM_BHEAD = ElementId("bhead",47);
ElementId ELEM_BLOCK = ElementId("block",48);
ElementId ELEM_BLOCKEDGE = ElementId("blockedge",49);
ElementId ELEM_EDGE = ElementId("edge",50);
ElementId ELEM_BHEAD = ElementId("bhead",102);
ElementId ELEM_BLOCK = ElementId("block",103);
ElementId ELEM_BLOCKEDGE = ElementId("blockedge",104);
ElementId ELEM_EDGE = ElementId("edge",105);
/// The edge is saved assuming we already know what block we are in.
/// \param encoder is the stream encoder

View file

@ -16,8 +16,8 @@
#include "callgraph.hh"
#include "funcdata.hh"
ElementId ELEM_CALLGRAPH = ElementId("callgraph",51);
ElementId ELEM_NODE = ElementId("node",52);
ElementId ELEM_CALLGRAPH = ElementId("callgraph",226);
ElementId ELEM_NODE = ElementId("node",227);
void CallGraphEdge::encode(Encoder &encoder) const

View file

@ -16,9 +16,9 @@
#include "comment.hh"
#include "funcdata.hh"
ElementId ELEM_COMMENT = ElementId("comment",53);
ElementId ELEM_COMMENTDB = ElementId("commentdb",54);
ElementId ELEM_TEXT = ElementId("text",55);
ElementId ELEM_COMMENT = ElementId("comment",86);
ElementId ELEM_COMMENTDB = ElementId("commentdb",87);
ElementId ELEM_TEXT = ElementId("text",88);
/// \param tp is the set of properties to associate with the comment (or 0 for no properties)
/// \param fad is the Address of the function containing the comment

View file

@ -15,15 +15,15 @@
*/
#include "cpool.hh"
AttributeId ATTRIB_A = AttributeId("a",45);
AttributeId ATTRIB_B = AttributeId("b",46);
AttributeId ATTRIB_LENGTH = AttributeId("length",47);
AttributeId ATTRIB_TAG = AttributeId("tag",48);
AttributeId ATTRIB_A = AttributeId("a",80);
AttributeId ATTRIB_B = AttributeId("b",81);
AttributeId ATTRIB_LENGTH = AttributeId("length",82);
AttributeId ATTRIB_TAG = AttributeId("tag",83);
ElementId ELEM_CONSTANTPOOL = ElementId("constantpool",56);
ElementId ELEM_CPOOLREC = ElementId("cpoolrec",57);
ElementId ELEM_REF = ElementId("ref",58);
ElementId ELEM_TOKEN = ElementId("token",59);
ElementId ELEM_CONSTANTPOOL = ElementId("constantpool",109);
ElementId ELEM_CPOOLREC = ElementId("cpoolrec",110);
ElementId ELEM_REF = ElementId("ref",111);
ElementId ELEM_TOKEN = ElementId("token",112);
/// Encode the constant pool object description as a \<cpoolrec> element.
/// \param encoder is the stream encoder

View file

@ -18,27 +18,27 @@
#include "crc32.hh"
#include <ctype.h>
AttributeId ATTRIB_CAT = AttributeId("cat",49);
AttributeId ATTRIB_FIELD = AttributeId("field",50);
AttributeId ATTRIB_MERGE = AttributeId("merge",51);
AttributeId ATTRIB_SCOPEIDBYNAME = AttributeId("scopeidbyname",52);
AttributeId ATTRIB_VOLATILE = AttributeId("volatile",53);
AttributeId ATTRIB_CAT = AttributeId("cat",61);
AttributeId ATTRIB_FIELD = AttributeId("field",62);
AttributeId ATTRIB_MERGE = AttributeId("merge",63);
AttributeId ATTRIB_SCOPEIDBYNAME = AttributeId("scopeidbyname",64);
AttributeId ATTRIB_VOLATILE = AttributeId("volatile",65);
ElementId ELEM_COLLISION = ElementId("collision",60);
ElementId ELEM_DB = ElementId("db",61);
ElementId ELEM_EQUATESYMBOL = ElementId("equatesymbol",62);
ElementId ELEM_EXTERNREFSYMBOL = ElementId("externrefsymbol",63);
ElementId ELEM_FACETSYMBOL = ElementId("facetsymbol",64);
ElementId ELEM_FUNCTIONSHELL = ElementId("functionshell",65);
ElementId ELEM_HASH = ElementId("hash",66);
ElementId ELEM_HOLE = ElementId("hole",67);
ElementId ELEM_LABELSYM = ElementId("labelsym",68);
ElementId ELEM_MAPSYM = ElementId("mapsym",69);
ElementId ELEM_PARENT = ElementId("parent",70);
ElementId ELEM_PROPERTY_CHANGEPOINT = ElementId("property_changepoint",71);
ElementId ELEM_RANGEEQUALSSYMBOLS = ElementId("rangeequalssymbols",72);
ElementId ELEM_SCOPE = ElementId("scope",73);
ElementId ELEM_SYMBOLLIST = ElementId("symbollist",74);
ElementId ELEM_COLLISION = ElementId("collision",67);
ElementId ELEM_DB = ElementId("db",68);
ElementId ELEM_EQUATESYMBOL = ElementId("equatesymbol",69);
ElementId ELEM_EXTERNREFSYMBOL = ElementId("externrefsymbol",70);
ElementId ELEM_FACETSYMBOL = ElementId("facetsymbol",71);
ElementId ELEM_FUNCTIONSHELL = ElementId("functionshell",72);
ElementId ELEM_HASH = ElementId("hash",73);
ElementId ELEM_HOLE = ElementId("hole",74);
ElementId ELEM_LABELSYM = ElementId("labelsym",75);
ElementId ELEM_MAPSYM = ElementId("mapsym",76);
ElementId ELEM_PARENT = ElementId("parent",77);
ElementId ELEM_PROPERTY_CHANGEPOINT = ElementId("property_changepoint",78);
ElementId ELEM_RANGEEQUALSSYMBOLS = ElementId("rangeequalssymbols",79);
ElementId ELEM_SCOPE = ElementId("scope",80);
ElementId ELEM_SYMBOLLIST = ElementId("symbollist",81);
uint8 Symbol::ID_BASE = 0x4000000000000000L;

View file

@ -16,37 +16,37 @@
#include "fspec.hh"
#include "funcdata.hh"
AttributeId ATTRIB_CUSTOM = AttributeId("custom",54);
AttributeId ATTRIB_DOTDOTDOT = AttributeId("dotdotdot",55);
AttributeId ATTRIB_EXTENSION = AttributeId("extension",56);
AttributeId ATTRIB_HASTHIS = AttributeId("hasthis",57);
AttributeId ATTRIB_INLINE = AttributeId("inline",58);
AttributeId ATTRIB_KILLEDBYCALL = AttributeId("killedbycall",59);
AttributeId ATTRIB_MAXSIZE = AttributeId("maxsize",60);
AttributeId ATTRIB_MINSIZE = AttributeId("minsize",61);
AttributeId ATTRIB_MODELLOCK = AttributeId("modellock",62);
AttributeId ATTRIB_NORETURN = AttributeId("noreturn",63);
AttributeId ATTRIB_POINTERMAX = AttributeId("pointermax",64);
AttributeId ATTRIB_SEPARATEFLOAT = AttributeId("separatefloat",65);
AttributeId ATTRIB_STACKSHIFT = AttributeId("stackshift",66);
AttributeId ATTRIB_STRATEGY = AttributeId("strategy",67);
AttributeId ATTRIB_THISBEFORERETPOINTER = AttributeId("thisbeforeretpointer",68);
AttributeId ATTRIB_VOIDLOCK = AttributeId("voidlock",69);
AttributeId ATTRIB_CUSTOM = AttributeId("custom",114);
AttributeId ATTRIB_DOTDOTDOT = AttributeId("dotdotdot",115);
AttributeId ATTRIB_EXTENSION = AttributeId("extension",116);
AttributeId ATTRIB_HASTHIS = AttributeId("hasthis",117);
AttributeId ATTRIB_INLINE = AttributeId("inline",118);
AttributeId ATTRIB_KILLEDBYCALL = AttributeId("killedbycall",119);
AttributeId ATTRIB_MAXSIZE = AttributeId("maxsize",120);
AttributeId ATTRIB_MINSIZE = AttributeId("minsize",121);
AttributeId ATTRIB_MODELLOCK = AttributeId("modellock",122);
AttributeId ATTRIB_NORETURN = AttributeId("noreturn",123);
AttributeId ATTRIB_POINTERMAX = AttributeId("pointermax",124);
AttributeId ATTRIB_SEPARATEFLOAT = AttributeId("separatefloat",125);
AttributeId ATTRIB_STACKSHIFT = AttributeId("stackshift",126);
AttributeId ATTRIB_STRATEGY = AttributeId("strategy",127);
AttributeId ATTRIB_THISBEFORERETPOINTER = AttributeId("thisbeforeretpointer",128);
AttributeId ATTRIB_VOIDLOCK = AttributeId("voidlock",129);
ElementId ELEM_GROUP = ElementId("group",75);
ElementId ELEM_INTERNALLIST = ElementId("internallist",76);
ElementId ELEM_KILLEDBYCALL = ElementId("killedbycall",77);
ElementId ELEM_LIKELYTRASH = ElementId("likelytrash",78);
ElementId ELEM_LOCALRANGE = ElementId("localrange",79);
ElementId ELEM_MODEL = ElementId("model",80);
ElementId ELEM_PARAM = ElementId("param",81);
ElementId ELEM_PARAMRANGE = ElementId("paramrange",82);
ElementId ELEM_PENTRY = ElementId("pentry",83);
ElementId ELEM_PROTOTYPE = ElementId("prototype",84);
ElementId ELEM_RESOLVEPROTOTYPE = ElementId("resolveprototype",85);
ElementId ELEM_RETPARAM = ElementId("retparam",86);
ElementId ELEM_RETURNSYM = ElementId("returnsym",87);
ElementId ELEM_UNAFFECTED = ElementId("unaffected",88);
ElementId ELEM_GROUP = ElementId("group",160);
ElementId ELEM_INTERNALLIST = ElementId("internallist",161);
ElementId ELEM_KILLEDBYCALL = ElementId("killedbycall",162);
ElementId ELEM_LIKELYTRASH = ElementId("likelytrash",163);
ElementId ELEM_LOCALRANGE = ElementId("localrange",164);
ElementId ELEM_MODEL = ElementId("model",165);
ElementId ELEM_PARAM = ElementId("param",166);
ElementId ELEM_PARAMRANGE = ElementId("paramrange",167);
ElementId ELEM_PENTRY = ElementId("pentry",168);
ElementId ELEM_PROTOTYPE = ElementId("prototype",169);
ElementId ELEM_RESOLVEPROTOTYPE = ElementId("resolveprototype",170);
ElementId ELEM_RETPARAM = ElementId("retparam",171);
ElementId ELEM_RETURNSYM = ElementId("returnsym",172);
ElementId ELEM_UNAFFECTED = ElementId("unaffected",173);
/// \brief Find a ParamEntry matching the given storage Varnode
///

View file

@ -15,13 +15,13 @@
*/
#include "funcdata.hh"
AttributeId ATTRIB_NOCODE = AttributeId("nocode",70);
AttributeId ATTRIB_NOCODE = AttributeId("nocode",84);
ElementId ELEM_AST = ElementId("ast",89);
ElementId ELEM_FUNCTION = ElementId("function",90);
ElementId ELEM_HIGHLIST = ElementId("highlist",91);
ElementId ELEM_JUMPTABLELIST = ElementId("jumptablelist",92);
ElementId ELEM_VARNODES = ElementId("varnodes",93);
ElementId ELEM_AST = ElementId("ast",115);
ElementId ELEM_FUNCTION = ElementId("function",116);
ElementId ELEM_HIGHLIST = ElementId("highlist",117);
ElementId ELEM_JUMPTABLELIST = ElementId("jumptablelist",118);
ElementId ELEM_VARNODES = ElementId("varnodes",119);
/// \param nm is the (base) name of the function
/// \param scope is Symbol scope associated with the function

View file

@ -63,7 +63,7 @@ void connect_to_console(Funcdata *fd)
#endif
ElementId ELEM_DOC = ElementId("doc",218);
ElementId ELEM_DOC = ElementId("doc",229);
vector<ArchitectureGhidra *> archlist; // List of architectures currently running

View file

@ -15,13 +15,13 @@
*/
#include "globalcontext.hh"
ElementId ELEM_CONTEXT_DATA = ElementId("context_data",94);
ElementId ELEM_CONTEXT_POINTS = ElementId("context_points",95);
ElementId ELEM_CONTEXT_POINTSET = ElementId("context_pointset",96);
ElementId ELEM_CONTEXT_SET = ElementId("context_set",97);
ElementId ELEM_SET = ElementId("set",98);
ElementId ELEM_TRACKED_POINTSET = ElementId("tracked_pointset",99);
ElementId ELEM_TRACKED_SET = ElementId("tracked_set",100);
ElementId ELEM_CONTEXT_DATA = ElementId("context_data",120);
ElementId ELEM_CONTEXT_POINTS = ElementId("context_points",121);
ElementId ELEM_CONTEXT_POINTSET = ElementId("context_pointset",122);
ElementId ELEM_CONTEXT_SET = ElementId("context_set",123);
ElementId ELEM_SET = ElementId("set",124);
ElementId ELEM_TRACKED_POINTSET = ElementId("tracked_pointset",125);
ElementId ELEM_TRACKED_SET = ElementId("tracked_set",126);
/// Bits within the whole context blob are labeled starting with 0 as the most significant bit
/// in the first word in the sequence. The new context value must be contained within a single

View file

@ -17,16 +17,16 @@
#include "emulate.hh"
#include "flow.hh"
AttributeId ATTRIB_LABEL = AttributeId("label",71);
AttributeId ATTRIB_NUM = AttributeId("num",72);
AttributeId ATTRIB_LABEL = AttributeId("label",131);
AttributeId ATTRIB_NUM = AttributeId("num",132);
ElementId ELEM_BASICOVERRIDE = ElementId("basicoverride",101);
ElementId ELEM_DEST = ElementId("dest",102);
ElementId ELEM_JUMPTABLE = ElementId("jumptable",103);
ElementId ELEM_LOADTABLE = ElementId("loadtable",104);
ElementId ELEM_NORMADDR = ElementId("normaddr",105);
ElementId ELEM_NORMHASH = ElementId("normhash",106);
ElementId ELEM_STARTVAL = ElementId("startval",107);
ElementId ELEM_BASICOVERRIDE = ElementId("basicoverride",211);
ElementId ELEM_DEST = ElementId("dest",212);
ElementId ELEM_JUMPTABLE = ElementId("jumptable",213);
ElementId ELEM_LOADTABLE = ElementId("loadtable",214);
ElementId ELEM_NORMADDR = ElementId("normaddr",215);
ElementId ELEM_NORMHASH = ElementId("normhash",216);
ElementId ELEM_STARTVAL = ElementId("startval",217);
/// \param encoder is the stream encoder
void LoadTable::encode(Encoder &encoder) const

View file

@ -16,10 +16,10 @@
#include "loadimage_xml.hh"
#include "translate.hh"
AttributeId ATTRIB_ARCH = AttributeId("arch",73);
AttributeId ATTRIB_ARCH = AttributeId("arch",135);
ElementId ELEM_BINARYIMAGE = ElementId("binaryimage",108);
ElementId ELEM_BYTECHUNK = ElementId("bytechunk",109);
ElementId ELEM_BINARYIMAGE = ElementId("binaryimage",230);
ElementId ELEM_BYTECHUNK = ElementId("bytechunk",231);
/// \param f is the (path to the) underlying XML file
/// \param el is the parsed form of the file

View file

@ -500,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",147); // Number serves as next open index
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",148); // Number serves as next open index
ElementId ELEM_DATA = ElementId("data",1);
ElementId ELEM_INPUT = ElementId("input",2);
@ -513,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",231); // Number serves as next open index
ElementId ELEM_UNKNOWN = ElementId("XMLunknown",251); // Number serves as next open index

View file

@ -16,7 +16,8 @@
#include "op.hh"
#include "funcdata.hh"
ElementId ELEM_IOP = ElementId("iop",110);
ElementId ELEM_IOP = ElementId("iop",113);
ElementId ELEM_UNIMPL = ElementId("unimpl",114);
const string IopSpace::NAME = "iop";

View file

@ -21,6 +21,7 @@
#include "typeop.hh"
extern ElementId ELEM_IOP; ///< Marshaling element \<iop>
extern ElementId ELEM_UNIMPL; ///< Marshaling element \<unimpl>
/// \brief Space for storing internal PcodeOp pointers as addresses
///

View file

@ -18,43 +18,43 @@
#include "flow.hh"
#include "printc.hh"
ElementId ELEM_ALIASBLOCK = ElementId("aliasblock",111);
ElementId ELEM_ALLOWCONTEXTSET = ElementId("allowcontextset",112);
ElementId ELEM_ANALYZEFORLOOPS = ElementId("analyzeforloops",113);
ElementId ELEM_COMMENTHEADER = ElementId("commentheader",114);
ElementId ELEM_COMMENTINDENT = ElementId("commentindent",115);
ElementId ELEM_COMMENTINSTRUCTION = ElementId("commentinstruction",116);
ElementId ELEM_COMMENTSTYLE = ElementId("commentstyle",117);
ElementId ELEM_CONVENTIONPRINTING = ElementId("conventionprinting",118);
ElementId ELEM_CURRENTACTION = ElementId("currentaction",119);
ElementId ELEM_DEFAULTPROTOTYPE = ElementId("defaultprototype",120);
ElementId ELEM_ERRORREINTERPRETED = ElementId("errorreinterpreted",121);
ElementId ELEM_ERRORTOOMANYINSTRUCTIONS = ElementId("errortoomanyinstructions",122);
ElementId ELEM_ERRORUNIMPLEMENTED = ElementId("errorunimplemented",123);
ElementId ELEM_EXTRAPOP = ElementId("extrapop",124);
ElementId ELEM_IGNOREUNIMPLEMENTED = ElementId("ignoreunimplemented",125);
ElementId ELEM_INDENTINCREMENT = ElementId("indentincrement",126);
ElementId ELEM_INFERCONSTPTR = ElementId("inferconstptr",127);
ElementId ELEM_INLINE = ElementId("inline",128);
ElementId ELEM_INPLACEOPS = ElementId("inplaceops",129);
ElementId ELEM_INTEGERFORMAT = ElementId("integerformat",130);
ElementId ELEM_JUMPLOAD = ElementId("jumpload",131);
ElementId ELEM_MAXINSTRUCTION = ElementId("maxinstruction",132);
ElementId ELEM_MAXLINEWIDTH = ElementId("maxlinewidth",133);
ElementId ELEM_NAMESPACESTRATEGY = ElementId("namespacestrategy",134);
ElementId ELEM_NOCASTPRINTING = ElementId("nocastprinting",135);
ElementId ELEM_NORETURN = ElementId("noreturn",136);
ElementId ELEM_NULLPRINTING = ElementId("nullprinting",137);
ElementId ELEM_OPTIONSLIST = ElementId("optionslist",138);
ElementId ELEM_PARAM1 = ElementId("param1",139);
ElementId ELEM_PARAM2 = ElementId("param2",140);
ElementId ELEM_PARAM3 = ElementId("param3",141);
ElementId ELEM_PROTOEVAL = ElementId("protoeval",142);
ElementId ELEM_SETACTION = ElementId("setaction",143);
ElementId ELEM_SETLANGUAGE = ElementId("setlanguage",144);
ElementId ELEM_STRUCTALIGN = ElementId("structalign",145);
ElementId ELEM_TOGGLERULE = ElementId("togglerule",146);
ElementId ELEM_WARNING = ElementId("warning",147);
ElementId ELEM_ALIASBLOCK = ElementId("aliasblock",174);
ElementId ELEM_ALLOWCONTEXTSET = ElementId("allowcontextset",175);
ElementId ELEM_ANALYZEFORLOOPS = ElementId("analyzeforloops",176);
ElementId ELEM_COMMENTHEADER = ElementId("commentheader",177);
ElementId ELEM_COMMENTINDENT = ElementId("commentindent",178);
ElementId ELEM_COMMENTINSTRUCTION = ElementId("commentinstruction",179);
ElementId ELEM_COMMENTSTYLE = ElementId("commentstyle",180);
ElementId ELEM_CONVENTIONPRINTING = ElementId("conventionprinting",181);
ElementId ELEM_CURRENTACTION = ElementId("currentaction",182);
ElementId ELEM_DEFAULTPROTOTYPE = ElementId("defaultprototype",183);
ElementId ELEM_ERRORREINTERPRETED = ElementId("errorreinterpreted",184);
ElementId ELEM_ERRORTOOMANYINSTRUCTIONS = ElementId("errortoomanyinstructions",185);
ElementId ELEM_ERRORUNIMPLEMENTED = ElementId("errorunimplemented",186);
ElementId ELEM_EXTRAPOP = ElementId("extrapop",187);
ElementId ELEM_IGNOREUNIMPLEMENTED = ElementId("ignoreunimplemented",188);
ElementId ELEM_INDENTINCREMENT = ElementId("indentincrement",189);
ElementId ELEM_INFERCONSTPTR = ElementId("inferconstptr",190);
ElementId ELEM_INLINE = ElementId("inline",191);
ElementId ELEM_INPLACEOPS = ElementId("inplaceops",192);
ElementId ELEM_INTEGERFORMAT = ElementId("integerformat",193);
ElementId ELEM_JUMPLOAD = ElementId("jumpload",194);
ElementId ELEM_MAXINSTRUCTION = ElementId("maxinstruction",195);
ElementId ELEM_MAXLINEWIDTH = ElementId("maxlinewidth",196);
ElementId ELEM_NAMESPACESTRATEGY = ElementId("namespacestrategy",197);
ElementId ELEM_NOCASTPRINTING = ElementId("nocastprinting",198);
ElementId ELEM_NORETURN = ElementId("noreturn",199);
ElementId ELEM_NULLPRINTING = ElementId("nullprinting",200);
ElementId ELEM_OPTIONSLIST = ElementId("optionslist",201);
ElementId ELEM_PARAM1 = ElementId("param1",202);
ElementId ELEM_PARAM2 = ElementId("param2",203);
ElementId ELEM_PARAM3 = ElementId("param3",204);
ElementId ELEM_PROTOEVAL = ElementId("protoeval",205);
ElementId ELEM_SETACTION = ElementId("setaction",206);
ElementId ELEM_SETLANGUAGE = ElementId("setlanguage",207);
ElementId ELEM_STRUCTALIGN = ElementId("structalign",208);
ElementId ELEM_TOGGLERULE = ElementId("togglerule",209);
ElementId ELEM_WARNING = ElementId("warning",210);
/// If the parameter is "on" return \b true, if "off" return \b false.
/// Any other value causes an exception.

View file

@ -16,13 +16,13 @@
#include "override.hh"
#include "funcdata.hh"
ElementId ELEM_DEADCODEDELAY = ElementId("deadcodedelay",148);
ElementId ELEM_FLOW = ElementId("flow",149);
ElementId ELEM_FORCEGOTO = ElementId("forcegoto",150);
ElementId ELEM_INDIRECTOVERRIDE = ElementId("indirectoverride",151);
ElementId ELEM_MULTISTAGEJUMP = ElementId("multistagejump",152);
ElementId ELEM_OVERRIDE = ElementId("override",153);
ElementId ELEM_PROTOOVERRIDE = ElementId("protooverride",154);
ElementId ELEM_DEADCODEDELAY = ElementId("deadcodedelay",218);
ElementId ELEM_FLOW = ElementId("flow",219);
ElementId ELEM_FORCEGOTO = ElementId("forcegoto",220);
ElementId ELEM_INDIRECTOVERRIDE = ElementId("indirectoverride",221);
ElementId ELEM_MULTISTAGEJUMP = ElementId("multistagejump",222);
ElementId ELEM_OVERRIDE = ElementId("override",223);
ElementId ELEM_PROTOOVERRIDE = ElementId("protooverride",224);
void Override::clear(void)

View file

@ -15,9 +15,9 @@
*/
#include "paramid.hh"
ElementId ELEM_PARAMMEASURES = ElementId("parammeasures",155);
ElementId ELEM_PROTO = ElementId("proto",156);
ElementId ELEM_RANK = ElementId("rank",157);
ElementId ELEM_PARAMMEASURES = ElementId("parammeasures",106);
ElementId ELEM_PROTO = ElementId("proto",107);
ElementId ELEM_RANK = ElementId("rank",108);
// NOTES FROM 20121206 W/Decompiler-Man
// direct reads is for all opcodes, with special for these:

View file

@ -16,25 +16,25 @@
#include "pcodeinject.hh"
#include "architecture.hh"
AttributeId ATTRIB_DYNAMIC = AttributeId("dynamic",74);
AttributeId ATTRIB_INCIDENTALCOPY = AttributeId("incidentalcopy",75);
AttributeId ATTRIB_INJECT = AttributeId("inject",76);
AttributeId ATTRIB_PARAMSHIFT = AttributeId("paramshift",77);
AttributeId ATTRIB_TARGETOP = AttributeId("targetop",78);
AttributeId ATTRIB_DYNAMIC = AttributeId("dynamic",70);
AttributeId ATTRIB_INCIDENTALCOPY = AttributeId("incidentalcopy",71);
AttributeId ATTRIB_INJECT = AttributeId("inject",72);
AttributeId ATTRIB_PARAMSHIFT = AttributeId("paramshift",73);
AttributeId ATTRIB_TARGETOP = AttributeId("targetop",74);
ElementId ELEM_ADDR_PCODE = ElementId("addr_pcode",158);
ElementId ELEM_BODY = ElementId("body",159);
ElementId ELEM_CALLFIXUP = ElementId("callfixup",160);
ElementId ELEM_CALLOTHERFIXUP = ElementId("callotherfixup",161);
ElementId ELEM_CASE_PCODE = ElementId("case_pcode",162);
ElementId ELEM_CONTEXT = ElementId("context",163);
ElementId ELEM_DEFAULT_PCODE = ElementId("default_pcode",164);
ElementId ELEM_INJECT = ElementId("inject",165);
ElementId ELEM_INJECTDEBUG = ElementId("injectdebug",166);
ElementId ELEM_INST = ElementId("inst",167);
ElementId ELEM_PAYLOAD = ElementId("payload",168);
ElementId ELEM_PCODE = ElementId("pcode",169);
ElementId ELEM_SIZE_PCODE = ElementId("size_pcode",170);
ElementId ELEM_ADDR_PCODE = ElementId("addr_pcode",89);
ElementId ELEM_BODY = ElementId("body",90);
ElementId ELEM_CALLFIXUP = ElementId("callfixup",91);
ElementId ELEM_CALLOTHERFIXUP = ElementId("callotherfixup",92);
ElementId ELEM_CASE_PCODE = ElementId("case_pcode",93);
ElementId ELEM_CONTEXT = ElementId("context",94);
ElementId ELEM_DEFAULT_PCODE = ElementId("default_pcode",95);
ElementId ELEM_INJECT = ElementId("inject",96);
ElementId ELEM_INJECTDEBUG = ElementId("injectdebug",97);
ElementId ELEM_INST = ElementId("inst",98);
ElementId ELEM_PAYLOAD = ElementId("payload",99);
ElementId ELEM_PCODE = ElementId("pcode",100);
ElementId ELEM_SIZE_PCODE = ElementId("size_pcode",101);
/// \brief Parse an \<input> or \<output> element describing an injection parameter
///

View file

@ -16,7 +16,7 @@
#include "prefersplit.hh"
#include "funcdata.hh"
ElementId ELEM_PREFERSPLIT = ElementId("prefersplit",171);
ElementId ELEM_PREFERSPLIT = ElementId("prefersplit",225);
bool PreferSplitRecord::operator<(const PreferSplitRecord &op2) const

View file

@ -16,24 +16,24 @@
#include "prettyprint.hh"
#include "funcdata.hh"
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);
AttributeId ATTRIB_BLOCKREF = AttributeId("blockref",35);
AttributeId ATTRIB_CLOSE = AttributeId("close",36);
AttributeId ATTRIB_COLOR = AttributeId("color",37);
AttributeId ATTRIB_INDENT = AttributeId("indent",38);
AttributeId ATTRIB_OFF = AttributeId("off",39);
AttributeId ATTRIB_OPEN = AttributeId("open",40);
AttributeId ATTRIB_OPREF = AttributeId("opref",41);
AttributeId ATTRIB_VARREF = AttributeId("varref",42);
ElementId ELEM_BREAK = ElementId("break",17);
ElementId ELEM_CLANG_DOCUMENT = ElementId("clang_document",18);
ElementId ELEM_FUNCNAME = ElementId("funcname",19);
ElementId ELEM_FUNCPROTO = ElementId("funcproto",20);
ElementId ELEM_LABEL = ElementId("label",21);
ElementId ELEM_RETURN_TYPE = ElementId("return_type",22);
ElementId ELEM_STATEMENT = ElementId("statement",23);
ElementId ELEM_SYNTAX = ElementId("syntax",24);
ElementId ELEM_VARDECL = ElementId("vardecl",25);
ElementId ELEM_VARIABLE = ElementId("variable",26);
const string Emit::EMPTY_STRING = "";

View file

@ -15,7 +15,7 @@
*/
#include "raw_arch.hh"
ElementId ELEM_RAW_SAVEFILE = ElementId("raw_savefile",172);
ElementId ELEM_RAW_SAVEFILE = ElementId("raw_savefile",237);
// Constructing this object registers the capability
RawBinaryArchitectureCapability RawBinaryArchitectureCapability::rawBinaryArchitectureCapability;

View file

@ -16,20 +16,20 @@
#include "sleigh_arch.hh"
#include "inject_sleigh.hh"
AttributeId ATTRIB_DEPRECATED = AttributeId("deprecated",79);
AttributeId ATTRIB_ENDIAN = AttributeId("endian",80);
AttributeId ATTRIB_PROCESSOR = AttributeId("processor",81);
AttributeId ATTRIB_PROCESSORSPEC = AttributeId("processorspec",82);
AttributeId ATTRIB_SLAFILE = AttributeId("slafile",83);
AttributeId ATTRIB_SPEC = AttributeId("spec",84);
AttributeId ATTRIB_TARGET = AttributeId("target",85);
AttributeId ATTRIB_VARIANT = AttributeId("variant",86);
AttributeId ATTRIB_VERSION = AttributeId("version",87);
AttributeId ATTRIB_DEPRECATED = AttributeId("deprecated",136);
AttributeId ATTRIB_ENDIAN = AttributeId("endian",137);
AttributeId ATTRIB_PROCESSOR = AttributeId("processor",138);
AttributeId ATTRIB_PROCESSORSPEC = AttributeId("processorspec",139);
AttributeId ATTRIB_SLAFILE = AttributeId("slafile",140);
AttributeId ATTRIB_SPEC = AttributeId("spec",141);
AttributeId ATTRIB_TARGET = AttributeId("target",142);
AttributeId ATTRIB_VARIANT = AttributeId("variant",143);
AttributeId ATTRIB_VERSION = AttributeId("version",144);
ElementId ELEM_COMPILER = ElementId("compiler",173);
ElementId ELEM_DESCRIPTION = ElementId("description",174);
ElementId ELEM_LANGUAGE = ElementId("language",175);
ElementId ELEM_LANGUAGE_DEFINITIONS = ElementId("language_definitions",176);
ElementId ELEM_COMPILER = ElementId("compiler",232);
ElementId ELEM_DESCRIPTION = ElementId("description",233);
ElementId ELEM_LANGUAGE = ElementId("language",234);
ElementId ELEM_LANGUAGE_DEFINITIONS = ElementId("language_definitions",235);
map<int4,Sleigh *> SleighArchitecture::translators;
vector<LanguageDescription> SleighArchitecture::description;

View file

@ -16,20 +16,20 @@
#include "space.hh"
#include "translate.hh"
AttributeId ATTRIB_BASE = AttributeId("base",88);
AttributeId ATTRIB_DEADCODEDELAY = AttributeId("deadcodedelay",89);
AttributeId ATTRIB_DELAY = AttributeId("delay", 90);
AttributeId ATTRIB_LOGICALSIZE = AttributeId("logicalsize",91);
AttributeId ATTRIB_PHYSICAL = AttributeId("physical",92);
AttributeId ATTRIB_PIECE1 = AttributeId("piece1",93); // piece attributes must have sequential ids
AttributeId ATTRIB_PIECE2 = AttributeId("piece2",94);
AttributeId ATTRIB_PIECE3 = AttributeId("piece3",95);
AttributeId ATTRIB_PIECE4 = AttributeId("piece4",96);
AttributeId ATTRIB_PIECE5 = AttributeId("piece5",97);
AttributeId ATTRIB_PIECE6 = AttributeId("piece6",98);
AttributeId ATTRIB_PIECE7 = AttributeId("piece7",99);
AttributeId ATTRIB_PIECE8 = AttributeId("piece8",100);
AttributeId ATTRIB_PIECE9 = AttributeId("piece9",101);
AttributeId ATTRIB_BASE = AttributeId("base",89);
AttributeId ATTRIB_DEADCODEDELAY = AttributeId("deadcodedelay",90);
AttributeId ATTRIB_DELAY = AttributeId("delay", 91);
AttributeId ATTRIB_LOGICALSIZE = AttributeId("logicalsize",92);
AttributeId ATTRIB_PHYSICAL = AttributeId("physical",93);
AttributeId ATTRIB_PIECE1 = AttributeId("piece1",94); // piece attributes must have sequential ids
AttributeId ATTRIB_PIECE2 = AttributeId("piece2",95);
AttributeId ATTRIB_PIECE3 = AttributeId("piece3",96);
AttributeId ATTRIB_PIECE4 = AttributeId("piece4",97);
AttributeId ATTRIB_PIECE5 = AttributeId("piece5",98);
AttributeId ATTRIB_PIECE6 = AttributeId("piece6",99);
AttributeId ATTRIB_PIECE7 = AttributeId("piece7",100);
AttributeId ATTRIB_PIECE8 = AttributeId("piece8",101);
AttributeId ATTRIB_PIECE9 = AttributeId("piece9",102);
/// Calculate \e highest based on \e addressSize, and \e wordsize.
/// This also calculates the default pointerLowerBound

View file

@ -16,11 +16,11 @@
#include "stringmanage.hh"
#include "architecture.hh"
AttributeId ATTRIB_TRUNC = AttributeId("trunc",102);
AttributeId ATTRIB_TRUNC = AttributeId("trunc",69);
ElementId ELEM_BYTES = ElementId("bytes",177);
ElementId ELEM_STRING = ElementId("string",178);
ElementId ELEM_STRINGMANAGE = ElementId("stringmanage",179);
ElementId ELEM_BYTES = ElementId("bytes",83);
ElementId ELEM_STRING = ElementId("string",84);
ElementId ELEM_STRINGMANAGE = ElementId("stringmanage",85);
/// \param max is the maximum number of characters to allow before truncating string
StringManager::StringManager(int4 max)

View file

@ -16,7 +16,7 @@
#include "transform.hh"
#include "funcdata.hh"
AttributeId ATTRIB_VECTOR_LANE_SIZES = AttributeId("vector_lane_sizes",103);
AttributeId ATTRIB_VECTOR_LANE_SIZES = AttributeId("vector_lane_sizes",130);
/// \param op2 is the lane description to copy from
LaneDescription::LaneDescription(const LaneDescription &op2)

View file

@ -15,21 +15,21 @@
*/
#include "translate.hh"
AttributeId ATTRIB_CODE = AttributeId("code",104);
AttributeId ATTRIB_CONTAIN = AttributeId("contain",105);
AttributeId ATTRIB_DEFAULTSPACE = AttributeId("defaultspace",106);
AttributeId ATTRIB_UNIQBASE = AttributeId("uniqbase",107);
AttributeId ATTRIB_CODE = AttributeId("code",43);
AttributeId ATTRIB_CONTAIN = AttributeId("contain",44);
AttributeId ATTRIB_DEFAULTSPACE = AttributeId("defaultspace",45);
AttributeId ATTRIB_UNIQBASE = AttributeId("uniqbase",46);
ElementId ELEM_OP = ElementId("op",180);
ElementId ELEM_SLEIGH = ElementId("sleigh",181);
ElementId ELEM_SPACE = ElementId("space",182);
ElementId ELEM_SPACEID = ElementId("spaceid",183);
ElementId ELEM_SPACES = ElementId("spaces",184);
ElementId ELEM_SPACE_BASE = ElementId("space_base",185);
ElementId ELEM_SPACE_OTHER = ElementId("space_other",186);
ElementId ELEM_SPACE_OVERLAY = ElementId("space_overlay",187);
ElementId ELEM_SPACE_UNIQUE = ElementId("space_unique",188);
ElementId ELEM_TRUNCATE_SPACE = ElementId("truncate_space",189);
ElementId ELEM_OP = ElementId("op",27);
ElementId ELEM_SLEIGH = ElementId("sleigh",28);
ElementId ELEM_SPACE = ElementId("space",29);
ElementId ELEM_SPACEID = ElementId("spaceid",30);
ElementId ELEM_SPACES = ElementId("spaces",31);
ElementId ELEM_SPACE_BASE = ElementId("space_base",32);
ElementId ELEM_SPACE_OTHER = ElementId("space_other",33);
ElementId ELEM_SPACE_OVERLAY = ElementId("space_overlay",34);
ElementId ELEM_SPACE_UNIQUE = ElementId("space_unique",35);
ElementId ELEM_TRUNCATE_SPACE = ElementId("truncate_space",36);
/// Parse a \<truncate_space> element to configure \b this object
/// \param decoder is the stream decoder

View file

@ -23,33 +23,51 @@ sub_metatype Datatype::base2sub[14] = {
SUB_UINT_PLAIN, SUB_INT_PLAIN, SUB_UNKNOWN, SUB_SPACEBASE, SUB_VOID
};
AttributeId ATTRIB_ALIGNMENT = AttributeId("alignment",108);
AttributeId ATTRIB_ARRAYSIZE = AttributeId("arraysize",109);
AttributeId ATTRIB_CHAR = AttributeId("char",110);
AttributeId ATTRIB_CORE = AttributeId("core",111);
AttributeId ATTRIB_ENUM = AttributeId("enum",112);
AttributeId ATTRIB_ENUMSIGNED = AttributeId("enumsigned",113);
AttributeId ATTRIB_ENUMSIZE = AttributeId("enumsize",114);
AttributeId ATTRIB_INTSIZE = AttributeId("intsize",115);
AttributeId ATTRIB_LONGSIZE = AttributeId("longsize",116);
AttributeId ATTRIB_OPAQUESTRING = AttributeId("opaquestring",117);
AttributeId ATTRIB_SIGNED = AttributeId("signed",118);
AttributeId ATTRIB_STRUCTALIGN = AttributeId("structalign",119);
AttributeId ATTRIB_UTF = AttributeId("utf",120);
AttributeId ATTRIB_VARLENGTH = AttributeId("varlength",121);
AttributeId ATTRIB_ALIGNMENT = AttributeId("alignment",47);
AttributeId ATTRIB_ARRAYSIZE = AttributeId("arraysize",48);
AttributeId ATTRIB_CHAR = AttributeId("char",49);
AttributeId ATTRIB_CORE = AttributeId("core",50);
AttributeId ATTRIB_ENUM = AttributeId("enum",51);
AttributeId ATTRIB_ENUMSIGNED = AttributeId("enumsigned",52);
AttributeId ATTRIB_ENUMSIZE = AttributeId("enumsize",53);
AttributeId ATTRIB_INTSIZE = AttributeId("intsize",54);
AttributeId ATTRIB_LONGSIZE = AttributeId("longsize",55);
AttributeId ATTRIB_OPAQUESTRING = AttributeId("opaquestring",56);
AttributeId ATTRIB_SIGNED = AttributeId("signed",57);
AttributeId ATTRIB_STRUCTALIGN = AttributeId("structalign",58);
AttributeId ATTRIB_UTF = AttributeId("utf",59);
AttributeId ATTRIB_VARLENGTH = AttributeId("varlength",60);
ElementId ELEM_CORETYPES = ElementId("coretypes",190);
ElementId ELEM_DATA_ORGANIZATION = ElementId("data_organization",191);
ElementId ELEM_DEF = ElementId("def",192);
ElementId ELEM_ENTRY = ElementId("entry",193);
ElementId ELEM_ENUM = ElementId("enum",194);
ElementId ELEM_FIELD = ElementId("field",195);
ElementId ELEM_INTEGER_SIZE = ElementId("integer_size",196);
ElementId ELEM_LONG_SIZE = ElementId("long_size",197);
ElementId ELEM_SIZE_ALIGNMENT_MAP = ElementId("size_alignment_map",198);
ElementId ELEM_TYPE = ElementId("type",199);
ElementId ELEM_TYPEGRP = ElementId("typegrp",200);
ElementId ELEM_TYPEREF = ElementId("typeref",201);
//ElementId ELEM_ABSOLUTE_MAX_ALIGNMENT = ElementId("absolute_max_alignment", 37);
//ElementId ELEM_BITFIELD_PACKING = ElementId("bitfield_packing", 38);
//ElementId ELEM_CHAR_SIZE = ElementId("char_size", 39);
//ElementId ELEM_CHAR_TYPE = ElementId("char_type", 40);
ElementId ELEM_CORETYPES = ElementId("coretypes",41);
ElementId ELEM_DATA_ORGANIZATION = ElementId("data_organization", 42);
ElementId ELEM_DEF = ElementId("def",43);
//ElementId ELEM_DEFAULT_ALIGNMENT = ElementId("default_alignment", 44);
//ElementId ELEM_DEFAULT_POINTER_ALIGNMENT = ElementId("default_pointer_alignment", 45);
//ElementId ELEM_DOUBLE_SIZE = ElementId("double_size", 46);
ElementId ELEM_ENTRY = ElementId("entry",47);
ElementId ELEM_ENUM = ElementId("enum",48);
ElementId ELEM_FIELD = ElementId("field",49);
//ElementId ELEM_FLOAT_SIZE = ElementId("float_size", 50);
ElementId ELEM_INTEGER_SIZE = ElementId("integer_size",51);
//ElementId ELEM_LONG_DOUBLE_SIZE = ElementId("long_double_size", 52);
//ElementId ELEM_LONG_LONG_SIZE = ElementId("long_long_size", 53);
ElementId ELEM_LONG_SIZE = ElementId("long_size", 54);
//ElementId ELEM_MACHINE_ALIGNMENT = ElementId("machine_alignment", 55);
//ElementId ELEM_POINTER_SHIFT = ElementId("pointer_shift", 56);
//ElementId ELEM_POINTER_SIZE = ElementId("pointer_size", 57);
//ElementId ELEM_SHORT_SIZE = ElementId("short_size", 58);
ElementId ELEM_SIZE_ALIGNMENT_MAP = ElementId("size_alignment_map", 59);
ElementId ELEM_TYPE = ElementId("type",60);
//ElementId ELEM_TYPE_ALIGNMENT_ENABLED = ElementId("type_alignment_enabled", 61);
ElementId ELEM_TYPEGRP = ElementId("typegrp",62);
ElementId ELEM_TYPEREF = ElementId("typeref",63);
//ElementId ELEM_USE_MS_CONVENTION = ElementId("use_MS_convention", 64);
//ElementId ELEM_WCHAR_SIZE = ElementId("wchar_size", 65);
//ElementId ELEM_ZERO_LENGTH_BOUNDARY = ElementId("zero_length_boundary", 66);
// Some default routines for displaying data
@ -3344,7 +3362,7 @@ Datatype *TypeFactory::decodeType(Decoder &decoder)
if (attribId == ATTRIB_ID) {
newid = decoder.readUnsignedInteger();
}
else if (attribId == ATTRIB_ID) { // A "size" attribute indicates a "variable length" base
else if (attribId == ATTRIB_SIZE) { // A "size" attribute indicates a "variable length" base
size = decoder.readSignedInteger();
}
}

View file

@ -36,18 +36,36 @@ extern AttributeId ATTRIB_STRUCTALIGN; ///< Marshaling attribute "structalign"
extern AttributeId ATTRIB_UTF; ///< Marshaling attribute "utf"
extern AttributeId ATTRIB_VARLENGTH; ///< Marshaling attribute "varlength"
//extern ElementId ELEM_ABSOLUTE_MAX_ALIGNMENT; ///< Marshaling element \<absolute_max_alignment>
//extern ElementId ELEM_BITFIELD_PACKING; ///< Marshaling element \<bitfield_packing>
//extern ElementId ELEM_CHAR_SIZE; ///< Marshaling element \<char_size>
//extern ElementId ELEM_CHAR_TYPE; ///< Marshaling element \<char_type>
extern ElementId ELEM_CORETYPES; ///< Marshaling element \<coretypes>
extern ElementId ELEM_DATA_ORGANIZATION; ///< Marshaling element \<data_organization>
extern ElementId ELEM_DEF; ///< Marshaling element \<def>
//extern ElementId ELEM_DEFAULT_ALIGNMENT; ///< Marshaling element \<default_alignment>
//extern ElementId ELEM_DEFAULT_POINTER_ALIGNMENT; ///< Marshaling element \<default_pointer_alignment>
//extern ElementId ELEM_DOUBLE_SIZE; ///< Marshaling element \<double_size>
extern ElementId ELEM_ENTRY; ///< Marshaling element \<entry>
extern ElementId ELEM_ENUM; ///< Marshaling element \<enum>
extern ElementId ELEM_FIELD; ///< Marshaling element \<field>
//extern ElementId ELEM_FLOAT_SIZE; ///< Marshaling element \<float_size>
extern ElementId ELEM_INTEGER_SIZE; ///< Marshaling element \<integer_size>
//extern ElementId ELEM_LONG_DOUBLE_SIZE; ///< Marshaling element \<long_double_size>
//extern ElementId ELEM_LONG_LONG_SIZE; ///< Marshaling element \<long_long_size>
extern ElementId ELEM_LONG_SIZE; ///< Marshaling element \<long_size>
//extern ElementId ELEM_MACHINE_ALIGNMENT; ///< Marshaling element \<machine_alignment>
//extern ElementId ELEM_POINTER_SHIFT; ///< Marshaling element \<pointer_shift>
//extern ElementId ELEM_POINTER_SIZE; ///< Marshaling element \<pointer_size>
//extern ElementId ELEM_SHORT_SIZE; ///< Marshaling element \<short_size>
extern ElementId ELEM_SIZE_ALIGNMENT_MAP; ///< Marshaling element \<size_alignment_map>
extern ElementId ELEM_TYPE; ///< Marshaling element \<type>
//extern ElementId ELEM_TYPE_ALIGNMENT_ENABLED; ///< Marshaling element \<type_alignment_enabled>
extern ElementId ELEM_TYPEGRP; ///< Marshaling element \<typegrp>
extern ElementId ELEM_TYPEREF; ///< Marshaling element \<typeref>
//extern ElementId ELEM_USE_MS_CONVENTION; ///< Marshaling element \<use_MS_convention>
//extern ElementId ELEM_WCHAR_SIZE; ///< Marshaling element \<wchar_size>
//extern ElementId ELEM_ZERO_LENGTH_BOUNDARY; ///< Marshaling element \<zero_length_boundary>
/// Print a hex dump of a data buffer to stream
extern void print_data(ostream &s,uint1 *buffer,int4 size,const Address &baseaddr);

View file

@ -16,14 +16,14 @@
#include "userop.hh"
#include "funcdata.hh"
AttributeId ATTRIB_FARPOINTER = AttributeId("farpointer",122);
AttributeId ATTRIB_INPUTOP = AttributeId("inputop",123);
AttributeId ATTRIB_OUTPUTOP = AttributeId("outputop",124);
AttributeId ATTRIB_USEROP = AttributeId("userop",125);
AttributeId ATTRIB_FARPOINTER = AttributeId("farpointer",85);
AttributeId ATTRIB_INPUTOP = AttributeId("inputop",86);
AttributeId ATTRIB_OUTPUTOP = AttributeId("outputop",87);
AttributeId ATTRIB_USEROP = AttributeId("userop",88);
ElementId ELEM_CONSTRESOLVE = ElementId("constresolve",202);
ElementId ELEM_JUMPASSIST = ElementId("jumpassist",203);
ElementId ELEM_SEGMENTOP = ElementId("segmentop",204);
ElementId ELEM_CONSTRESOLVE = ElementId("constresolve",127);
ElementId ELEM_JUMPASSIST = ElementId("jumpassist",128);
ElementId ELEM_SEGMENTOP = ElementId("segmentop",129);
void InjectedUserOp::decode(Decoder &decoder)

View file

@ -17,11 +17,11 @@
#include "op.hh"
#include "database.hh"
AttributeId ATTRIB_CLASS = AttributeId("class",126);
AttributeId ATTRIB_REPREF = AttributeId("repref",127);
AttributeId ATTRIB_SYMREF = AttributeId("symref",128);
AttributeId ATTRIB_CLASS = AttributeId("class",66);
AttributeId ATTRIB_REPREF = AttributeId("repref",67);
AttributeId ATTRIB_SYMREF = AttributeId("symref",68);
ElementId ELEM_HIGH = ElementId("high",205);
ElementId ELEM_HIGH = ElementId("high",82);
/// The new instance starts off with no associate Symbol and all properties marked as \e dirty.
/// \param vn is the single Varnode member

View file

@ -16,10 +16,10 @@
#include "varmap.hh"
#include "funcdata.hh"
AttributeId ATTRIB_LOCK = AttributeId("lock",129);
AttributeId ATTRIB_MAIN = AttributeId("main",130);
AttributeId ATTRIB_LOCK = AttributeId("lock",133);
AttributeId ATTRIB_MAIN = AttributeId("main",134);
ElementId ELEM_LOCALDB = ElementId("localdb",206);
ElementId ELEM_LOCALDB = ElementId("localdb",228);
/// \brief Can the given intersecting RangeHint coexist with \b this at their given offsets
///

View file

@ -16,11 +16,11 @@
#include "varnode.hh"
#include "funcdata.hh"
AttributeId ATTRIB_ADDRTIED = AttributeId("addrtied",131);
AttributeId ATTRIB_GRP = AttributeId("grp",132);
AttributeId ATTRIB_INPUT = AttributeId("input",133);
AttributeId ATTRIB_PERSISTS = AttributeId("persists",134);
AttributeId ATTRIB_UNAFF = AttributeId("unaff",135);
AttributeId ATTRIB_ADDRTIED = AttributeId("addrtied",30);
AttributeId ATTRIB_GRP = AttributeId("grp",31);
AttributeId ATTRIB_INPUT = AttributeId("input",32);
AttributeId ATTRIB_PERSISTS = AttributeId("persists",33);
AttributeId ATTRIB_UNAFF = AttributeId("unaff",34);
/// Compare by location then by definition.
/// This is the same as the normal varnode compare, but we distinguish identical frees by their

View file

@ -15,7 +15,7 @@
*/
#include "xml_arch.hh"
ElementId ELEM_XML_SAVEFILE = ElementId("xml_savefile",207);
ElementId ELEM_XML_SAVEFILE = ElementId("xml_savefile",236);
// Constructing the singleton registers the capability
XmlArchitectureCapability XmlArchitectureCapability::xmlArchitectureCapability;

View file

@ -88,6 +88,7 @@ public class DecompInterface {
protected CompilerSpec compilerSpec;
protected DecompileProcess decompProcess;
protected DecompileCallback decompCallback;
protected Encoder encoder;
private DecompileDebug debug;
protected CancelledListener monitorListener = new CancelledListener() {
@Override
@ -110,6 +111,7 @@ public class DecompInterface {
dtmanage = null;
decompCallback = null;
xmlOptions = null;
encoder = null;
debug = null;
decompileMessage = "";
compilerSpec = null;
@ -213,16 +215,19 @@ public class DecompInterface {
decompProcess = DecompileProcessFactory.get();
}
long uniqueBase = UniqueLayout.SLEIGH_BASE.getOffset(pcodelanguage);
String tspec =
pcodelanguage.buildTranslatorTag(program.getAddressFactory(), uniqueBase, null);
String coretypes = dtmanage.buildCoreTypes();
encoder.clear();
pcodelanguage.encodeTranslator(encoder, program.getAddressFactory(), uniqueBase);
String tspec = encoder.toString();
encoder.clear();
dtmanage.encodeCoreTypes(encoder);
String coretypes = encoder.toString();
SleighLanguageDescription sleighdescription =
(SleighLanguageDescription) pcodelanguage.getLanguageDescription();
ResourceFile pspecfile = sleighdescription.getSpecFile();
String pspecxml = fileToString(pspecfile);
StringBuilder buffer = new StringBuilder();
compilerSpec.saveXml(buffer);
String cspecxml = buffer.toString();
XmlEncode xmlEncode = new XmlEncode();
compilerSpec.encode(xmlEncode);
String cspecxml = xmlEncode.toString();
decompCallback.setNativeMessage(null);
decompProcess.registerProgram(decompCallback, pspecxml, cspecxml, tspec, coretypes);
@ -317,6 +322,7 @@ public class DecompInterface {
compilerSpec = spec;
dtmanage = new PcodeDataTypeManager(prog);
encoder = new XmlEncode();
try {
decompCallback =
new DecompileCallback(prog, pcodelanguage, program.getCompilerSpec(), dtmanage);
@ -338,6 +344,7 @@ public class DecompInterface {
}
program = null;
decompCallback = null;
encoder = null;
return false;
}
@ -353,6 +360,7 @@ public class DecompInterface {
if (program != null) {
program = null;
decompCallback = null;
encoder = null;
try {
if ((decompProcess != null) && decompProcess.isReady()) {
decompProcess.deregisterProgram();
@ -661,17 +669,17 @@ public class DecompInterface {
LimitedByteBuffer res = null;
BlockGraph resgraph = null;
try {
StringWriter writer = new StringWriter();
ingraph.saveXml(writer);
encoder.clear();
ingraph.encode(encoder);
verifyProcess();
res = decompProcess.sendCommand1ParamTimeout("structureGraph", writer.toString(),
res = decompProcess.sendCommand1ParamTimeout("structureGraph", encoder.toString(),
timeoutSecs);
decompileMessage = decompCallback.getNativeMessage();
if (res != null) {
XmlDecode decoder = new XmlDecode(factory);
decoder.ingestStream(res.getInputStream(), "structureGraph results");
resgraph = new BlockGraph();
resgraph.restoreXml(decoder);
resgraph.decode(decoder);
resgraph.transferObjectRef(ingraph);
}
}
@ -718,10 +726,10 @@ public class DecompInterface {
debug.setFunction(func);
}
decompCallback.setFunction(func, funcEntry, debug);
StringBuilder addrBuf = new StringBuilder();
AddressXML.buildXML(addrBuf, funcEntry);
encoder.clear();
AddressXML.encode(encoder, funcEntry);
verifyProcess();
res = decompProcess.sendCommand1ParamTimeout("decompileAt", addrBuf.toString(),
res = decompProcess.sendCommand1ParamTimeout("decompileAt", encoder.toString(),
timeoutSecs);
decompileMessage = decompCallback.getNativeMessage();
}

View file

@ -16,16 +16,8 @@
package ghidra.app.decompiler;
import java.io.IOException;
import java.io.StringReader;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import ghidra.app.cmd.function.CallDepthChangeInfo;
import ghidra.docking.settings.Settings;
@ -44,7 +36,6 @@ import ghidra.util.UndefinedFunction;
import ghidra.util.exception.UsrException;
import ghidra.util.task.TaskMonitor;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.util.xml.XmlUtilities;
/**
*
@ -55,6 +46,7 @@ import ghidra.util.xml.XmlUtilities;
public class DecompileCallback {
public final static int MAX_SYMBOL_COUNT = 16;
public final static byte[] EMPTY_BYTE_ARRAY = new byte[0];
/**
* Data returned for a query about strings
@ -81,6 +73,7 @@ public class DecompileCallback {
private String nativeMessage;
private XmlDecodeLight lightDecoder;
private XmlEncode resultEncode;
private InstructionBlock lastPseudoInstructionBlock;
private Disassembler pseudoDisassembler;
@ -98,19 +91,7 @@ public class DecompileCallback {
debug = null;
utf8Charset = Charset.availableCharsets().get(CharsetInfo.UTF8);
lightDecoder = new XmlDecodeLight(addrfactory);
}
private static SAXParser getSAXParser() throws PcodeXMLException {
try {
SAXParserFactory saxParserFactory = XmlUtilities.createSecureSAXParserFactory(false);
saxParserFactory.setFeature("http://xml.org/sax/features/namespaces", false);
saxParserFactory.setFeature("http://xml.org/sax/features/validation", false);
return saxParserFactory.newSAXParser();
}
catch (Exception e) {
Msg.error(DecompileCallback.class, e.getMessage());
throw new PcodeXMLException("Failed to instantiate XML parser", e);
}
resultEncode = new XmlEncode();
}
/**
@ -156,20 +137,6 @@ public class DecompileCallback {
nativeMessage = msg;
}
public synchronized ArrayList<String> readXMLNameList(String xml) throws PcodeXMLException {
try {
NameListHandler nmHandler = new NameListHandler();
getSAXParser().parse(new InputSource(new StringReader(xml)), nmHandler);
return nmHandler.getList();
}
catch (SAXException e1) {
throw new PcodeXMLException("Problem parsing list string " + xml, e1);
}
catch (IOException e1) {
throw new PcodeXMLException("Problem parsing list string " + xml, e1);
}
}
public byte[] getBytes(String addrxml) {
try {
lightDecoder.ingestString(addrxml);
@ -218,9 +185,10 @@ public class DecompileCallback {
*
* @param addrstring is the XML rep of function address
* @param types is the string encoding of the comment type flags
* @return XML document describing comments
* @return Encoded description of comments
* @throws IOException for errors in the underlying stream
*/
public String getComments(String addrstring, String types) {
public byte[] getComments(String addrstring, String types) throws IOException {
Address addr;
int flags;
try {
@ -232,37 +200,21 @@ public class DecompileCallback {
}
catch (PcodeXMLException e) {
Msg.error(this, "Decompiling " + funcEntry + ": " + e.getMessage());
return null;
return EMPTY_BYTE_ARRAY;
}
flags = SpecXmlUtils.decodeInt(types);
Function func = getFunctionAt(addr);
if (func == null) {
return null;
return EMPTY_BYTE_ARRAY;
}
AddressSetView addrset = func.getBody();
StringBuilder buf = new StringBuilder();
buf.append("<commentdb>\n");
if ((flags & 8) != 0) {
generateHeaderCommentXML(func, buf);
}
if ((flags & 1) != 0) {
generateCommentXML(addrset, addr, buf, CodeUnit.EOL_COMMENT);
}
if ((flags & 2) != 0) {
generateCommentXML(addrset, addr, buf, CodeUnit.PRE_COMMENT);
}
if ((flags & 4) != 0) {
generateCommentXML(addrset, addr, buf, CodeUnit.POST_COMMENT);
}
if ((flags & 8) != 0) {
generateCommentXML(addrset, addr, buf, CodeUnit.PLATE_COMMENT);
}
buf.append("</commentdb>\n");
String res = buf.toString();
resultEncode.clear();
encodeComments(resultEncode, addr, func, flags);
if (debug != null) {
debug.getComments(res);
XmlEncode xmlEncode = new XmlEncode();
encodeComments(xmlEncode, addr, func, flags);
debug.getComments(xmlEncode.toString());
}
return res;
return resultEncode.getBytes();
}
public PackedBytes getPcodePacked(String addrstring) {
@ -314,45 +266,42 @@ public class DecompileCallback {
}
/**
* Build an XML representation of all the pcode op's a given Instruction is
* defined to perform.
* Encode a list of pcode, representing an entire Instruction, to the stream
*
* @param encoder is the stream encoder
* @param ops pcode ops
* @param fallthruoffset number of bytes after instruction start that pcode
* flow falls into
* @param paramshift special instructions for injection use
* @param addrFactory is the address factory for recovering address space names
* @return XML document as string representing all the p-code
* @throws IOException for errors in the underlying stream
*/
public static String buildInstruction(PcodeOp[] ops, int fallthruoffset, int paramshift,
AddressFactory addrFactory) {
StringBuilder resBuf = new StringBuilder();
public static void encodeInstruction(Encoder encoder, PcodeOp[] ops, int fallthruoffset,
int paramshift, AddressFactory addrFactory) throws IOException {
if ((ops.length == 1) && (ops[0].getOpcode() == PcodeOp.UNIMPLEMENTED)) {
resBuf.append("<unimpl");
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "offset", fallthruoffset);
resBuf.append("/>\n");
return resBuf.toString();
encoder.openElement(ElementId.ELEM_UNIMPL);
encoder.writeSignedInteger(AttributeId.ATTRIB_OFFSET, fallthruoffset);
encoder.closeElement(ElementId.ELEM_UNIMPL);
return;
}
resBuf.append("<inst");
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "offset", fallthruoffset);
encoder.openElement(ElementId.ELEM_INST);
encoder.writeSignedInteger(AttributeId.ATTRIB_OFFSET, fallthruoffset);
if (paramshift != 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "paramshift", paramshift);
encoder.writeSignedInteger(AttributeId.ATTRIB_PARAMSHIFT, paramshift);
}
resBuf.append('>');
for (PcodeOp op : ops) {
op.buildXML(resBuf, addrFactory);
op.encode(encoder, addrFactory);
}
resBuf.append("</inst>\n");
return resBuf.toString();
encoder.closeElement(ElementId.ELEM_INST);
}
public String getPcodeInject(String nm, String context, int type) {
public byte[] getPcodeInject(String nm, String context, int type) {
PcodeInjectLibrary snippetLibrary = pcodecompilerspec.getPcodeInjectLibrary();
InjectPayload payload = snippetLibrary.getPayload(type, nm);
if (payload == null) {
Msg.warn(this, "Decompiling " + funcEntry + ", no pcode inject with name: " + nm);
return null; // No fixup associated with this name
return EMPTY_BYTE_ARRAY; // No fixup associated with this name
}
InjectContext con = snippetLibrary.buildInjectContext();
PcodeOp[] pcode;
@ -362,7 +311,7 @@ public class DecompileCallback {
}
catch (PcodeXMLException e) {
Msg.error(this, "Decompiling " + funcEntry + ": " + e.getMessage());
return null;
return EMPTY_BYTE_ARRAY;
}
try {
int fallThruOffset;
@ -377,7 +326,7 @@ public class DecompileCallback {
if (instr == null) {
Msg.warn(this, "Decompiling " + funcEntry + ", pcode inject error at " +
con.baseAddr + ": instruction not found");
return null;
return EMPTY_BYTE_ARRAY;
}
// get next inst addr for inst_next pcode variable
@ -395,14 +344,18 @@ public class DecompileCallback {
}
pcode = payload.getPcode(program, con);
if (pcode == null) {
return null; // Just return a null string, which should let the decompiler exit gracefully
return EMPTY_BYTE_ARRAY; // Return without result, which should let the decompiler exit gracefully
}
String finalPayload =
buildInstruction(pcode, fallThruOffset, payload.getParamShift(), addrfactory);
resultEncode.clear();
encodeInstruction(resultEncode, pcode, fallThruOffset, payload.getParamShift(),
addrfactory);
if (debug != null) {
debug.addInject(con.baseAddr, nm, type, finalPayload);
XmlEncode xmlEncode = new XmlEncode();
encodeInstruction(xmlEncode, pcode, fallThruOffset, payload.getParamShift(),
addrfactory);
debug.addInject(con.baseAddr, nm, type, xmlEncode.toString());
}
return finalPayload;
return resultEncode.getBytes();
}
catch (UnknownInstructionException e) {
Msg.warn(this, "Decompiling " + funcEntry + ", pcode inject error at " + con.baseAddr +
@ -412,19 +365,22 @@ public class DecompileCallback {
Msg.error(this, "Decompiling " + funcEntry + ", pcode inject error at " + con.baseAddr +
": " + e.getMessage(), e);
}
return null;
return EMPTY_BYTE_ARRAY;
}
public String getCPoolRef(long[] refs) throws IOException {
public byte[] getCPoolRef(long[] refs) throws IOException {
if (cpool == null) {
cpool = pcodecompilerspec.getPcodeInjectLibrary().getConstantPool(program);
}
Record record = cpool.getRecord(refs);
String res = record.build(refs[0], dtmanage).toString();
resultEncode.clear();
record.encode(resultEncode, refs[0], dtmanage);
if (debug != null) {
debug.getCPoolRef(res, refs);
XmlEncode xmlEncode = new XmlEncode();
record.encode(xmlEncode, refs[0], dtmanage);
debug.getCPoolRef(xmlEncode.toString(), refs);
}
return res;
return resultEncode.getBytes();
}
private Instruction getInstruction(Address addr) throws UnknownInstructionException {
@ -614,46 +570,50 @@ public class DecompileCallback {
}
/**
* Return an XML description of the formal namespace path to the given namespace
* Write a description of the formal namespace path to the given namespace
* @param id is the ID of the given namespace
* @return a parent XML tag
* @return the encoded result
* @throws IOException for errors in the underlying stream
*/
public String getNamespacePath(long id) {
public byte[] getNamespacePath(long id) throws IOException {
Namespace namespace = getNameSpaceByID(id);
StringBuilder buf = new StringBuilder();
HighFunction.createNamespaceTag(buf, namespace);
resultEncode.clear();
HighFunction.encodeNamespace(resultEncode, namespace);
if (debug != null) {
debug.getNamespacePath(namespace);
}
return buf.toString();
return resultEncode.getBytes();
}
private void generateHeaderCommentXML(Function func, StringBuilder buf) {
private void encodeHeaderComment(Encoder encoder, Function func) throws IOException {
Address addr = func.getEntryPoint();
String text = listing.getComment(CodeUnit.PLATE_COMMENT, addr);
if (text != null) {
buf.append("<comment");
SpecXmlUtils.encodeStringAttribute(buf, "type", "header");
buf.append(">\n");
AddressXML.buildXML(buf, addr);
AddressXML.buildXML(buf, addr);
buf.append("\n<text>");
SpecXmlUtils.xmlEscape(buf, text);
buf.append("</text>\n");
buf.append("</comment>\n");
encoder.openElement(ElementId.ELEM_COMMENT);
encoder.writeString(AttributeId.ATTRIB_TYPE, "header");
AddressXML.encode(encoder, addr);
AddressXML.encode(encoder, addr);
encoder.openElement(ElementId.ELEM_TEXT);
encoder.writeString(AttributeId.ATTRIB_CONTENT, text);
encoder.closeElement(ElementId.ELEM_TEXT);
encoder.closeElement(ElementId.ELEM_COMMENT);
}
}
/**
* Generate XML for comments of a certain type
* Encode comments of a specific type to stream for a given address set. Comments are
* collected from the listing. The encoding associates the comment both with the address where
* it was placed, but also with the (entry point) address of the function containing it.
* Plate comments whose address matches the function entry point are not encoded.
*
* @param addrset = addresses over which to search for comments
* @param buf = StringBuilder where XML should be written
* @param commenttype = type of comment
* @param encoder is the stream encoder
* @param addrset is the address set over which to search
* @param addr is the entry point of the function
* @param commenttype is the type of comment
* @throws IOException for errors in the underlying stream
*/
private void generateCommentXML(AddressSetView addrset, Address addr, StringBuilder buf,
int commenttype) {
private void encodeCommentsType(Encoder encoder, AddressSetView addrset, Address addr,
int commenttype) throws IOException {
String typename;
switch (commenttype) {
case CodeUnit.EOL_COMMENT:
@ -684,29 +644,50 @@ public class DecompileCallback {
continue;
}
}
buf.append("<comment");
SpecXmlUtils.encodeStringAttribute(buf, "type", typename);
buf.append(">\n");
AddressXML.buildXML(buf, addr);
AddressXML.buildXML(buf, commaddr);
buf.append("\n<text>");
SpecXmlUtils.xmlEscape(buf, text);
buf.append("</text>\n");
buf.append("</comment>\n");
encoder.openElement(ElementId.ELEM_COMMENT);
encoder.writeString(AttributeId.ATTRIB_TYPE, typename);
AddressXML.encode(encoder, addr);
AddressXML.encode(encoder, commaddr);
encoder.openElement(ElementId.ELEM_TEXT);
encoder.writeString(AttributeId.ATTRIB_CONTENT, text);
encoder.closeElement(ElementId.ELEM_TEXT);
encoder.closeElement(ElementId.ELEM_COMMENT);
}
}
}
private void encodeComments(Encoder encoder, Address addr, Function func, int flags)
throws IOException {
AddressSetView addrset = func.getBody();
encoder.openElement(ElementId.ELEM_COMMENTDB);
if ((flags & 8) != 0) {
encodeHeaderComment(encoder, func);
}
if ((flags & 1) != 0) {
encodeCommentsType(encoder, addrset, addr, CodeUnit.EOL_COMMENT);
}
if ((flags & 2) != 0) {
encodeCommentsType(encoder, addrset, addr, CodeUnit.PRE_COMMENT);
}
if ((flags & 4) != 0) {
encodeCommentsType(encoder, addrset, addr, CodeUnit.POST_COMMENT);
}
if ((flags & 8) != 0) {
encodeCommentsType(encoder, addrset, addr, CodeUnit.PLATE_COMMENT);
}
encoder.closeElement(ElementId.ELEM_COMMENTDB);
}
/**
* Describe data or functions at addr.
* Called by the native decompiler to query the GHIDRA database about any
* symbols at the given address.
*
* @param addrstring XML encoded address to query
* @return XML encoded result. Either function, reference, datatype, or hole
* @return an encoded description, either function, reference, datatype, or hole
*/
public String getMappedSymbolsXML(String addrstring) { // Return XML describing data or functions at addr
public byte[] getMappedSymbolsXML(String addrstring) {
Address addr;
try {
lightDecoder.ingestString(addrstring);
@ -716,43 +697,50 @@ public class DecompileCallback {
}
if (addr == Address.NO_ADDRESS) {
// Unknown spaces may result from "spacebase" registers defined in cspec
return null;
return EMPTY_BYTE_ARRAY;
}
}
catch (PcodeXMLException e) {
Msg.error(this, "Decompiling " + funcEntry + ": " + e.getMessage());
return null;
return EMPTY_BYTE_ARRAY;
}
try {
String res = null;
Object obj = lookupSymbol(addr);
resultEncode.clear();
if (obj instanceof Function) {
boolean includeDefaults = addr.equals(funcEntry);
res = buildFunctionXML((Function) obj, addr, includeDefaults);
encodeFunction(resultEncode, (Function) obj, addr, includeDefaults);
}
else if (obj instanceof Data) {
res = buildData((Data) obj);
if (!encodeData(resultEncode, (Data) obj)) {
encodeHole(resultEncode, addr);
}
}
else if (obj instanceof ExternalReference) {
res = buildExternalRef(addr, (ExternalReference) obj);
encodeExternalRef(resultEncode, addr, (ExternalReference) obj);
}
else if (obj instanceof Symbol) {
res = buildLabel((Symbol) obj, addr);
encodeLabel(resultEncode, (Symbol) obj, addr);
}
if (res == null) { // There is a hole, describe the extent of the hole
res = buildHole(addr).toString();
else {
encodeHole(resultEncode, addr); // There is a hole, describe the extent of the hole
}
return res;
return resultEncode.getBytes();
}
catch (Exception e) {
Msg.error(this, "Decompiling " + funcEntry + ", mapped symbol error for " + addrstring +
": " + e.getMessage(), e);
}
return null;
return EMPTY_BYTE_ARRAY;
}
public String getExternalRefXML(String addrstring) { // Return any external reference at addr
/**
* Describe an external reference at the given address
* @param addrstring is the description of the address
* @return the encoded description
*/
public byte[] getExternalRefXML(String addrstring) {
Address addr;
try {
lightDecoder.ingestString(addrstring);
@ -763,7 +751,7 @@ public class DecompileCallback {
}
catch (PcodeXMLException e) {
Msg.error(this, "Decompiling " + funcEntry + ": " + e.getMessage());
return null;
return EMPTY_BYTE_ARRAY;
}
try {
@ -787,7 +775,9 @@ public class DecompileCallback {
}
HighSymbol shellSymbol =
new HighFunctionShellSymbol(extId, extRef.getLabel(), addr, dtmanage);
return buildResult(shellSymbol, null);
resultEncode.clear();
encodeResult(resultEncode, shellSymbol, null);
return resultEncode.getBytes();
}
}
else {
@ -796,7 +786,7 @@ public class DecompileCallback {
}
if (func == null) {
// Its conceivable we could have external data, but we aren't currently checking for it
return null;
return EMPTY_BYTE_ARRAY;
}
HighFunction hfunc = new HighFunction(func, pcodelanguage, pcodecompilerspec, dtmanage);
@ -810,38 +800,38 @@ public class DecompileCallback {
debug.getFNTypes(hfunc);
debug.addPossiblePrototypeExtension(func);
}
return buildResult(funcSymbol, namespc);
resultEncode.clear();
encodeResult(resultEncode, funcSymbol, namespc);
return resultEncode.getBytes();
}
catch (Exception e) {
Msg.error(this,
"Decompiling " + funcEntry + ", error in getExternalRefXML: " + e.getMessage(), e);
}
return null;
return EMPTY_BYTE_ARRAY;
}
public String getType(String name, long id) {
public byte[] getType(String name, long id) throws IOException {
DataType type = dtmanage.findBaseType(name, id);
if (type == null) {
return null;
return EMPTY_BYTE_ARRAY;
}
StringBuilder resBuf = new StringBuilder();
dtmanage.buildType(resBuf, type, 0);
resBuf.append("\n"); // Make into official XML document
String res = resBuf.toString();
resultEncode.clear();
dtmanage.encodeType(resultEncode, type, 0);
if (debug != null) {
debug.getType(type);
}
return res;
return resultEncode.getBytes();
}
public String getRegister(String name) {
public byte[] getRegister(String name) throws IOException {
Register reg = pcodelanguage.getRegister(name);
if (reg == null) {
throw new RuntimeException("No Register Defined: " + name);
}
StringBuilder resBuf = buildRegister(reg);
resBuf.append("\n");
return resBuf.toString();
resultEncode.clear();
encodeRegister(resultEncode, reg);
return resultEncode.getBytes();
}
public String getRegisterName(String addrstring) {
@ -852,7 +842,7 @@ public class DecompileCallback {
int size = (int) lightDecoder.readSignedInteger(AttributeId.ATTRIB_SIZE);
Register reg = pcodelanguage.getRegister(addr, size);
if (reg == null) {
return null;
return "";
}
return reg.getName();
}
@ -860,10 +850,10 @@ public class DecompileCallback {
Msg.error(this, "Decompiling " + funcEntry +
", error while searching for register name: " + e.getMessage(), e);
}
return null;
return "";
}
public String getTrackedRegisters(String addrstring) {
public byte[] getTrackedRegisters(String addrstring) throws IOException {
Address addr;
try {
lightDecoder.ingestString(addrstring);
@ -874,30 +864,18 @@ public class DecompileCallback {
}
catch (PcodeXMLException e) {
Msg.error(this, "Decompiling " + funcEntry + ": " + e.getMessage());
return null;
return EMPTY_BYTE_ARRAY;
}
ProgramContext context = program.getProgramContext();
StringBuilder stringBuf = new StringBuilder();
stringBuf.append("<tracked_pointset");
AddressXML.appendAttributes(stringBuf, addr);
stringBuf.append(">\n");
for (Register reg : context.getRegisters()) {
if (reg.isProcessorContext()) {
continue;
}
BigInteger val = context.getValue(reg, addr, false);
if (val != null) {
buildTrackSet(stringBuf, reg, val.longValue());
}
}
stringBuf.append("</tracked_pointset>\n");
String res = stringBuf.toString();
resultEncode.clear();
encodeTrackedPointSet(resultEncode, addr, context);
if (debug != null) {
debug.getTrackedRegisters(res);
XmlEncode xmlEncode = new XmlEncode();
encodeTrackedPointSet(xmlEncode, addr, context);
debug.getTrackedRegisters(xmlEncode.toString());
}
return res;
return resultEncode.getBytes();
}
public String getUserOpName(String indexStr) {
@ -906,7 +884,8 @@ public class DecompileCallback {
return name;
}
private String buildResult(HighSymbol highSymbol, Namespace namespc) {
private void encodeResult(Encoder encoder, HighSymbol highSymbol, Namespace namespc)
throws IOException {
long namespaceId;
if (namespc == null || namespc instanceof Library) {
namespaceId = Namespace.GLOBAL_NAMESPACE_ID;
@ -914,26 +893,26 @@ public class DecompileCallback {
else {
namespaceId = namespc.getID();
}
StringBuilder res = new StringBuilder();
res.append("<result");
SpecXmlUtils.encodeUnsignedIntegerAttribute(res, "id", namespaceId);
res.append(">\n");
encoder.openElement(ElementId.ELEM_DOC);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, namespaceId);
if (debug != null) {
StringBuilder res2 = new StringBuilder();
HighSymbol.buildMapSymXML(res2, highSymbol);
String res2string = res2.toString();
XmlEncode debugEncode = new XmlEncode();
HighSymbol.encodeMapSym(debugEncode, highSymbol);
String res2string = debugEncode.toString();
debug.getMapped(namespc, res2string);
res.append(res2string);
}
else {
HighSymbol.buildMapSymXML(res, highSymbol);
}
res.append("</result>\n");
return res.toString();
HighSymbol.encodeMapSym(encoder, highSymbol);
encoder.closeElement(ElementId.ELEM_DOC);
}
private String buildData(Data data) { // Convert global variable to XML
/**
* Encode a global variable to the stream
* @param encoder is the stream encoder
* @param data describes the global variable
* @return true if the variable is successfully encoded
* @throws IOException for errors in the underlying stream
*/
private boolean encodeData(Encoder encoder, Data data) throws IOException {
Symbol sym = data.getPrimarySymbol();
HighCodeSymbol highSymbol;
if (sym != null) {
@ -945,36 +924,36 @@ public class DecompileCallback {
SymbolEntry entry = highSymbol.getFirstWholeMap();
if (data.getDataType() == DataType.DEFAULT && !entry.isReadOnly() &&
!entry.isVolatile()) {
return null;
return false;
}
}
if (debug != null) {
debug.getType(highSymbol.getDataType());
}
Namespace namespc = (sym != null) ? sym.getParentNamespace() : null;
return buildResult(highSymbol, namespc);
encodeResult(encoder, highSymbol, namespc);
return true;
}
private StringBuilder buildRegister(Register reg) {
StringBuilder resBuf = new StringBuilder();
resBuf.append("<addr");
SpecXmlUtils.encodeStringAttribute(resBuf, "space", reg.getAddressSpace().getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "offset", reg.getOffset());
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", reg.getMinimumByteSize());
resBuf.append("/>");
return resBuf;
private static void encodeRegister(Encoder encoder, Register reg) throws IOException {
encoder.openElement(ElementId.ELEM_ADDR);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, reg.getAddressSpace());
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, reg.getOffset());
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, reg.getMinimumByteSize());
encoder.closeElement(ElementId.ELEM_ADDR);
}
/**
* Generate description of a non-data symbol, probably a code label
* Encode a description of a non-data symbol, probably a code label, to the stream
*
* @param encoder is the stream encoder
* @param sym is the symbol
* @return the XML description
* @throws IOException for errors in the underlying stream
*/
private String buildLabel(Symbol sym, Address addr) {
private void encodeLabel(Encoder encoder, Symbol sym, Address addr) throws IOException {
HighSymbol labelSymbol = new HighLabelSymbol(sym.getName(), addr, dtmanage);
Namespace namespc = sym.getParentNamespace();
return buildResult(labelSymbol, namespc);
encodeResult(encoder, labelSymbol, namespc);
}
/**
@ -1032,13 +1011,15 @@ public class DecompileCallback {
* contiguous block in the body of the function containing the queried
* address
*
* @param encoder is the stream encoder
* @param func Function whose body contains the address
* @param addr The queried address
* @param includeDefaultNames true if default parameter names should be
* included
* @return XML string describing the function or the hole
* @throws IOException for errors in the underlying stream
*/
private String buildFunctionXML(Function func, Address addr, boolean includeDefaultNames) {
private void encodeFunction(Encoder encoder, Function func, Address addr,
boolean includeDefaultNames) throws IOException {
Address entry = func.getEntryPoint();
if (entry.getAddressSpace().equals(addr.getAddressSpace())) {
long diff = addr.getOffset() - entry.getOffset();
@ -1056,7 +1037,8 @@ public class DecompileCallback {
debug.getFNTypes(hfunc);
debug.addPossiblePrototypeExtension(func);
}
return buildResult(functionSymbol, namespc);
encodeResult(encoder, functionSymbol, namespc);
return;
}
}
@ -1067,14 +1049,15 @@ public class DecompileCallback {
Address first = range.getMinAddress();
Address last = range.getMaxAddress();
boolean readonly = true; // Treat function body as readonly
return buildHoleXML(first.getAddressSpace().getPhysicalSpace().getName(),
encodeHole(encoder, first.getAddressSpace().getPhysicalSpace(),
first.getUnsignedOffset(), last.getUnsignedOffset(), readonly, false);
return;
}
}
// There is probably some sort of error, just return a block
// containing the single queried address
return buildHoleXML(addr.getAddressSpace().getPhysicalSpace().getName(),
addr.getUnsignedOffset(), addr.getUnsignedOffset(), true, false);
encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(),
addr.getUnsignedOffset(), true, false);
}
private int getExtraPopOverride(Function func, Address addr) {
@ -1110,17 +1093,15 @@ public class DecompileCallback {
return extrapop;
}
private String buildHoleXML(String nm, long first, long last, boolean readonly,
boolean isVolatile) {
StringBuilder resBuf = new StringBuilder();
resBuf.append("<hole");
SpecXmlUtils.encodeBooleanAttribute(resBuf, "readonly", readonly);
SpecXmlUtils.encodeBooleanAttribute(resBuf, "volatile", isVolatile);
SpecXmlUtils.encodeStringAttribute(resBuf, "space", nm);
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "first", first);
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "last", last);
resBuf.append("/>\n");
return resBuf.toString();
private void encodeHole(Encoder encoder, AddressSpace spc, long first, long last,
boolean readonly, boolean isVolatile) throws IOException {
encoder.openElement(ElementId.ELEM_HOLE);
encoder.writeBool(AttributeId.ATTRIB_READONLY, readonly);
encoder.writeBool(AttributeId.ATTRIB_VOLATILE, isVolatile);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, spc);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, first);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, last);
encoder.closeElement(ElementId.ELEM_HOLE);
}
/**
@ -1133,63 +1114,19 @@ public class DecompileCallback {
*
* So now we assume that biggest hole we can find is just 1 byte
*
* @param addr = Address around which to find region
* @return String <hole> tag
* @param encoder is the stream encoder
* @param addr is the Address around which to find region
* @throws IOException for errors in the underlying stream
*/
private String buildHole(Address addr) {
// AddressSpace addrspace = addr.getAddressSpace();
// Address before,after;
// MemoryBlock block = program.getMemory().getBlock(addr);
// boolean readonly;
// boolean isVolatile = isVolatileNoData(addr);
// if (block != null) {
// before = block.getStart();
// after = block.getEnd();
// readonly = !block.isWrite();
// }
// else {
// before = addrspace.getAddress(0);
// after = addrspace.getMaxAddress();
// readonly = false;
// }
// CodeUnit cubefore = listing.getDefinedCodeUnitBefore(addr);
// if (cubefore != null) {
// Address tmp = cubefore.getMaxAddress();
// if (tmp.getAddressSpace().getBaseSpaceID()==addrspace.getBaseSpaceID()) {
// tmp = tmp.add(1);
// if (tmp.getOffset()<=addr.getOffset()) {
// if (tmp.getOffset() > before.getOffset())
// before = tmp;
// }
// else { // Address is inside codeunit
// tmp = cubefore.getMaxAddress();
// if (tmp.getOffset()<after.getOffset())
// after = tmp;
// tmp = cubefore.getMinAddress();
// if (tmp.getOffset() > before.getOffset())
// before = tmp;
// }
// }
// }
// CodeUnit cuafter = listing.getDefinedCodeUnitAfter(addr);
// if (cuafter != null) {
// Address tmp = cuafter.getMinAddress();
// if ((tmp.getAddressSpace()==addrspace)) {
// tmp = tmp.subtract(1);
// if (tmp.getOffset()<after.getOffset()) {
// after = tmp;
// }
// }
// }
// return buildHoleXML(addrspace.getPhysicalSpace().getName(),before.getOffset(),
// after.getOffset(),readonly,isVolatile);
private void encodeHole(Encoder encoder, Address addr) throws IOException {
boolean readonly = isReadOnlyNoData(addr);
boolean isvolatile = isVolatileNoData(addr);
return buildHoleXML(addr.getAddressSpace().getPhysicalSpace().getName(),
addr.getUnsignedOffset(), addr.getUnsignedOffset(), readonly, isvolatile);
encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(),
addr.getUnsignedOffset(), readonly, isvolatile);
}
private String buildExternalRef(Address addr, ExternalReference ref) {
private void encodeExternalRef(Encoder encoder, Address addr, ExternalReference ref)
throws IOException {
// The decompiler model was to assume that the ExternalReference
// object could resolve the physical address where the dll
// function was getting loaded, just as a linker would do.
@ -1204,19 +1141,35 @@ public class DecompileCallback {
// no attempt to get a realistic linked address. This works because
// we never read bytes or look up code units at the address.
HighSymbol externSymbol = new HighExternalSymbol(ref.getLabel(), addr, addr, dtmanage);
return buildResult(externSymbol, null);
encodeResult(encoder, externSymbol, null);
}
private void buildTrackSet(StringBuilder buf, Register reg, long val) {
private void encodeTrackSet(Encoder encoder, Register reg, long val) throws IOException {
AddressSpace spc = reg.getAddressSpace();
long offset = reg.getOffset();
int size = reg.getMinimumByteSize();
buf.append("<set");
SpecXmlUtils.encodeStringAttribute(buf, "space", spc.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "offset", offset);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "size", size);
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "val", val);
buf.append("/>\n");
encoder.openElement(ElementId.ELEM_SET);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, spc);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, offset);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, size);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_VAL, val);
encoder.closeElement(ElementId.ELEM_SET);
}
private void encodeTrackedPointSet(Encoder encoder, Address addr, ProgramContext context)
throws IOException {
encoder.openElement(ElementId.ELEM_TRACKED_POINTSET);
AddressXML.encodeAttributes(encoder, addr);
for (Register reg : context.getRegisters()) {
if (reg.isProcessorContext()) {
continue;
}
BigInteger val = context.getValue(reg, addr, false);
if (val != null) {
encodeTrackSet(encoder, reg, val.longValue());
}
}
encoder.closeElement(ElementId.ELEM_TRACKED_POINTSET);
}
private ExternalReference getExternalReference(Address addr) {
@ -1422,46 +1375,4 @@ public class DecompileCallback {
}
return stringData;
}
//==================================================================================================
// Inner Classes
//==================================================================================================
private class NameListHandler extends DefaultHandler {
private ArrayList<String> res;
private StringBuilder curbuffer;
NameListHandler() {
super();
res = new ArrayList<>();
curbuffer = null;
}
@Override
public void startElement(String uri, String localName, String rawName, Attributes attr)
throws SAXException {
if (localName.equals("val")) {
curbuffer = new StringBuilder();
}
}
@Override
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
if ((curbuffer != null) && (arg0 != null)) {
curbuffer.append(arg0, arg1, arg2);
}
}
@Override
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
if (arg1.equals("val")) {
res.add(curbuffer.toString());
curbuffer = null;
}
}
public ArrayList<String> getList() {
return res;
}
}
}

View file

@ -288,14 +288,14 @@ public class DecompileDebug {
if (stringmap.isEmpty()) {
return;
}
StringBuilder buf = new StringBuilder();
buf.append("<stringmanage>\n");
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_STRINGMANAGE);
for (Map.Entry<Address, StringData> entry : stringmap.entrySet()) {
buf.append("<string>\n");
AddressXML.buildXML(buf, entry.getKey());
buf.append("\n<bytes");
SpecXmlUtils.encodeBooleanAttribute(buf, "trunc", entry.getValue().isTruncated);
buf.append(">\n ");
encoder.openElement(ElementId.ELEM_STRING);
AddressXML.encode(encoder, entry.getKey());
encoder.openElement(ElementId.ELEM_BYTES);
encoder.writeBool(AttributeId.ATTRIB_TRUNC, entry.getValue().isTruncated);
StringBuilder buf = new StringBuilder();
int count = 0;
for (byte element : entry.getValue().byteData) {
int hi = (element >> 4) & 0xf;
@ -318,46 +318,41 @@ public class DecompileDebug {
buf.append("\n ");
}
}
buf.append("00\n</bytes>\n");
buf.append("</string>\n");
buf.append("00\n");
encoder.writeString(AttributeId.ATTRIB_CONTENT, buf.toString());
encoder.closeElement(ElementId.ELEM_BYTES);
encoder.closeElement(ElementId.ELEM_STRING);
}
buf.append("</stringmanage>\n");
debugStream.write(buf.toString().getBytes());
encoder.closeElement(ElementId.ELEM_STRINGMANAGE);
debugStream.write(encoder.getBytes());
}
private void dumpDataTypes(OutputStream debugStream) throws IOException {
DataOrganization dataOrganization = program.getCompilerSpec().getDataOrganization();
int intSize = dataOrganization.getIntegerSize();
int longSize = dataOrganization.getLongSize();
StringBuilder buf = new StringBuilder();
buf.append("<typegrp");
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "intsize", intSize);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "longsize", longSize);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "structalign", 4);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "enumsize", 4);
SpecXmlUtils.encodeBooleanAttribute(buf, "enumsigned", false);
buf.append(">\n");
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_TYPEGRP);
encoder.writeSignedInteger(AttributeId.ATTRIB_INTSIZE, intSize);
encoder.writeSignedInteger(AttributeId.ATTRIB_LONGSIZE, longSize);
encoder.writeSignedInteger(AttributeId.ATTRIB_STRUCTALIGN, 4);
encoder.writeSignedInteger(AttributeId.ATTRIB_ENUMSIZE, 4);
encoder.writeBool(AttributeId.ATTRIB_ENUMSIGNED, false);
// structalign should come out of pcodelanguage.getCompilerSpec()
debugStream.write(buf.toString().getBytes());
DataTypeDependencyOrderer TypeOrderer =
new DataTypeDependencyOrderer(program.getDataTypeManager(), dtypes);
//First output all structures as zero size so to avoid any cyclic dependencies.
for (DataType dataType : TypeOrderer.getCompositeList()) {
debugStream
.write((dtmanage.buildCompositeZeroSizePlaceholder(dataType) + "\n").toString()
.getBytes());
dtmanage.encodeCompositeZeroSizePlaceholder(encoder, dataType);
}
//Next, use the dependency stack to output types.
for (DataType dataType : TypeOrderer.getDependencyList()) {
if (!(dataType instanceof BuiltIn)) {
StringBuilder typeBuf = new StringBuilder();
dtmanage.buildType(typeBuf, dataType, dataType.getLength());
typeBuf.append('\n');
debugStream.write(typeBuf.toString().getBytes());
dtmanage.encodeType(encoder, dataType, dataType.getLength());
}
}
debugStream.write("</typegrp>\n".getBytes());
encoder.closeElement(ElementId.ELEM_TYPEGRP);
debugStream.write(encoder.getBytes());
}
private void dumpTrackedContext(OutputStream debugStream) throws IOException {
@ -428,7 +423,6 @@ public class DecompileDebug {
Address addr = iter.next();
ProgramProcessorContext procctx = new ProgramProcessorContext(progctx, addr);
ctxcache.getContext(procctx, buf);
StringBuilder stringBuf = new StringBuilder();
if (lastbuf != null) { // Check to make sure we don't have identical context data
int i;
for (i = 0; i < buf.length; ++i) {
@ -447,9 +441,9 @@ public class DecompileDebug {
lastbuf[i] = buf[i];
}
stringBuf.append("<context_pointset");
AddressXML.appendAttributes(stringBuf, addr);
stringBuf.append(">\n");
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_CONTEXT_POINTSET);
AddressXML.encodeAttributes(encoder, addr);
for (ContextSymbol sym : ctxsymbols) {
int sbit = sym.getInternalLow();
int ebit = sym.getInternalHigh();
@ -459,14 +453,13 @@ public class DecompileDebug {
int shift = (8 * 4) - endbit - 1;
int mask = -1 >>> (startbit + shift);
int val = (buf[word] >>> shift) & mask;
stringBuf.append(" <set");
SpecXmlUtils.encodeStringAttribute(stringBuf, "name", sym.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(stringBuf, "val", val);
stringBuf.append("/>\n");
encoder.openElement(ElementId.ELEM_SET);
encoder.writeString(AttributeId.ATTRIB_NAME, sym.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_VAL, val);
encoder.closeElement(ElementId.ELEM_SET);
}
stringBuf.append("</context_pointset>\n");
String end = stringBuf.toString();
debugStream.write(end.getBytes());
encoder.closeElement(ElementId.ELEM_CONTEXT_POINTSET);
debugStream.write(encoder.getBytes());
}
}
@ -606,28 +599,26 @@ public class DecompileDebug {
return;
}
PcodeInjectLibrary library = program.getCompilerSpec().getPcodeInjectLibrary();
debugStream.write("<specextensions>\n".getBytes());
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_SPECEXTENSIONS);
for (Object obj : specExtensions.values()) {
if (obj instanceof PrototypeModel) {
PrototypeModel model = (PrototypeModel) obj;
StringBuilder buffer = new StringBuilder();
model.saveXml(buffer, library);
String modelString = buffer.toString();
debugStream.write(modelString.getBytes());
model.encode(encoder, library);
}
else if (obj instanceof InjectPayload) {
InjectPayload payload = (InjectPayload) obj;
StringBuilder buffer = new StringBuilder();
payload.saveXml(buffer);
String payloadString = buffer.toString();
debugStream.write(payloadString.getBytes());
payload.encode(encoder);
}
}
debugStream.write("</specextensions>\n".getBytes());
encoder.closeElement(ElementId.ELEM_SPECEXTENSIONS);
debugStream.write(encoder.getBytes());
}
private void dumpCoretypes(OutputStream debugStream) throws IOException {
debugStream.write(dtmanage.buildCoreTypes().getBytes());
XmlEncode encoder = new XmlEncode();
dtmanage.encodeCoreTypes(encoder);
debugStream.write(encoder.getBytes());
}
public void getPcode(Address addr, Instruction instr) {
@ -694,17 +685,19 @@ public class DecompileDebug {
comments = comm; // Already in XML form
}
public void getCodeSymbol(Address addr, long id, String name, Namespace namespace) {
StringBuilder buf = new StringBuilder();
buf.append("<mapsym>\n");
buf.append(" <labelsym");
SpecXmlUtils.xmlEscapeAttribute(buf, "name", name);
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "id", id);
buf.append("/>\n ");
AddressXML.buildXML(buf, addr);
buf.append("\n <rangelist/>\n");
buf.append("</mapsym>\n");
getMapped(namespace, buf.toString());
public void getCodeSymbol(Address addr, long id, String name, Namespace namespace)
throws IOException {
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_MAPSYM);
encoder.openElement(ElementId.ELEM_LABELSYM);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, id);
encoder.closeElement(ElementId.ELEM_LABELSYM);
AddressXML.encode(encoder, addr);
encoder.openElement(ElementId.ELEM_RANGELIST);
encoder.closeElement(ElementId.ELEM_RANGELIST);
encoder.closeElement(ElementId.ELEM_MAPSYM);
getMapped(namespace, encoder.toString());
}
public void getNamespacePath(Namespace namespace) {
@ -765,43 +758,42 @@ public class DecompileDebug {
getMapped(spc, buffer.toString());
}
public void addFlowOverride(Address addr, FlowOverride fo) {
StringBuilder buf = new StringBuilder();
buf.append("<flow type=\"");
public void addFlowOverride(Address addr, FlowOverride fo) throws IOException {
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_FLOW);
if (fo == FlowOverride.BRANCH) {
buf.append("branch");
encoder.writeString(AttributeId.ATTRIB_TYPE, "branch");
}
else if (fo == FlowOverride.CALL) {
buf.append("call");
encoder.writeString(AttributeId.ATTRIB_TYPE, "call");
}
else if (fo == FlowOverride.CALL_RETURN) {
buf.append("callreturn");
encoder.writeString(AttributeId.ATTRIB_TYPE, "callreturn");
}
else if (fo == FlowOverride.RETURN) {
buf.append("return");
encoder.writeString(AttributeId.ATTRIB_TYPE, "return");
}
else {
buf.append("none");
encoder.writeString(AttributeId.ATTRIB_TYPE, "none");
}
buf.append("\">");
AddressXML.buildXML(buf, func.getEntryPoint());
AddressXML.buildXML(buf, addr);
buf.append("</flow>\n");
flowoverride.add(buf.toString());
AddressXML.encode(encoder, func.getEntryPoint());
AddressXML.encode(encoder, addr);
encoder.closeElement(ElementId.ELEM_FLOW);
flowoverride.add(encoder.toString());
}
public void addInject(Address addr, String name, int injectType, String payload) {
StringBuilder buf = new StringBuilder();
buf.append("<inject name=\"");
buf.append(name);
buf.append('"');
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "type", injectType);
buf.append(">\n ");
AddressXML.buildXML(buf, addr);
buf.append("\n <payload><![CDATA[\n");
buf.append(payload);
buf.append("\n]]></payload>\n</inject>\n");
inject.add(buf.toString());
public void addInject(Address addr, String name, int injectType, String payload)
throws IOException {
XmlEncode encoder = new XmlEncode();
encoder.openElement(ElementId.ELEM_INJECT);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
encoder.writeSignedInteger(AttributeId.ATTRIB_TYPE, injectType);
AddressXML.encode(encoder, addr);
encoder.openElement(ElementId.ELEM_PAYLOAD);
encoder.writeString(AttributeId.ATTRIB_CONTENT, payload);
encoder.closeElement(ElementId.ELEM_PAYLOAD);
encoder.closeElement(ElementId.ELEM_INJECT);
inject.add(encoder.toString());
PcodeInjectLibrary library = program.getCompilerSpec().getPcodeInjectLibrary();
if (library.hasProgramPayload(name, injectType)) {

View file

@ -233,6 +233,12 @@ public class DecompileProcess {
write(string_end);
}
private void writeBytes(byte[] msg) throws IOException {
write(string_start);
write(msg);
write(string_end);
}
/**
* Transfer bytes written to -out- to decompiler process
* @param out has the collected byte for this write
@ -628,10 +634,10 @@ public class DecompileProcess {
private void getRegister() throws IOException {
String name = readQueryString();
String res = callback.getRegister(name);
byte[] res = callback.getRegister(name);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -640,9 +646,6 @@ public class DecompileProcess {
String addr = readQueryString();
String res = callback.getRegisterName(addr);
if (res == null) {
res = "";
}
write(query_response_start);
writeString(res);
write(query_response_end);
@ -650,12 +653,9 @@ public class DecompileProcess {
private void getTrackedRegisters() throws IOException {
String addr = readQueryString();
String res = callback.getTrackedRegisters(addr);
if (res == null) {
res = "";
}
byte[] res = callback.getTrackedRegisters(addr);
write(query_response_start);
writeString(res);
writeBytes(res);
write(query_response_end);
}
@ -683,10 +683,10 @@ public class DecompileProcess {
private void getPcodeInject(int type) throws IOException {
String name = readQueryString();
String context = readQueryString();
String res = callback.getPcodeInject(name, context, type);
byte[] res = callback.getPcodeInject(name, context, type);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -698,10 +698,10 @@ public class DecompileProcess {
for (int i = 0; i < split.length; ++i) {
refs[i] = Long.parseUnsignedLong(split[i], 16);
}
String res = callback.getCPoolRef(refs);
byte[] res = callback.getCPoolRef(refs);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -709,10 +709,10 @@ public class DecompileProcess {
private void getMappedSymbolsXML() throws IOException {
String addr = readQueryString();
String res = callback.getMappedSymbolsXML(addr);
byte[] res = callback.getMappedSymbolsXML(addr);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -720,10 +720,10 @@ public class DecompileProcess {
private void getNamespacePath() throws IOException {
String idString = readQueryString();
long id = Long.parseLong(idString, 16);
String res = callback.getNamespacePath(id);
byte[] res = callback.getNamespacePath(id);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -744,10 +744,10 @@ public class DecompileProcess {
private void getExternalRefXML() throws IOException {
String refaddr = readQueryString();
String res = callback.getExternalRefXML(refaddr);
byte[] res = callback.getExternalRefXML(refaddr);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}
@ -767,32 +767,19 @@ public class DecompileProcess {
private void getComments() throws IOException {
String addr = readQueryString();
String flags = readQueryString();
String res = callback.getComments(addr, flags);
if (res == null) {
res = "";
}
byte[] res = callback.getComments(addr, flags);
write(query_response_start);
writeString(res);
writeBytes(res);
write(query_response_end);
}
// private void getScope() throws IOException {
// String namepath = readQueryString();
// String res = callback.getScope(namepath);
// if (res==null)
// res = "";
// write(query_response_start);
// writeString(res);
// write(query_response_end);
// }
private void getType() throws IOException {
String name = readQueryString();
long id = SpecXmlUtils.decodeLong(readQueryString());
String res = callback.getType(name, id);
byte[] res = callback.getType(name, id);
write(query_response_start);
if ((res != null) && (res.length() != 0)) {
writeString(res);
if (res.length != 0) {
writeBytes(res);
}
write(query_response_end);
}

View file

@ -17,6 +17,7 @@ package ghidra.app.plugin.core.decompile;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
@ -32,6 +33,7 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.lang.*;
import ghidra.program.model.lang.CompilerSpec.EvaluationModelType;
import ghidra.program.model.listing.Function;
import ghidra.program.model.pcode.XmlEncode;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
@ -125,15 +127,15 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
}
@Test
public void test_PrototypeExtension() {
public void test_PrototypeExtension() throws IOException {
decompile("100272e");
ClangTextField line = getLineContaining("FUN_010026a7(pHVar1);");
assertNotNull(line);
CompilerSpec cspec = program.getCompilerSpec();
PrototypeModel defaultModel = cspec.getDefaultCallingConvention();
StringBuilder buffer = new StringBuilder();
defaultModel.saveXml(buffer, cspec.getPcodeInjectLibrary());
String defaultString = buffer.toString();
XmlEncode encoder = new XmlEncode();
defaultModel.encode(encoder, cspec.getPcodeInjectLibrary());
String defaultString = encoder.toString();
// Replace the output register EAX with ECX
defaultString = defaultString.replace("<addr space=\"register\" offset=\"0x0\"/>",
"<addr space=\"register\" offset=\"4\"/>");

View file

@ -40,6 +40,7 @@ import ghidra.program.model.lang.*;
import ghidra.program.model.listing.DefaultProgramContext;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.pcode.*;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.util.AddressLabelInfo;
import ghidra.program.model.util.ProcessorSymbolType;
@ -1402,70 +1403,65 @@ public class SleighLanguage implements Language {
}
/**
* Generates a limited translator XML tag for the specified address factory and optional register set.
* @param factory address factory
* Encode limited information to the stream about the SLEIGH translator for the specified
* address factory and optional register set.
* @param encoder is the stream encoder
* @param factory is the specified address factory
* @param uniqueOffset the initial offset within the unique address space to start assigning temporary registers
* @param optionalSymTab optional symbol table to be passed (may be null to omit). Only non-context registers
* and user-defined pcodeop's are included.
* @return the entire XML tag as a String
* @throws IOException for errors writing to the underlying stream
*/
public String buildTranslatorTag(AddressFactory factory, long uniqueOffset,
SymbolTable optionalSymTab) {
public void encodeTranslator(Encoder encoder, AddressFactory factory, long uniqueOffset)
throws IOException {
AddressSpace[] spclist = factory.getAllAddressSpaces();
StringBuilder resBuf = new StringBuilder();
resBuf.append("<sleigh");
SpecXmlUtils.encodeBooleanAttribute(resBuf, "bigendian", isBigEndian());
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "uniqbase", uniqueOffset);
resBuf.append(">\n");
resBuf.append("<spaces");
SpecXmlUtils.encodeStringAttribute(resBuf, "defaultspace",
encoder.openElement(ElementId.ELEM_SLEIGH);
encoder.writeBool(AttributeId.ATTRIB_BIGENDIAN, isBigEndian());
encoder.writeUnsignedInteger(AttributeId.ATTRIB_UNIQBASE, uniqueOffset);
encoder.openElement(ElementId.ELEM_SPACES);
encoder.writeString(AttributeId.ATTRIB_DEFAULTSPACE,
factory.getDefaultAddressSpace().getName());
resBuf.append(">\n");
String tag;
ElementId tag;
int delay;
boolean physical;
for (AddressSpace element : spclist) {
if ((element instanceof OverlayAddressSpace)) {
OverlayAddressSpace ospace = (OverlayAddressSpace) element;
resBuf.append("<space_overlay");
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", ospace.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "index", ospace.getUnique());
SpecXmlUtils.encodeStringAttribute(resBuf, "base",
ospace.getOverlayedSpace().getName());
resBuf.append("/>\n");
encoder.openElement(ElementId.ELEM_SPACE_OVERLAY);
encoder.writeString(AttributeId.ATTRIB_NAME, ospace.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, ospace.getUnique());
encoder.writeSpace(AttributeId.ATTRIB_BASE, ospace.getOverlayedSpace());
encoder.closeElement(ElementId.ELEM_SPACE_OVERLAY);
continue;
}
switch (element.getType()) {
case AddressSpace.TYPE_RAM:
tag = "space";
tag = ElementId.ELEM_SPACE;
delay = 1;
physical = true;
break;
case AddressSpace.TYPE_REGISTER:
tag = "space";
tag = ElementId.ELEM_SPACE;
delay = 0;
physical = true;
break;
case AddressSpace.TYPE_UNIQUE:
tag = "space_unique";
tag = ElementId.ELEM_SPACE_UNIQUE;
delay = 0;
physical = true;
break;
case AddressSpace.TYPE_OTHER:
tag = "space_other";
tag = ElementId.ELEM_SPACE_OTHER;
delay = 0;
physical = true;
break;
default:
continue;
}
resBuf.append("<").append(tag);
SpecXmlUtils.encodeStringAttribute(resBuf, "name", element.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "index", element.getUnique());
encoder.openElement(tag);
encoder.writeString(AttributeId.ATTRIB_NAME, element.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, element.getUnique());
int size = element.getSize(); // Size in bits
if (element instanceof SegmentedAddressSpace) {
@ -1476,20 +1472,19 @@ public class SleighLanguage implements Language {
size = 64;
}
int bytesize = (size + 7) / 8; // Convert bits to bytes
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", bytesize);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, bytesize);
if (element.getAddressableUnitSize() > 1) {
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "wordsize",
encoder.writeSignedInteger(AttributeId.ATTRIB_WORDSIZE,
element.getAddressableUnitSize());
}
SpecXmlUtils.encodeBooleanAttribute(resBuf, "bigendian", isBigEndian());
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "delay", delay);
SpecXmlUtils.encodeBooleanAttribute(resBuf, "physical", physical);
resBuf.append("/>\n");
encoder.writeBool(AttributeId.ATTRIB_BIGENDIAN, isBigEndian());
encoder.writeSignedInteger(AttributeId.ATTRIB_DELAY, delay);
encoder.writeBool(AttributeId.ATTRIB_PHYSICAL, physical);
encoder.closeElement(tag);
}
resBuf.append("</spaces>\n");
encoder.closeElement(ElementId.ELEM_SPACES);
SleighLanguageDescription sleighDescription =
(SleighLanguageDescription) getLanguageDescription();
@ -1497,75 +1492,13 @@ public class SleighLanguage implements Language {
if (!truncatedSpaceNames.isEmpty()) {
for (String spaceName : truncatedSpaceNames) {
int sz = sleighDescription.getTruncatedSpaceSize(spaceName);
resBuf.append("<truncate_space");
SpecXmlUtils.encodeStringAttribute(resBuf, "space", spaceName);
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", sz);
resBuf.append("/>\n");
encoder.openElement(ElementId.ELEM_TRUNCATE_SPACE);
encoder.writeString(AttributeId.ATTRIB_SPACE, spaceName);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, sz);
encoder.closeElement(ElementId.ELEM_TRUNCATE_SPACE);
}
}
if (optionalSymTab != null) {
resBuf.append(buildSymbolsXml(optionalSymTab));
}
resBuf.append("</sleigh>\n");
return resBuf.toString();
}
private static String buildSymbolsXml(SymbolTable symtab) {
ArrayList<Symbol> symList = new ArrayList<>();
for (Symbol sym : symtab.getSymbolList()) {
if (sym instanceof UseropSymbol) {
symList.add(sym);
}
else if (sym instanceof VarnodeSymbol) {
if ("contextreg".equals(sym.getName())) {
continue;
}
symList.add(sym);
}
}
int count = symList.size();
StringBuilder s = new StringBuilder();
s.append("<symbol_table scopesize=\"1\" symbolsize=\"");
s.append(count);
s.append("\">\n");
s.append("<scope id=\"0x0\" parent=\"0x0\"/>\n");
// First save the headers
for (int i = 0; i < count; ++i) {
Symbol sym = symList.get(i);
String type;
if (sym instanceof UseropSymbol) {
type = "userop_head";
}
else {
type = "varnode_sym_head";
}
s.append("<" + type + " name=\"" + sym.getName() + "\" id=\"0x" +
Integer.toHexString(i) + "\" scope=\"0x0\"/>\n");
}
// Now save the content of each symbol
for (int i = 0; i < count; ++i) {
Symbol sym = symList.get(i);
if (sym instanceof UseropSymbol) {
UseropSymbol opSym = (UseropSymbol) sym;
s.append("<userop name=\"" + sym.getName() + "\" id=\"0x" + Integer.toHexString(i) +
"\" scope=\"0x0\" index=\"" + opSym.getIndex() + "\"/>\n");
}
else {
VarnodeSymbol vnSym = (VarnodeSymbol) sym;
VarnodeData vn = vnSym.getFixedVarnode();
s.append(
"<varnode_sym name=\"" + sym.getName() + "\" id=\"0x" + Integer.toHexString(i) +
"\" scope=\"0x0\" space=\"" + vn.space.getName() + "\" offset=\"0x" +
Long.toHexString(vn.offset) + "\" size=\"" + vn.size + "\"/>\n");
}
}
s.append("</symbol_table>\n");
return s.toString();
encoder.closeElement(ElementId.ELEM_SLEIGH);
}
private void initParallelHelper() {

View file

@ -38,6 +38,7 @@ import ghidra.program.database.ProgramDB;
import ghidra.program.database.SpecExtension;
import ghidra.program.database.SpecExtension.DocInfo;
import ghidra.program.model.lang.*;
import ghidra.program.model.pcode.XmlEncode;
import ghidra.util.Msg;
import ghidra.util.Swing;
import ghidra.util.exception.CancelledException;
@ -541,45 +542,45 @@ public class SpecExtensionPanel extends JPanel {
}
}
private String getXmlString(CompilerElement element) {
private String getXmlString(CompilerElement element) throws IOException {
CompilerSpec compilerSpec = program.getCompilerSpec();
PcodeInjectLibrary injectLibrary = compilerSpec.getPcodeInjectLibrary();
InjectPayload payload;
PrototypeModel model;
String resultString = null;
String resultString;
if (element.status == Status.CORE) {
StringBuilder buffer = new StringBuilder();
XmlEncode encoder = new XmlEncode();
switch (element.type) {
case CALL_FIXUP:
payload = injectLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, element.name);
if (payload != null) {
payload.saveXml(buffer);
payload.encode(encoder);
}
break;
case CALLOTHER_FIXUP:
payload =
injectLibrary.getPayload(InjectPayload.CALLOTHERFIXUP_TYPE, element.name);
if (payload != null) {
payload.saveXml(buffer);
payload.encode(encoder);
}
break;
case PROTOTYPE_MODEL:
case MERGE_MODEL:
model = compilerSpec.getCallingConvention(element.name);
if (model != null) {
model.saveXml(buffer, injectLibrary);
model.encode(encoder, injectLibrary);
}
break;
}
resultString = buffer.toString();
if (resultString.length() == 0) {
resultString = null;
}
resultString = encoder.toString();
}
else {
resultString =
SpecExtension.getCompilerSpecExtension(program, element.type, element.name);
}
if (resultString == null || resultString.length() == 0) {
throw new IOException("Unable to build document for " + element.name);
}
return resultString;
}
@ -603,24 +604,16 @@ public class SpecExtensionPanel extends JPanel {
return;
}
}
String exportString = getXmlString(compilerElement);
String errMessage = null;
if (exportString == null) {
errMessage = "Unable to build document for " + compilerElement.name;
}
else {
FileWriter writer = null;
try {
String exportString = getXmlString(compilerElement);
writer = new FileWriter(outputFile);
writer.write(exportString);
writer.close();
}
catch (IOException ex) {
errMessage = "Failed to write to file: " + ex.getMessage();
}
}
if (errMessage != null) {
Msg.showError(this, this, "Export Failure", errMessage);
Msg.showError(this, this, "Export Failure",
"Failed to write to file: " + ex.getMessage());
}
}

View file

@ -15,6 +15,9 @@
*/
package ghidra.program.model.data;
import java.io.IOException;
import ghidra.program.model.pcode.*;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
@ -70,26 +73,31 @@ public class BitFieldPackingImpl implements BitFieldPacking {
}
/**
* Write configuration to a stream as an XML \<bitfield_packing> tag
* @param buffer is the stream to write to
* Write configuration to a stream as a \<bitfield_packing> element
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void saveXml(StringBuilder buffer) {
public void encode(Encoder encoder) throws IOException {
if (!useMSConvention && typeAlignmentEnabled && zeroLengthBoundary == 0) {
return; // All defaults
}
buffer.append("<bitfield_packing>\n");
encoder.openElement(ElementId.ELEM_BITFIELD_PACKING);
if (useMSConvention) {
buffer.append("<use_MS_convention value=\"yes\"/>\n");
encoder.openElement(ElementId.ELEM_USE_MS_CONVENTION);
encoder.writeBool(AttributeId.ATTRIB_VALUE, true);
encoder.closeElement(ElementId.ELEM_USE_MS_CONVENTION);
}
if (!typeAlignmentEnabled) {
buffer.append("<type_alignment_enabled value=\"no\"/>\n");
encoder.openElement(ElementId.ELEM_TYPE_ALIGNMENT_ENABLED);
encoder.writeBool(AttributeId.ATTRIB_VALUE, false);
encoder.closeElement(ElementId.ELEM_TYPE_ALIGNMENT_ENABLED);
}
if (zeroLengthBoundary != 0) {
buffer.append("<zero_length_boundary");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", zeroLengthBoundary);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_ZERO_LENGTH_BOUNDARY);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, zeroLengthBoundary);
encoder.closeElement(ElementId.ELEM_ZERO_LENGTH_BOUNDARY);
}
buffer.append("</bitfield_packing>\n");
encoder.closeElement(ElementId.ELEM_BITFIELD_PACKING);
}
/**

View file

@ -15,9 +15,11 @@
*/
package ghidra.program.model.data;
import java.io.IOException;
import java.util.*;
import ghidra.program.model.lang.Language;
import ghidra.program.model.pcode.*;
import ghidra.util.exception.NoValueException;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.XmlElement;
@ -551,99 +553,101 @@ public class DataOrganizationImpl implements DataOrganization {
return (value2 != 0) ? getGreatestCommonDenominator(value2, value1 % value2) : value1;
}
public void saveXml(StringBuilder buffer) {
buffer.append("<data_organization>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_DATA_ORGANIZATION);
if (absoluteMaxAlignment != NO_MAXIMUM_ALIGNMENT) {
buffer.append("<absolute_max_alignment");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", absoluteMaxAlignment);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_ABSOLUTE_MAX_ALIGNMENT);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, absoluteMaxAlignment);
encoder.closeElement(ElementId.ELEM_ABSOLUTE_MAX_ALIGNMENT);
}
if (machineAlignment != 8) {
buffer.append("<machine_alignment");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", machineAlignment);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_MACHINE_ALIGNMENT);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, machineAlignment);
encoder.closeElement(ElementId.ELEM_MACHINE_ALIGNMENT);
}
if (defaultAlignment != 1) {
buffer.append("<default_alignment");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", defaultAlignment);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_DEFAULT_ALIGNMENT);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, defaultAlignment);
encoder.closeElement(ElementId.ELEM_DEFAULT_ALIGNMENT);
}
if (defaultPointerAlignment != 4) {
buffer.append("<default_pointer_alignment");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", defaultPointerAlignment);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_DEFAULT_POINTER_ALIGNMENT);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, defaultPointerAlignment);
encoder.closeElement(ElementId.ELEM_DEFAULT_POINTER_ALIGNMENT);
}
if (pointerSize != 0) {
buffer.append("<pointer_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", pointerSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_POINTER_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, pointerSize);
encoder.closeElement(ElementId.ELEM_POINTER_SIZE);
}
if (pointerShift != 0) {
buffer.append("<pointer_shift");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", pointerShift);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_POINTER_SHIFT);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, pointerShift);
encoder.closeElement(ElementId.ELEM_POINTER_SHIFT);
}
if (!isSignedChar) {
buffer.append("<char_type signed=\"no\"/>\n");
encoder.openElement(ElementId.ELEM_CHAR_TYPE);
encoder.writeBool(AttributeId.ATTRIB_SIGNED, false);
encoder.closeElement(ElementId.ELEM_CHAR_TYPE);
}
if (charSize != 1) {
buffer.append("<char_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", charSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_CHAR_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, charSize);
encoder.closeElement(ElementId.ELEM_CHAR_SIZE);
}
if (wideCharSize != 2) {
buffer.append("<wchar_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", wideCharSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_WCHAR_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, wideCharSize);
encoder.closeElement(ElementId.ELEM_WCHAR_SIZE);
}
if (shortSize != 2) {
buffer.append("<short_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", shortSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_SHORT_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, shortSize);
encoder.closeElement(ElementId.ELEM_SHORT_SIZE);
}
if (integerSize != 4) {
buffer.append("<integer_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", integerSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_INTEGER_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, integerSize);
encoder.closeElement(ElementId.ELEM_INTEGER_SIZE);
}
if (longSize != 4) {
buffer.append("<long_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", longSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_LONG_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, longSize);
encoder.closeElement(ElementId.ELEM_LONG_SIZE);
}
if (longLongSize != 8) {
buffer.append("<long_long_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", longLongSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_LONG_LONG_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, longLongSize);
encoder.closeElement(ElementId.ELEM_LONG_LONG_SIZE);
}
if (floatSize != 4) {
buffer.append("<float_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", floatSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_FLOAT_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, floatSize);
encoder.closeElement(ElementId.ELEM_FLOAT_SIZE);
}
if (doubleSize != 8) {
buffer.append("<double_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", doubleSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_DOUBLE_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, doubleSize);
encoder.closeElement(ElementId.ELEM_DOUBLE_SIZE);
}
if (longDoubleSize != 8) {
buffer.append("<long_double_size");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "value", longDoubleSize);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_LONG_DOUBLE_SIZE);
encoder.writeSignedInteger(AttributeId.ATTRIB_VALUE, longDoubleSize);
encoder.closeElement(ElementId.ELEM_LONG_DOUBLE_SIZE);
}
if (sizeAlignmentMap.size() != 0) {
buffer.append("<size_alignment_map>\n");
encoder.openElement(ElementId.ELEM_SIZE_ALIGNMENT_MAP);
for (int key : sizeAlignmentMap.keySet()) {
buffer.append("<entry");
encoder.openElement(ElementId.ELEM_ENTRY);
int value = sizeAlignmentMap.get(key);
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "size", key);
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "alignment", value);
buffer.append("/>\n");
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, key);
encoder.writeSignedInteger(AttributeId.ATTRIB_ALIGNMENT, value);
encoder.closeElement(ElementId.ELEM_ENTRY);
}
buffer.append("</size_alignment_map>\n");
encoder.closeElement(ElementId.ELEM_SIZE_ALIGNMENT_MAP);
}
bitFieldPacking.saveXml(buffer);
buffer.append("</data_organization>\n");
bitFieldPacking.encode(encoder);
encoder.closeElement(ElementId.ELEM_DATA_ORGANIZATION);
}
/**

View file

@ -32,8 +32,7 @@ import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.DefaultProgramContext;
import ghidra.program.model.listing.Parameter;
import ghidra.program.model.pcode.AddressXML;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.DuplicateNameException;
@ -508,64 +507,64 @@ public class BasicCompilerSpec implements CompilerSpec {
}
@Override
public void saveXml(StringBuilder buffer) {
buffer.append("<compiler_spec>\n");
saveProperties(buffer);
dataOrganization.saveXml(buffer);
ContextSetting.buildContextDataXml(buffer, ctxsetting);
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_COMPILER_SPEC);
encodeProperties(encoder);
dataOrganization.encode(encoder);
ContextSetting.encodeContextData(encoder, ctxsetting);
if (aggressiveTrim) {
buffer.append("<aggressivetrim");
SpecXmlUtils.encodeBooleanAttribute(buffer, "signext", aggressiveTrim);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_AGGRESSIVETRIM);
encoder.writeBool(AttributeId.ATTRIB_SIGNEXT, aggressiveTrim);
encoder.closeElement(ElementId.ELEM_AGGRESSIVETRIM);
}
if (stackPointer != null) {
buffer.append("<stackpointer");
SpecXmlUtils.encodeStringAttribute(buffer, "register", stackPointer.getName());
SpecXmlUtils.encodeStringAttribute(buffer, "space", stackBaseSpace.getName());
encoder.openElement(ElementId.ELEM_STACKPOINTER);
encoder.writeString(AttributeId.ATTRIB_REGISTER, stackPointer.getName());
encoder.writeSpace(AttributeId.ATTRIB_SPACE, stackBaseSpace);
if (reverseJustifyStack) {
SpecXmlUtils.encodeBooleanAttribute(buffer, "reversejustify", reverseJustifyStack);
encoder.writeBool(AttributeId.ATTRIB_REVERSEJUSTIFY, reverseJustifyStack);
}
if (!stackGrowsNegative) {
SpecXmlUtils.encodeStringAttribute(buffer, "growth", "positive");
encoder.writeString(AttributeId.ATTRIB_GROWTH, "positive");
}
buffer.append("/>\n");
encoder.closeElement(ElementId.ELEM_STACKPOINTER);
}
saveSpaceBases(buffer);
saveMemoryTags(buffer, "global", globalSet);
saveReturnAddress(buffer); // Must come before PrototypeModels
pcodeInject.saveCompilerSpecXml(buffer);
encodeSpaceBases(encoder);
encodeMemoryTags(encoder, ElementId.ELEM_GLOBAL, globalSet);
encodeReturnAddress(encoder); // Must come before PrototypeModels
pcodeInject.encodeCompilerSpec(encoder);
if (defaultModel != null) {
buffer.append("<default_proto>\n");
defaultModel.saveXml(buffer, pcodeInject);
buffer.append("</default_proto>\n");
encoder.openElement(ElementId.ELEM_DEFAULT_PROTO);
defaultModel.encode(encoder, pcodeInject);
encoder.closeElement(ElementId.ELEM_DEFAULT_PROTO);
}
for (PrototypeModel model : allmodels) {
if (model == defaultModel) {
continue; // Already emitted
}
model.saveXml(buffer, pcodeInject);
model.encode(encoder, pcodeInject);
}
if (evalCurrentModel != null && evalCurrentModel != defaultModel) {
buffer.append("<eval_current_prototype");
SpecXmlUtils.encodeStringAttribute(buffer, "name", evalCurrentModel.name);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_EVAL_CURRENT_PROTOTYPE);
encoder.writeString(AttributeId.ATTRIB_NAME, evalCurrentModel.name);
encoder.closeElement(ElementId.ELEM_EVAL_CURRENT_PROTOTYPE);
}
if (evalCalledModel != null && evalCalledModel != defaultModel) {
buffer.append("<eval_called_prototype");
SpecXmlUtils.encodeStringAttribute(buffer, "name", evalCalledModel.name);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_EVAL_CALLED_PROTOTYPE);
encoder.writeString(AttributeId.ATTRIB_NAME, evalCalledModel.name);
encoder.closeElement(ElementId.ELEM_EVAL_CALLED_PROTOTYPE);
}
savePreferSplit(buffer);
saveMemoryTags(buffer, "nohighptr", noHighPtr);
saveMemoryTags(buffer, "readonly", readOnlySet);
encodePreferSplit(encoder);
encodeMemoryTags(encoder, ElementId.ELEM_NOHIGHPTR, noHighPtr);
encodeMemoryTags(encoder, ElementId.ELEM_READONLY, readOnlySet);
if (funcPtrAlign != 0) {
buffer.append("<funcptr");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "align", funcPtrAlign);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_FUNCPTR);
encoder.writeSignedInteger(AttributeId.ATTRIB_ALIGN, funcPtrAlign);
encoder.closeElement(ElementId.ELEM_FUNCPTR);
}
saveDeadCodeDelay(buffer);
saveInferPtrBounds(buffer);
buffer.append("</compiler_spec>");
encodeDeadCodeDelay(encoder);
encodeInferPtrBounds(encoder);
encoder.closeElement(ElementId.ELEM_COMPILER_SPEC);
}
/**
@ -712,18 +711,18 @@ public class BasicCompilerSpec implements CompilerSpec {
}
}
private void saveProperties(StringBuilder buffer) {
private void encodeProperties(Encoder encoder) throws IOException {
if (properties.isEmpty()) {
return;
}
buffer.append("<properties>\n");
encoder.openElement(ElementId.ELEM_PROPERTIES);
for (Entry<String, String> property : properties.entrySet()) {
buffer.append("<property");
SpecXmlUtils.encodeStringAttribute(buffer, "key", property.getKey());
SpecXmlUtils.encodeStringAttribute(buffer, "value", property.getValue());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_PROPERTY);
encoder.writeString(AttributeId.ATTRIB_KEY, property.getKey());
encoder.writeString(AttributeId.ATTRIB_VALUE, property.getValue());
encoder.closeElement(ElementId.ELEM_PROPERTY);
}
buffer.append("</properties>\n");
encoder.closeElement(ElementId.ELEM_PROPERTIES);
}
private void restoreProperties(XmlPullParser parser) {
@ -743,16 +742,16 @@ public class BasicCompilerSpec implements CompilerSpec {
parser.end();
}
private void saveSpaceBases(StringBuilder buffer) {
private void encodeSpaceBases(Encoder encoder) throws IOException {
if (spaceBases == null) {
return;
}
for (Entry<String, Pair<AddressSpace, String>> entry : spaceBases.entrySet()) {
buffer.append("<spacebase");
SpecXmlUtils.encodeStringAttribute(buffer, "name", entry.getKey());
SpecXmlUtils.encodeStringAttribute(buffer, "register", entry.getValue().second);
SpecXmlUtils.encodeStringAttribute(buffer, "space", entry.getValue().first.getName());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_SPACEBASE);
encoder.writeString(AttributeId.ATTRIB_NAME, entry.getKey());
encoder.writeString(AttributeId.ATTRIB_REGISTER, entry.getValue().second);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, entry.getValue().first);
encoder.closeElement(ElementId.ELEM_SPACEBASE);
}
}
@ -776,15 +775,15 @@ public class BasicCompilerSpec implements CompilerSpec {
parser.end(el);
}
private void saveReturnAddress(StringBuilder buffer) {
private void encodeReturnAddress(Encoder encoder) throws IOException {
if (returnAddress == null) {
return;
}
buffer.append("<returnaddress>\n");
buffer.append("<varnode");
AddressXML.appendAttributes(buffer, returnAddress.getAddress(), returnAddress.getSize());
buffer.append("/>\n");
buffer.append("</returnaddress>\n");
encoder.openElement(ElementId.ELEM_RETURNADDRESS);
encoder.openElement(ElementId.ELEM_VARNODE);
AddressXML.encodeAttributes(encoder, returnAddress.getAddress(), returnAddress.getSize());
encoder.closeElement(ElementId.ELEM_VARNODE);
encoder.closeElement(ElementId.ELEM_RETURNADDRESS);
}
private void restoreReturnAddress(XmlPullParser parser) throws XmlParseException {
@ -819,12 +818,12 @@ public class BasicCompilerSpec implements CompilerSpec {
extraRanges.add(new Pair<>(tagName + '_' + spcName, new Pair<>(first, last)));
}
private void saveExtraRanges(StringBuilder buffer, String tagName) {
private void encodeExtraRanges(Encoder encoder, ElementId tag) throws IOException {
if (extraRanges == null) {
return;
}
for (Pair<String, Pair<Long, Long>> entry : extraRanges) {
if (!entry.first.startsWith(tagName)) {
if (!entry.first.startsWith(tag.getName())) {
continue;
}
String spcName = entry.first.substring(entry.first.indexOf('_') + 1);
@ -832,32 +831,34 @@ public class BasicCompilerSpec implements CompilerSpec {
long last = entry.second.second;
boolean useFirst = (first != 0);
boolean useLast = (last != -1);
buffer.append("<range");
SpecXmlUtils.encodeStringAttribute(buffer, "space", spcName);
encoder.openElement(ElementId.ELEM_RANGE);
// Must use string encoding here, as address space may not exist
encoder.writeString(AttributeId.ATTRIB_SPACE, spcName);
if (useFirst) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "first", first);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, first);
}
if (useLast) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "last", last);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, last);
}
buffer.append("/>\n");
encoder.closeElement(ElementId.ELEM_RANGE);
}
}
private void saveMemoryTags(StringBuilder buffer, String tagName, AddressSet addrSet) {
private void encodeMemoryTags(Encoder encoder, ElementId tag, AddressSet addrSet)
throws IOException {
if (addrSet == null) {
return;
}
buffer.append('<').append(tagName).append(">\n");
encoder.openElement(tag);
AddressRangeIterator iter = addrSet.getAddressRanges();
while (iter.hasNext()) {
AddressRange range = iter.next();
buffer.append("<range");
AddressXML.appendAttributes(buffer, range.getMinAddress(), range.getMaxAddress());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_RANGE);
AddressXML.encodeAttributes(encoder, range.getMinAddress(), range.getMaxAddress());
encoder.closeElement(ElementId.ELEM_RANGE);
}
saveExtraRanges(buffer, tagName);
buffer.append("</").append(tagName).append(">\n");
encodeExtraRanges(encoder, tag);
encoder.closeElement(tag);
}
private void restoreMemoryTags(String tagName, XmlPullParser parser, AddressSet addrSet)
@ -903,17 +904,18 @@ public class BasicCompilerSpec implements CompilerSpec {
parser.end(el);
}
private void savePreferSplit(StringBuilder buffer) {
private void encodePreferSplit(Encoder encoder) throws IOException {
if (preferSplit == null || preferSplit.isEmpty()) {
return;
}
buffer.append("<prefersplit style=\"inhalf\">\n");
encoder.openElement(ElementId.ELEM_PREFERSPLIT);
encoder.writeString(AttributeId.ATTRIB_STYLE, "inhalf");
for (Varnode varnode : preferSplit) {
buffer.append("<varnode");
AddressXML.appendAttributes(buffer, varnode.getAddress(), varnode.getSize());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_VARNODE);
AddressXML.encodeAttributes(encoder, varnode.getAddress(), varnode.getSize());
encoder.closeElement(ElementId.ELEM_VARNODE);
}
buffer.append("</prefersplit>\n");
encoder.closeElement(ElementId.ELEM_PREFERSPLIT);
}
private void restoreDeadCodeDelay(XmlPullParser parser) {
@ -927,15 +929,15 @@ public class BasicCompilerSpec implements CompilerSpec {
parser.end(el);
}
private void saveDeadCodeDelay(StringBuilder buffer) {
private void encodeDeadCodeDelay(Encoder encoder) throws IOException {
if (deadCodeDelay == null) {
return;
}
for (Pair<AddressSpace, Integer> pair : deadCodeDelay) {
buffer.append("<deadcodedelay");
SpecXmlUtils.encodeStringAttribute(buffer, "space", pair.first.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "delay", pair.second.intValue());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_DEADCODEDELAY);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, pair.first);
encoder.writeSignedInteger(AttributeId.ATTRIB_DELAY, pair.second.intValue());
encoder.closeElement(ElementId.ELEM_DEADCODEDELAY);
}
}
@ -955,18 +957,18 @@ public class BasicCompilerSpec implements CompilerSpec {
parser.end(el);
}
private void saveInferPtrBounds(StringBuilder buffer) {
private void encodeInferPtrBounds(Encoder encoder) throws IOException {
if (inferPtrBounds == null) {
return;
}
buffer.append("<inferptrbounds>\n");
encoder.openElement(ElementId.ELEM_INFERPTRBOUNDS);
for (AddressRange addrRange : inferPtrBounds) {
buffer.append("<range");
AddressXML.appendAttributes(buffer, addrRange.getMinAddress(),
encoder.openElement(ElementId.ELEM_RANGE);
AddressXML.encodeAttributes(encoder, addrRange.getMinAddress(),
addrRange.getMaxAddress());
buffer.append("/>\n");
encoder.closeElement(ElementId.ELEM_RANGE);
}
buffer.append("</inferptrbounds>\n");
encoder.closeElement(ElementId.ELEM_INFERPTRBOUNDS);
}
private void setStackPointer(XmlPullParser parser) {

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.Set;
import ghidra.program.model.address.Address;
@ -23,6 +24,7 @@ import ghidra.program.model.data.DataOrganization;
import ghidra.program.model.data.GenericCallingConvention;
import ghidra.program.model.listing.DefaultProgramContext;
import ghidra.program.model.listing.Parameter;
import ghidra.program.model.pcode.Encoder;
/**
* Interface for requesting specific information about the compiler used to
@ -239,11 +241,12 @@ public interface CompilerSpec {
public Set<String> getPropertyKeys();
/**
* Marshal this entire specification to an XML stream. An XML document is written with
* root tag \<compiler_spec>.
* @param buffer is the XML stream
* Encode this entire specification to a stream. A document is written with
* root element \<compiler_spec>.
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void saveXml(StringBuilder buffer);
public void encode(Encoder encoder) throws IOException;
/**
* Determine if this CompilerSpec is equivalent to another specified instance

View file

@ -15,11 +15,11 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.nio.charset.Charset;
import ghidra.program.model.data.DataType;
import ghidra.program.model.pcode.PcodeDataTypeManager;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.program.model.pcode.*;
/**
* Class for manipulating "deferred" constant systems like the java virtual machine constant pool
@ -43,45 +43,46 @@ public abstract class ConstantPool {
public DataType type;
public boolean isConstructor = false;
public StringBuilder build(long ref, PcodeDataTypeManager dtmanage) {
StringBuilder buf = new StringBuilder();
buf.append("<cpoolrec");
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "ref", ref);
public void encode(Encoder encoder, long ref, PcodeDataTypeManager dtmanage)
throws IOException {
encoder.openElement(ElementId.ELEM_CPOOLREC);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_REF, ref);
if (tag == STRING_LITERAL) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "string");
encoder.writeString(AttributeId.ATTRIB_TAG, "string");
}
else if (tag == CLASS_REFERENCE) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "classref");
encoder.writeString(AttributeId.ATTRIB_TAG, "classref");
}
else if (tag == POINTER_METHOD) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "method");
encoder.writeString(AttributeId.ATTRIB_TAG, "method");
}
else if (tag == POINTER_FIELD) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "field");
encoder.writeString(AttributeId.ATTRIB_TAG, "field");
}
else if (tag == ARRAY_LENGTH) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "arraylength");
encoder.writeString(AttributeId.ATTRIB_TAG, "arraylength");
}
else if (tag == INSTANCE_OF) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "instanceof");
encoder.writeString(AttributeId.ATTRIB_TAG, "instanceof");
}
else if (tag == CHECK_CAST) {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "checkcast");
encoder.writeString(AttributeId.ATTRIB_TAG, "checkcast");
}
else {
SpecXmlUtils.encodeStringAttribute(buf, "tag", "primitive");
encoder.writeString(AttributeId.ATTRIB_TAG, "primitive");
}
if (isConstructor) {
SpecXmlUtils.encodeBooleanAttribute(buf, "constructor", true);
encoder.writeBool(AttributeId.ATTRIB_CONSTRUCTOR, true);
}
buf.append(">\n");
if (tag == PRIMITIVE) {
buf.append("<value>");
buf.append(SpecXmlUtils.encodeUnsignedInteger(value));
buf.append("</value>\n");
encoder.openElement(ElementId.ELEM_VALUE);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_CONTENT, value);
encoder.closeElement(ElementId.ELEM_VALUE);
}
if (byteData != null) {
buf.append("<data length=\"").append(byteData.length).append("\">\n");
encoder.openElement(ElementId.ELEM_DATA);
encoder.writeSignedInteger(AttributeId.ATTRIB_LENGTH, byteData.length);
StringBuilder buf = new StringBuilder();
int wrap = 0;
for (byte val : byteData) {
int hival = (val >> 4) & 0xf;
@ -95,16 +96,16 @@ public abstract class ConstantPool {
wrap = 0;
}
}
buf.append("</data>\n");
encoder.writeString(AttributeId.ATTRIB_CONTENT, buf.toString());
encoder.closeElement(ElementId.ELEM_DATA);
}
else {
buf.append("<token>");
SpecXmlUtils.xmlEscape(buf, token);
buf.append("</token>\n");
encoder.openElement(ElementId.ELEM_TOKEN);
encoder.writeString(AttributeId.ATTRIB_CONTENT, token);
encoder.closeElement(ElementId.ELEM_TOKEN);
}
dtmanage.buildTypeRef(buf, type, type.getLength());
buf.append("</cpoolrec>\n");
return buf;
dtmanage.encodeTypeRef(encoder, type, type.getLength());
encoder.closeElement(ElementId.ELEM_CPOOLREC);
}
public void setUTF8Data(String val) {

View file

@ -15,14 +15,14 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.program.model.address.Address;
import ghidra.program.model.pcode.AddressXML;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.program.model.pcode.*;
import ghidra.xml.*;
/**
@ -101,11 +101,11 @@ public final class ContextSetting {
}
}
public void saveXml(StringBuilder buffer) {
buffer.append("<set");
SpecXmlUtils.encodeStringAttribute(buffer, "name", register.getName());
SpecXmlUtils.encodeStringAttribute(buffer, "val", value.toString());
buffer.append("/>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_SET);
encoder.writeString(AttributeId.ATTRIB_NAME, register.getName());
encoder.writeString(AttributeId.ATTRIB_VAL, value.toString());
encoder.closeElement(ElementId.ELEM_SET);
}
/**
@ -164,21 +164,22 @@ public final class ContextSetting {
parser.end();
}
public static void buildContextDataXml(StringBuilder buffer, List<ContextSetting> ctxList) {
public static void encodeContextData(Encoder encoder, List<ContextSetting> ctxList)
throws IOException {
if (ctxList.isEmpty()) {
return;
}
buffer.append("<context_data>\n");
encoder.openElement(ElementId.ELEM_CONTEXT_DATA);
Iterator<ContextSetting> iter = ctxList.iterator();
ContextSetting startContext = iter.next();
boolean isContextReg = startContext.register.isProcessorContext();
Address firstAddr = startContext.startAddr;
Address lastAddr = startContext.endAddr;
while (iter.hasNext()) {
buffer.append(isContextReg ? "<context_set" : "<tracked_set");
AddressXML.appendAttributes(buffer, firstAddr, lastAddr);
buffer.append(">\n");
startContext.saveXml(buffer);
encoder.openElement(
isContextReg ? ElementId.ELEM_CONTEXT_SET : ElementId.ELEM_TRACKED_SET);
AddressXML.encodeAttributes(encoder, firstAddr, lastAddr);
startContext.encode(encoder);
while (iter.hasNext()) {
startContext = iter.next();
boolean nextIsContext = startContext.register.isProcessorContext();
@ -198,10 +199,11 @@ public final class ContextSetting {
if (shouldBreak) {
break;
}
startContext.saveXml(buffer);
startContext.encode(encoder);
}
buffer.append(isContextReg ? "</context_set>\n" : "</tracked_set>\n");
encoder.closeElement(
isContextReg ? ElementId.ELEM_CONTEXT_SET : ElementId.ELEM_TRACKED_SET);
}
buffer.append("</context_data>\n");
encoder.closeElement(ElementId.ELEM_CONTEXT_DATA);
}
}

View file

@ -15,9 +15,12 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import ghidra.app.plugin.processors.sleigh.PcodeEmit;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.Encoder;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.xml.XmlParseException;
import ghidra.xml.XmlPullParser;
@ -142,10 +145,11 @@ public interface InjectPayload {
public boolean isIncidentalCopy();
/**
* Write out configuration parameters as a \<pcode> XML tag
* @param buffer is the stream to write to
* Encode configuration parameters as a \<pcode> element to stream
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void saveXml(StringBuilder buffer);
public void encode(Encoder encoder) throws IOException;
/**
* Restore the payload from an XML stream. The root expected document is

View file

@ -15,12 +15,13 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.app.plugin.processors.sleigh.template.ConstructTpl;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.program.model.pcode.*;
import ghidra.xml.*;
public class InjectPayloadCallfixup extends InjectPayloadSleigh {
@ -58,17 +59,16 @@ public class InjectPayloadCallfixup extends InjectPayloadSleigh {
}
@Override
public void saveXml(StringBuilder buffer) {
buffer.append("<callfixup");
SpecXmlUtils.encodeStringAttribute(buffer, "name", name);
buffer.append(">\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_CALLFIXUP);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
for (String nm : targetSymbolNames) {
buffer.append("<target");
SpecXmlUtils.encodeStringAttribute(buffer, "name", nm);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_TARGET);
encoder.writeString(AttributeId.ATTRIB_NAME, nm);
encoder.closeElement(ElementId.ELEM_TARGET);
}
super.saveXml(buffer);
buffer.append("</callfixup>\n");
super.encode(encoder);
encoder.closeElement(ElementId.ELEM_CALLFIXUP);
}
@Override

View file

@ -15,9 +15,11 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.app.plugin.processors.sleigh.template.ConstructTpl;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.program.model.pcode.*;
import ghidra.xml.*;
public class InjectPayloadCallother extends InjectPayloadSleigh {
@ -46,12 +48,11 @@ public class InjectPayloadCallother extends InjectPayloadSleigh {
}
@Override
public void saveXml(StringBuilder buffer) {
buffer.append("<callotherfixup");
SpecXmlUtils.encodeStringAttribute(buffer, "targetop", name);
buffer.append(">\n");
super.saveXml(buffer);
buffer.append("</callotherfixup>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_CALLOTHERFIXUP);
encoder.writeString(AttributeId.ATTRIB_TARGETOP, name);
super.encode(encoder);
encoder.closeElement(ElementId.ELEM_CALLOTHERFIXUP);
}
@Override

View file

@ -15,9 +15,11 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.pcode.AddressXML;
import ghidra.program.model.pcode.*;
import ghidra.util.SystemUtilities;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@ -41,29 +43,28 @@ public class InjectPayloadSegment extends InjectPayloadSleigh {
}
@Override
public void saveXml(StringBuilder buffer) {
buffer.append("<segmentop");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_SEGMENTOP);
int pos = name.indexOf('_');
String subName = pos > 0 ? name.substring(0, pos) : name;
if (!subName.equals("segment")) {
SpecXmlUtils.encodeStringAttribute(buffer, "userop", subName);
encoder.writeString(AttributeId.ATTRIB_USEROP, subName);
}
SpecXmlUtils.encodeStringAttribute(buffer, "space", space.getName());
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
if (supportsFarPointer) {
SpecXmlUtils.encodeBooleanAttribute(buffer, "farpointer", supportsFarPointer);
encoder.writeBool(AttributeId.ATTRIB_FARPOINTER, supportsFarPointer);
}
buffer.append(">\n");
super.saveXml(buffer);
super.encode(encoder);
if (constResolveSpace != null) {
buffer.append("<constresolve>\n");
buffer.append("<varnode");
SpecXmlUtils.encodeStringAttribute(buffer, "space", constResolveSpace.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "offset", constResolveOffset);
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "size", constResolveSize);
buffer.append("/>\n");
buffer.append("</constresolve>\n");
encoder.openElement(ElementId.ELEM_CONSTRESOLVE);
encoder.openElement(ElementId.ELEM_VARNODE);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, constResolveSpace);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, constResolveOffset);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, constResolveSize);
encoder.closeElement(ElementId.ELEM_VARNODE);
encoder.closeElement(ElementId.ELEM_CONSTRESOLVE);
}
buffer.append("</segmentop>\n");
encoder.closeElement(ElementId.ELEM_SEGMENTOP);
}
@Override

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -24,8 +25,7 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@ -230,39 +230,40 @@ public class InjectPayloadSleigh implements InjectPayload {
}
@Override
public void saveXml(StringBuilder buffer) {
buffer.append("<pcode");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_PCODE);
if (type == CALLMECHANISM_TYPE && subType >= 0) {
SpecXmlUtils.encodeStringAttribute(buffer, "inject",
encoder.writeString(AttributeId.ATTRIB_INJECT,
(subType == 0) ? "uponentry" : "uponreturn");
}
if (paramShift != 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "paramshift", paramShift);
encoder.writeSignedInteger(AttributeId.ATTRIB_PARAMSHIFT, paramShift);
}
if (pcodeTemplate == null) {
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
encoder.writeBool(AttributeId.ATTRIB_DYNAMIC, true);
}
if (incidentalCopy) {
SpecXmlUtils.encodeBooleanAttribute(buffer, "incidentalcopy", incidentalCopy);
encoder.writeBool(AttributeId.ATTRIB_INCIDENTALCOPY, incidentalCopy);
}
buffer.append(">\n");
for (InjectParameter param : inputlist) {
buffer.append("<input");
SpecXmlUtils.encodeStringAttribute(buffer, "name", param.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "size", param.getSize());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_INPUT);
encoder.writeString(AttributeId.ATTRIB_NAME, param.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, param.getSize());
encoder.closeElement(ElementId.ELEM_INPUT);
}
for (InjectParameter param : output) {
buffer.append("<output");
SpecXmlUtils.encodeStringAttribute(buffer, "name", param.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "size", param.getSize());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_OUTPUT);
encoder.writeString(AttributeId.ATTRIB_NAME, param.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, param.getSize());
encoder.closeElement(ElementId.ELEM_OUTPUT);
}
if (pcodeTemplate != null) {
// Decompiler will not read the <body> tag
buffer.append("<body> local tmp:1 = 0; </body>\n");
encoder.openElement(ElementId.ELEM_BODY);
encoder.writeString(AttributeId.ATTRIB_CONTENT, " local tmp:1 = 0; ");
encoder.closeElement(ElementId.ELEM_BODY);
}
buffer.append("</pcode>\n");
encoder.closeElement(ElementId.ELEM_PCODE);
}
@Override

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
@ -22,8 +23,7 @@ import ghidra.app.plugin.processors.sleigh.VarnodeData;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.*;
import ghidra.program.model.pcode.AddressXML;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.SystemUtilities;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@ -437,16 +437,16 @@ public class ParamEntry {
flags |= OVERLAPPING;
}
public void saveXml(StringBuilder buffer) {
buffer.append("<pentry");
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "minsize", minsize);
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "maxsize", size);
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_PENTRY);
encoder.writeSignedInteger(AttributeId.ATTRIB_MINSIZE, minsize);
encoder.writeSignedInteger(AttributeId.ATTRIB_MAXSIZE, size);
if (alignment != 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "align", alignment);
encoder.writeSignedInteger(AttributeId.ATTRIB_ALIGN, alignment);
}
if (type == TYPE_FLOAT || type == TYPE_PTR) {
String tok = (type == TYPE_FLOAT) ? "float" : "ptr";
SpecXmlUtils.encodeStringAttribute(buffer, "metatype", tok);
encoder.writeString(AttributeId.ATTRIB_METATYPE, tok);
}
String extString = null;
if ((flags & SMALLSIZE_SEXT) != 0) {
@ -462,9 +462,8 @@ public class ParamEntry {
extString = "float";
}
if (extString != null) {
SpecXmlUtils.encodeStringAttribute(buffer, "extension", extString);
encoder.writeString(AttributeId.ATTRIB_EXTENSION, extString);
}
buffer.append(">\n");
AddressXML addressSize;
if (joinrec == null) {
// Treat as unsized address with no size
@ -473,8 +472,8 @@ public class ParamEntry {
else {
addressSize = new AddressXML(spaceid, addressbase, size, joinrec);
}
addressSize.saveXml(buffer);
buffer.append("</pentry>");
addressSize.encode(encoder);
encoder.closeElement(ElementId.ELEM_PENTRY);
}
public void restoreXml(XmlPullParser parser, CompilerSpec cspec, List<ParamEntry> curList,

View file

@ -15,12 +15,14 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.VariableStorage;
import ghidra.program.model.pcode.Encoder;
import ghidra.xml.XmlParseException;
import ghidra.xml.XmlPullParser;
@ -44,7 +46,7 @@ public interface ParamList {
public void assignMap(Program prog, DataType[] proto, ArrayList<VariableStorage> res,
boolean addAutoParams);
public void saveXml(StringBuilder buffer, boolean isInput);
public void encode(Encoder encoder, boolean isInput) throws IOException;
public void restoreXml(XmlPullParser parser, CompilerSpec cspec) throws XmlParseException;

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.app.plugin.processors.sleigh.VarnodeData;
@ -22,7 +23,7 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
@ -199,39 +200,37 @@ public class ParamListStandard implements ParamList {
}
@Override
public void saveXml(StringBuilder buffer, boolean isInput) {
buffer.append(isInput ? "<input" : "<output");
public void encode(Encoder encoder, boolean isInput) throws IOException {
encoder.openElement(isInput ? ElementId.ELEM_INPUT : ElementId.ELEM_OUTPUT);
if (pointermax != 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "pointermax", pointermax);
encoder.writeSignedInteger(AttributeId.ATTRIB_POINTERMAX, pointermax);
}
if (thisbeforeret) {
SpecXmlUtils.encodeStringAttribute(buffer, "thisbeforeretpointer", "yes");
encoder.writeBool(AttributeId.ATTRIB_THISBEFORERETPOINTER, true);
}
if (isInput && resourceTwoStart == 0) {
SpecXmlUtils.encodeBooleanAttribute(buffer, "separatefloat", false);
encoder.writeBool(AttributeId.ATTRIB_SEPARATEFLOAT, false);
}
buffer.append(">\n");
int curgroup = -1;
for (ParamEntry el : entry) {
if (curgroup >= 0) {
if (!el.isGrouped() || el.getGroup() != curgroup) {
buffer.append("</group>\n");
encoder.closeElement(ElementId.ELEM_GROUP);
curgroup = -1;
}
}
if (el.isGrouped()) {
if (curgroup < 0) {
buffer.append("<group>\n");
encoder.openElement(ElementId.ELEM_GROUP);
curgroup = el.getGroup();
}
}
el.saveXml(buffer);
buffer.append('\n');
el.encode(encoder);
}
if (curgroup >= 0) {
buffer.append("</group>\n");
encoder.closeElement(ElementId.ELEM_GROUP);
}
buffer.append(isInput ? "</input>" : "</output>");
encoder.closeElement(isInput ? ElementId.ELEM_INPUT : ElementId.ELEM_OUTPUT);
}
private void parsePentry(XmlPullParser parser, CompilerSpec cspec, ArrayList<ParamEntry> pe,

View file

@ -23,6 +23,7 @@ import ghidra.app.plugin.processors.sleigh.*;
import ghidra.app.plugin.processors.sleigh.template.ConstructTpl;
import ghidra.program.model.lang.InjectPayload.InjectParameter;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.Encoder;
import ghidra.sleigh.grammar.Location;
import ghidra.util.Msg;
import ghidra.xml.XmlParseException;
@ -375,25 +376,26 @@ public class PcodeInjectLibrary {
}
/**
* Save the parts of the inject library that come from the compiler spec
* to the output stream as XML tags
* @param buffer is the output stream
* Encode the parts of the inject library that come from the compiler spec
* to the output stream
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void saveCompilerSpecXml(StringBuilder buffer) {
public void encodeCompilerSpec(Encoder encoder) throws IOException {
for (InjectPayload injectPayload : callFixupMap.values()) {
if (injectPayload instanceof InjectPayloadSleigh) {
((InjectPayloadSleigh) injectPayload).saveXml(buffer);
((InjectPayloadSleigh) injectPayload).encode(encoder);
}
}
for (InjectPayload injectPayload : callOtherFixupMap.values()) {
if (injectPayload instanceof InjectPayloadSleigh) {
((InjectPayloadSleigh) injectPayload).saveXml(buffer);
((InjectPayloadSleigh) injectPayload).encode(encoder);
}
}
for (InjectPayload injectPayload : exePcodeMap.values()) {
if (injectPayload instanceof InjectPayloadSegment) {
if (injectPayload.getSource().startsWith("cspec")) {
((InjectPayloadSleigh) injectPayload).saveXml(buffer);
((InjectPayloadSleigh) injectPayload).encode(encoder);
}
}
}

View file

@ -15,14 +15,14 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.program.database.SpecExtension;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.AddressXML;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
@ -417,89 +417,87 @@ public class PrototypeModel {
}
/**
* Marshal this object as XML to an output buffer
* @param buffer is the output buffer
* Encode this object to an output stream
* @param encoder is the stream encoder
* @param injectLibrary is a library containing any inject payloads associated with the model
* @throws IOException for errors writing to the underlying stream
*/
public void saveXml(StringBuilder buffer, PcodeInjectLibrary injectLibrary) {
public void encode(Encoder encoder, PcodeInjectLibrary injectLibrary) throws IOException {
if (compatModel != null) {
buffer.append("<modelalias");
SpecXmlUtils.encodeStringAttribute(buffer, "name", name);
SpecXmlUtils.encodeStringAttribute(buffer, "parent", compatModel.name);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_MODELALIAS);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
encoder.writeString(AttributeId.ATTRIB_PARENT, compatModel.name);
encoder.closeElement(ElementId.ELEM_MODELALIAS);
return;
}
buffer.append("<prototype");
SpecXmlUtils.encodeStringAttribute(buffer, "name", name);
encoder.openElement(ElementId.ELEM_PROTOTYPE);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
if (extrapop != PrototypeModel.UNKNOWN_EXTRAPOP) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "extrapop", extrapop);
encoder.writeSignedInteger(AttributeId.ATTRIB_EXTRAPOP, extrapop);
}
else {
SpecXmlUtils.encodeStringAttribute(buffer, "extrapop", "unknown");
encoder.writeString(AttributeId.ATTRIB_EXTRAPOP, "unknown");
}
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "stackshift", stackshift);
encoder.writeSignedInteger(AttributeId.ATTRIB_STACKSHIFT, stackshift);
GenericCallingConvention nameType = GenericCallingConvention.guessFromName(name);
if (nameType != genericCallingConvention) {
SpecXmlUtils.encodeStringAttribute(buffer, "type",
encoder.writeString(AttributeId.ATTRIB_TYPE,
genericCallingConvention.getDeclarationName());
}
if (hasThis) {
SpecXmlUtils.encodeStringAttribute(buffer, "hasthis", "yes");
encoder.writeBool(AttributeId.ATTRIB_HASTHIS, true);
}
if (isConstruct) {
SpecXmlUtils.encodeStringAttribute(buffer, "constructor", "yes");
encoder.writeBool(AttributeId.ATTRIB_CONSTRUCTOR, true);
}
if (inputListType != InputListType.STANDARD) {
SpecXmlUtils.encodeStringAttribute(buffer, "strategy", "register");
encoder.writeString(AttributeId.ATTRIB_STRATEGY, "register");
}
buffer.append(">\n");
inputParams.saveXml(buffer, true);
buffer.append('\n');
outputParams.saveXml(buffer, false);
buffer.append('\n');
inputParams.encode(encoder, true);
outputParams.encode(encoder, false);
if (hasUponEntry || hasUponReturn) {
InjectPayload payload =
injectLibrary.getPayload(InjectPayload.CALLMECHANISM_TYPE, getInjectName());
payload.saveXml(buffer);
payload.encode(encoder);
}
if (unaffected != null) {
buffer.append("<unaffected>\n");
writeVarnodes(buffer, unaffected);
buffer.append("</unaffected>\n");
encoder.openElement(ElementId.ELEM_UNAFFECTED);
encodeVarnodes(encoder, unaffected);
encoder.closeElement(ElementId.ELEM_UNAFFECTED);
}
if (killedbycall != null) {
buffer.append("<killedbycall>\n");
writeVarnodes(buffer, killedbycall);
buffer.append("</killedbycall>\n");
encoder.openElement(ElementId.ELEM_KILLEDBYCALL);
encodeVarnodes(encoder, killedbycall);
encoder.closeElement(ElementId.ELEM_KILLEDBYCALL);
}
if (likelytrash != null) {
buffer.append("<likelytrash>\n");
writeVarnodes(buffer, likelytrash);
buffer.append("</likelytrash>\n");
encoder.openElement(ElementId.ELEM_LIKELYTRASH);
encodeVarnodes(encoder, likelytrash);
encoder.closeElement(ElementId.ELEM_LIKELYTRASH);
}
if (returnaddress != null) {
buffer.append("<returnaddress>\n");
writeVarnodes(buffer, returnaddress);
buffer.append("</returnaddress>\n");
encoder.openElement(ElementId.ELEM_RETURNADDRESS);
encodeVarnodes(encoder, returnaddress);
encoder.closeElement(ElementId.ELEM_RETURNADDRESS);
}
if (localRange != null && !localRange.isEmpty()) {
buffer.append("<localrange>\n");
writeAddressSet(buffer, localRange);
buffer.append("</localrange>\n");
encoder.openElement(ElementId.ELEM_LOCALRANGE);
encodeAddressSet(encoder, localRange);
encoder.closeElement(ElementId.ELEM_LOCALRANGE);
}
if (paramRange != null && !paramRange.isEmpty()) {
buffer.append("<paramrange>\n");
writeAddressSet(buffer, paramRange);
buffer.append("</paramrange>\n");
encoder.openElement(ElementId.ELEM_PARAMRANGE);
encodeAddressSet(encoder, paramRange);
encoder.closeElement(ElementId.ELEM_PARAMRANGE);
}
buffer.append("</prototype>\n");
encoder.closeElement(ElementId.ELEM_PROTOTYPE);
}
private void writeVarnodes(StringBuilder buffer, Varnode[] varnodes) {
private void encodeVarnodes(Encoder encoder, Varnode[] varnodes) throws IOException {
for (Varnode vn : varnodes) {
buffer.append("<varnode");
AddressXML.appendAttributes(buffer, vn.getAddress(), vn.getSize());
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_VARNODE);
AddressXML.encodeAttributes(encoder, vn.getAddress(), vn.getSize());
encoder.closeElement(ElementId.ELEM_VARNODE);
}
}
@ -523,7 +521,7 @@ public class PrototypeModel {
return res;
}
private void writeAddressSet(StringBuilder buffer, AddressSet addressSet) {
private void encodeAddressSet(Encoder encoder, AddressSet addressSet) throws IOException {
AddressRangeIterator iter = addressSet.getAddressRanges();
while (iter.hasNext()) {
AddressRange addrRange = iter.next();
@ -543,22 +541,22 @@ public class PrototypeModel {
if (first < 0 && last >= 0) { // Range crosses 0
first &= mask;
// Split out the piece coming before 0
buffer.append("<range");
SpecXmlUtils.encodeStringAttribute(buffer, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "first", first);
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "last", mask);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_RANGE);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, first);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, mask);
encoder.closeElement(ElementId.ELEM_RANGE);
// Reset first,last to be the piece coming after 0
first = 0;
}
first &= mask;
last &= mask;
}
buffer.append("<range");
SpecXmlUtils.encodeStringAttribute(buffer, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "first", first);
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "last", last);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_RANGE);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, first);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, last);
encoder.closeElement(ElementId.ELEM_RANGE);
}
}

View file

@ -15,12 +15,13 @@
*/
package ghidra.program.model.lang;
import java.io.IOException;
import java.util.*;
import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Parameter;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.program.model.pcode.*;
import ghidra.xml.*;
/**
@ -54,16 +55,15 @@ public class PrototypeModelMerged extends PrototypeModel {
}
@Override
public void saveXml(StringBuilder buffer, PcodeInjectLibrary injectLibrary) {
buffer.append("<resolveprototype");
SpecXmlUtils.encodeStringAttribute(buffer, "name", name);
buffer.append(">\n");
public void encode(Encoder encoder, PcodeInjectLibrary injectLibrary) throws IOException {
encoder.openElement(ElementId.ELEM_RESOLVEPROTOTYPE);
encoder.writeString(AttributeId.ATTRIB_NAME, name);
for (PrototypeModel model : modellist) {
buffer.append("<model");
SpecXmlUtils.encodeStringAttribute(buffer, "name", model.name);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_MODEL);
encoder.writeString(AttributeId.ATTRIB_NAME, model.name);
encoder.closeElement(ElementId.ELEM_MODEL);
}
buffer.append("</resolveprototype>\n");
encoder.closeElement(ElementId.ELEM_RESOLVEPROTOTYPE);
}
public void restoreXml(XmlPullParser parser, List<PrototypeModel> modelList)

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.program.model.address.Address;
@ -127,10 +128,11 @@ public class AddressXML {
}
/**
* Write this sized address as an \<addr> XML tag.
* @param buffer is the buffer to write to
* Encode this sized address as an \<addr> element to the stream
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
public void saveXml(StringBuilder buffer) {
public void encode(Encoder encoder) throws IOException {
if (joinRecord != null) {
long logicalSize = size;
long sizeSum = 0;
@ -140,18 +142,18 @@ public class AddressXML {
if (sizeSum == size) {
logicalSize = 0;
}
buildXML(buffer, joinRecord, logicalSize);
encode(encoder, joinRecord, logicalSize);
return;
}
buffer.append("<addr");
encoder.openElement(ElementId.ELEM_ADDR);
if (space != null) {
SpecXmlUtils.encodeStringAttribute(buffer, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "offset", offset);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, offset);
if (size != 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "size", size);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, size);
}
}
buffer.append("/>");
encoder.closeElement(ElementId.ELEM_ADDR);
}
/**
@ -432,12 +434,13 @@ public class AddressXML {
}
/**
* Append "space" and "offset" attributes describing the given Address to the XML stream.
* This assumes the XML tag name has already been emitted.
* @param buf is the XML stream
* Encode "space" and "offset" attributes for the current element, describing the
* given Address to the stream.
* @param encoder is the stream encoder
* @param addr is the given Address
* @throws IOException for errors in the underlying stream
*/
public static void appendAttributes(StringBuilder buf, Address addr) {
public static void encodeAttributes(Encoder encoder, Address addr) throws IOException {
AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
if (space.getType() != AddressSpace.TYPE_OTHER) {
@ -445,18 +448,20 @@ public class AddressXML {
addr = space.getAddress(addr.getOffset());
}
}
SpecXmlUtils.encodeStringAttribute(buf, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "offset", addr.getUnsignedOffset());
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, addr.getUnsignedOffset());
}
/**
* Append "space" "offset" and "size" attributes describing the given memory range to the XML stream.
* This assumes the XML tag name has already been emitted.
* @param buf is the XML stream
* Encode "space" "offset" and "size" attributes for the current element, describing
* the given memory range to the stream.
* @param encoder is the stream encoder
* @param addr is the starting Address of the memory range
* @param size is the size of the memory range
* @throws IOException for errors in the underlying stream
*/
public static void appendAttributes(StringBuilder buf, Address addr, int size) {
public static void encodeAttributes(Encoder encoder, Address addr, int size)
throws IOException {
AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
if (space.getType() != AddressSpace.TYPE_OTHER) {
@ -464,19 +469,22 @@ public class AddressXML {
addr = space.getAddress(addr.getOffset());
}
}
SpecXmlUtils.encodeStringAttribute(buf, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "offset", addr.getUnsignedOffset());
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "size", size);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, addr.getUnsignedOffset());
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, size);
}
/**
* Append a memory range, as "space", "first", and "last" attributes, to the XML stream.
* This assumes the XML tag name has already been emitted.
* @param buffer is the XML stream
* Encode a memory range, as "space", "first", and "last" attributes, for the current element,
* to the stream.
* @param encoder is the stream encoder
* @param startAddr is the first address in the range
* @param endAddr is the last address in the range
* @throws IOException for errors in the underlying stream
*/
public static void appendAttributes(StringBuilder buffer, Address startAddr, Address endAddr) {
public static void encodeAttributes(Encoder encoder, Address startAddr, Address endAddr)
throws IOException {
AddressSpace space = startAddr.getAddressSpace();
long offset = startAddr.getOffset();
long size = endAddr.getOffset() - offset + 1;
@ -492,91 +500,114 @@ public class AddressXML {
long last = offset + size - 1;
boolean useFirst = (offset != 0);
boolean useLast = (last != -1);
SpecXmlUtils.encodeStringAttribute(buffer, "space", space.getName());
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
if (useFirst) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "first", offset);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, offset);
}
if (useLast) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "last", last);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, last);
}
}
/**
* Write out the given Address as an \<addr> tag to the XML stream
* Encode the given Address as an \<addr> element to the stream
*
* @param buf is the XML stream
* @param addr -- Address to convert to XML
* @param encoder is the stream encoder
* @param addr -- Address to encode
* @throws IOException for errors in the underlying stream
*/
public static void buildXML(StringBuilder buf, Address addr) {
public static void encode(Encoder encoder, Address addr) throws IOException {
encoder.openElement(ElementId.ELEM_ADDR);
if ((addr == null) || (addr == Address.NO_ADDRESS)) {
buf.append("<addr/>");
encoder.closeElement(ElementId.ELEM_ADDR);
return;
}
buf.append("<addr");
AddressXML.appendAttributes(buf, addr);
buf.append("/>");
encodeAttributes(encoder, addr);
encoder.closeElement(ElementId.ELEM_ADDR);
}
/**
* Write out the given Address and a size as an \<addr> tag to the XML stream
* Encode the given Address and a size as an \<addr> element to the stream
*
* @param buf is the XML stream
* @param encoder is the stream encoder
* @param addr is the given Address
* @param size is the given size
* @throws IOException for errors in the underlying stream
*/
public static void buildXML(StringBuilder buf, Address addr, int size) {
buf.append("<addr");
AddressXML.appendAttributes(buf, addr, size);
buf.append("/>");
public static void encode(Encoder encoder, Address addr, int size) throws IOException {
encoder.openElement(ElementId.ELEM_ADDR);
encodeAttributes(encoder, addr, size);
encoder.closeElement(ElementId.ELEM_ADDR);
}
private static void buildVarnodePiece(StringBuilder buf, Address addr, int size) {
private static String encodeVarnodePiece(Varnode vn) {
StringBuilder buffer = new StringBuilder();
Address addr = vn.getAddress();
AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
space = space.getPhysicalSpace();
addr = space.getAddress(addr.getOffset());
}
buf.append(space.getName());
buf.append(":0x");
buffer.append(space.getName());
buffer.append(":0x");
long off = addr.getUnsignedOffset();
buf.append(Long.toHexString(off));
buf.append(':');
buf.append(Integer.toString(size));
buffer.append(Long.toHexString(off));
buffer.append(':');
buffer.append(Integer.toString(vn.getSize()));
return buffer.toString();
}
/**
* Write out a sequence of Varnodes as a single \<addr> tag to an XML stream.
* Encode a sequence of Varnodes as a single \<addr> element to the stream.
* If there is more than one Varnode, or if the logical size is non-zero,
* the \<addr> tag will specify the address space as "join" and will have
* the \<addr> element will specify the address space as "join" and will have
* additional "piece" attributes.
*
* @param buf is the XML stream
* @param encoder is the stream encoder
* @param varnodes is the sequence of storage varnodes
* @param logicalsize is the logical size value of the varnode
* @throws IOException for errors in the underlying stream
*/
public static void buildXML(StringBuilder buf, Varnode[] varnodes, long logicalsize) {
public static void encode(Encoder encoder, Varnode[] varnodes, long logicalsize)
throws IOException {
if (varnodes == null) {
buf.append("<addr/>");
encoder.openElement(ElementId.ELEM_ADDR);
encoder.closeElement(ElementId.ELEM_ADDR);
return;
}
if ((varnodes.length == 1) && (logicalsize == 0)) {
AddressXML.buildXML(buf, varnodes[0].getAddress(), varnodes[0].getSize());
AddressXML.encode(encoder, varnodes[0].getAddress(), varnodes[0].getSize());
return;
}
buf.append("<addr space=\"join\"");
int piece = 0;
for (Varnode vn : varnodes) {
buf.append(" piece");
buf.append(Integer.toString(++piece));
buf.append("=\"");
buildVarnodePiece(buf, vn.getAddress(), vn.getSize());
buf.append("\"");
encoder.openElement(ElementId.ELEM_ADDR);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, AddressSpace.VARIABLE_SPACE);
encoder.writeString(AttributeId.ATTRIB_PIECE1, encodeVarnodePiece(varnodes[0]));
encoder.writeString(AttributeId.ATTRIB_PIECE2, encodeVarnodePiece(varnodes[1]));
if (varnodes.length > 2) {
encoder.writeString(AttributeId.ATTRIB_PIECE3, encodeVarnodePiece(varnodes[2]));
}
if (varnodes.length > 3) {
encoder.writeString(AttributeId.ATTRIB_PIECE4, encodeVarnodePiece(varnodes[3]));
}
if (varnodes.length > 4) {
encoder.writeString(AttributeId.ATTRIB_PIECE5, encodeVarnodePiece(varnodes[4]));
}
if (varnodes.length > 5) {
encoder.writeString(AttributeId.ATTRIB_PIECE6, encodeVarnodePiece(varnodes[5]));
}
if (varnodes.length > 6) {
encoder.writeString(AttributeId.ATTRIB_PIECE7, encodeVarnodePiece(varnodes[6]));
}
if (varnodes.length > 7) {
encoder.writeString(AttributeId.ATTRIB_PIECE8, encodeVarnodePiece(varnodes[7]));
}
if (varnodes.length > 8) {
encoder.writeString(AttributeId.ATTRIB_PIECE9, encodeVarnodePiece(varnodes[8]));
}
if (logicalsize != 0) {
buf.append(" logicalsize=\"").append(logicalsize).append('\"');
encoder.writeSignedInteger(AttributeId.ATTRIB_LOGICALSIZE, logicalsize);
}
buf.append("/>");
encoder.closeElement(ElementId.ELEM_ADDR);
}
}

View file

@ -32,14 +32,16 @@ import java.util.HashMap;
* The same AttributeId can be used to label a different type of data when associated with a different ElementId.
*/
public class AttributeId {
private static HashMap<String, Integer> lookupAttributeId = new HashMap<>();
private static HashMap<String, AttributeId> lookupAttributeId = new HashMap<>();
private final String name; // The name of the attribute
private final int id; // The (internal) id of the attribute
public AttributeId(String nm, int i) {
name = nm;
id = i;
lookupAttributeId.put(nm, i);
if (null != lookupAttributeId.put(nm, this)) {
throw new RuntimeException("Duplicate AttributeId: " + nm);
}
}
public final String getName() {
@ -56,11 +58,8 @@ public class AttributeId {
* @return the associated id
*/
public static int find(String nm) {
Integer res = lookupAttributeId.get(nm);
if (res != null) {
return res.intValue();
}
return ATTRIB_UNKNOWN.id;
AttributeId res = lookupAttributeId.getOrDefault(nm, ATTRIB_UNKNOWN);
return res.id;
}
// Common attributes. Attributes with multiple uses
@ -96,147 +95,162 @@ public class AttributeId {
public static final AttributeId ATTRIB_LAST = new AttributeId("last", 28);
public static final AttributeId ATTRIB_UNIQ = new AttributeId("uniq", 29);
// architecture
public static final AttributeId ATTRIB_ADJUSTVMA = new AttributeId("adjustvma", 30);
public static final AttributeId ATTRIB_ENABLE = new AttributeId("enable", 31);
public static final AttributeId ATTRIB_GROUP = new AttributeId("group", 32);
public static final AttributeId ATTRIB_GROWTH = new AttributeId("growth", 33);
public static final AttributeId ATTRIB_LOADERSYMBOLS = new AttributeId("loadersymbols", 34);
public static final AttributeId ATTRIB_PARENT = new AttributeId("parent", 35);
public static final AttributeId ATTRIB_REGISTER = new AttributeId("register", 36);
public static final AttributeId ATTRIB_REVERSEJUSTIFY = new AttributeId("reversejustify", 37);
public static final AttributeId ATTRIB_SIGNEXT = new AttributeId("signext", 38);
public static final AttributeId ATTRIB_STYLE = new AttributeId("style", 39);
// varnode
public static final AttributeId ATTRIB_ADDRTIED = new AttributeId("addrtied", 30);
public static final AttributeId ATTRIB_GRP = new AttributeId("grp", 31);
public static final AttributeId ATTRIB_INPUT = new AttributeId("input", 32);
public static final AttributeId ATTRIB_PERSISTS = new AttributeId("persists", 33);
public static final AttributeId ATTRIB_UNAFF = new AttributeId("unaff", 34);
// block
public static final AttributeId ATTRIB_ALTINDEX = new AttributeId("altindex", 40);
public static final AttributeId ATTRIB_DEPTH = new AttributeId("depth", 41);
public static final AttributeId ATTRIB_END = new AttributeId("end", 42);
public static final AttributeId ATTRIB_OPCODE = new AttributeId("opcode", 43);
public static final AttributeId ATTRIB_REV = new AttributeId("rev", 44);
// prettyprint
public static final AttributeId ATTRIB_BLOCKREF = new AttributeId("blockref", 35);
public static final AttributeId ATTRIB_CLOSE = new AttributeId("close", 36);
public static final AttributeId ATTRIB_COLOR = new AttributeId("color", 37);
public static final AttributeId ATTRIB_INDENT = new AttributeId("indent", 38);
public static final AttributeId ATTRIB_OFF = new AttributeId("off", 39);
public static final AttributeId ATTRIB_OPEN = new AttributeId("open", 40);
public static final AttributeId ATTRIB_OPREF = new AttributeId("opref", 41);
public static final AttributeId ATTRIB_VARREF = new AttributeId("varref", 42);
// cpool
public static final AttributeId ATTRIB_A = new AttributeId("a", 45);
public static final AttributeId ATTRIB_B = new AttributeId("b", 46);
public static final AttributeId ATTRIB_LENGTH = new AttributeId("length", 47);
public static final AttributeId ATTRIB_TAG = new AttributeId("tag", 48);
// translate
public static final AttributeId ATTRIB_CODE = new AttributeId("code", 43);
public static final AttributeId ATTRIB_CONTAIN = new AttributeId("contain", 44);
public static final AttributeId ATTRIB_DEFAULTSPACE = new AttributeId("defaultspace", 45);
public static final AttributeId ATTRIB_UNIQBASE = new AttributeId("uniqbase", 46);
// type
public static final AttributeId ATTRIB_ALIGNMENT = new AttributeId("alignment", 47);
public static final AttributeId ATTRIB_ARRAYSIZE = new AttributeId("arraysize", 48);
public static final AttributeId ATTRIB_CHAR = new AttributeId("char", 49);
public static final AttributeId ATTRIB_CORE = new AttributeId("core", 50);
public static final AttributeId ATTRIB_ENUM = new AttributeId("enum", 51);
public static final AttributeId ATTRIB_ENUMSIGNED = new AttributeId("enumsigned", 52);
public static final AttributeId ATTRIB_ENUMSIZE = new AttributeId("enumsize", 53);
public static final AttributeId ATTRIB_INTSIZE = new AttributeId("intsize", 54);
public static final AttributeId ATTRIB_LONGSIZE = new AttributeId("longsize", 55);
public static final AttributeId ATTRIB_OPAQUESTRING = new AttributeId("opaquestring", 56);
public static final AttributeId ATTRIB_SIGNED = new AttributeId("signed", 57);
public static final AttributeId ATTRIB_STRUCTALIGN = new AttributeId("structalign", 58);
public static final AttributeId ATTRIB_UTF = new AttributeId("utf", 59);
public static final AttributeId ATTRIB_VARLENGTH = new AttributeId("varlength", 60);
// database
public static final AttributeId ATTRIB_CAT = new AttributeId("cat", 49);
public static final AttributeId ATTRIB_FIELD = new AttributeId("field", 50);
public static final AttributeId ATTRIB_MERGE = new AttributeId("merge", 51);
public static final AttributeId ATTRIB_SCOPEIDBYNAME = new AttributeId("scopeidbyname", 52);
public static final AttributeId ATTRIB_VOLATILE = new AttributeId("volatile", 53);
public static final AttributeId ATTRIB_CAT = new AttributeId("cat", 61);
public static final AttributeId ATTRIB_FIELD = new AttributeId("field", 62);
public static final AttributeId ATTRIB_MERGE = new AttributeId("merge", 63);
public static final AttributeId ATTRIB_SCOPEIDBYNAME = new AttributeId("scopeidbyname", 64);
public static final AttributeId ATTRIB_VOLATILE = new AttributeId("volatile", 65);
// fspec
public static final AttributeId ATTRIB_CUSTOM = new AttributeId("custom", 54);
public static final AttributeId ATTRIB_DOTDOTDOT = new AttributeId("dotdotdot", 55);
public static final AttributeId ATTRIB_EXTENSION = new AttributeId("extension", 56);
public static final AttributeId ATTRIB_HASTHIS = new AttributeId("hasthis", 57);
public static final AttributeId ATTRIB_INLINE = new AttributeId("inline", 58);
public static final AttributeId ATTRIB_KILLEDBYCALL = new AttributeId("killedbycall", 59);
public static final AttributeId ATTRIB_MAXSIZE = new AttributeId("maxsize", 60);
public static final AttributeId ATTRIB_MINSIZE = new AttributeId("minsize", 61);
public static final AttributeId ATTRIB_MODELLOCK = new AttributeId("modellock", 62);
public static final AttributeId ATTRIB_NORETURN = new AttributeId("noreturn", 63);
public static final AttributeId ATTRIB_POINTERMAX = new AttributeId("pointermax", 64);
public static final AttributeId ATTRIB_SEPARATEFLOAT = new AttributeId("separatefloat", 65);
public static final AttributeId ATTRIB_STACKSHIFT = new AttributeId("stackshift", 66);
public static final AttributeId ATTRIB_STRATEGY = new AttributeId("strategy", 67);
public static final AttributeId ATTRIB_THISBEFORERETPOINTER =
new AttributeId("thisbeforeretpointer", 68);
public static final AttributeId ATTRIB_VOIDLOCK = new AttributeId("voidlock", 69);
// funcdata
public static final AttributeId ATTRIB_NOCODE = new AttributeId("nocode", 70);
// jumptable
public static final AttributeId ATTRIB_LABEL = new AttributeId("label", 71);
public static final AttributeId ATTRIB_NUM = new AttributeId("num", 72);
// pcodeinject
public static final AttributeId ATTRIB_DYNAMIC = new AttributeId("dynamic", 74);
public static final AttributeId ATTRIB_INCIDENTALCOPY = new AttributeId("incidentalcopy", 75);
public static final AttributeId ATTRIB_INJECT = new AttributeId("inject", 76);
public static final AttributeId ATTRIB_PARAMSHIFT = new AttributeId("paramshift", 77);
public static final AttributeId ATTRIB_TARGETOP = new AttributeId("targetop", 78);
// space
public static final AttributeId ATTRIB_BASE = new AttributeId("base", 88);
public static final AttributeId ATTRIB_DEADCODEDELAY = new AttributeId("deadcodedelay", 89);
public static final AttributeId ATTRIB_DELAY = new AttributeId("delay", 90);
public static final AttributeId ATTRIB_LOGICALSIZE = new AttributeId("logicalsize", 91);
public static final AttributeId ATTRIB_PHYSICAL = new AttributeId("physical", 92);
public static final AttributeId ATTRIB_PIECE1 = new AttributeId("piece1", 93);
public static final AttributeId ATTRIB_PIECE2 = new AttributeId("piece2", 94);
public static final AttributeId ATTRIB_PIECE3 = new AttributeId("piece3", 95);
public static final AttributeId ATTRIB_PIECE4 = new AttributeId("piece4", 96);
public static final AttributeId ATTRIB_PIECE5 = new AttributeId("piece5", 97);
public static final AttributeId ATTRIB_PIECE6 = new AttributeId("piece6", 98);
public static final AttributeId ATTRIB_PIECE7 = new AttributeId("piece7", 99);
public static final AttributeId ATTRIB_PIECE8 = new AttributeId("piece8", 100);
public static final AttributeId ATTRIB_PIECE9 = new AttributeId("piece9", 101);
// variable
public static final AttributeId ATTRIB_CLASS = new AttributeId("class", 66);
public static final AttributeId ATTRIB_REPREF = new AttributeId("repref", 67);
public static final AttributeId ATTRIB_SYMREF = new AttributeId("symref", 68);
// stringmanage
public static final AttributeId ATTRIB_TRUNC = new AttributeId("trunc", 102);
public static final AttributeId ATTRIB_TRUNC = new AttributeId("trunc", 69);
// pcodeinject
public static final AttributeId ATTRIB_DYNAMIC = new AttributeId("dynamic", 70);
public static final AttributeId ATTRIB_INCIDENTALCOPY = new AttributeId("incidentalcopy", 71);
public static final AttributeId ATTRIB_INJECT = new AttributeId("inject", 72);
public static final AttributeId ATTRIB_PARAMSHIFT = new AttributeId("paramshift", 73);
public static final AttributeId ATTRIB_TARGETOP = new AttributeId("targetop", 74);
// block
public static final AttributeId ATTRIB_ALTINDEX = new AttributeId("altindex", 75);
public static final AttributeId ATTRIB_DEPTH = new AttributeId("depth", 76);
public static final AttributeId ATTRIB_END = new AttributeId("end", 77);
public static final AttributeId ATTRIB_OPCODE = new AttributeId("opcode", 78);
public static final AttributeId ATTRIB_REV = new AttributeId("rev", 79);
// cpool
public static final AttributeId ATTRIB_A = new AttributeId("a", 80);
public static final AttributeId ATTRIB_B = new AttributeId("b", 81);
public static final AttributeId ATTRIB_LENGTH = new AttributeId("length", 82);
public static final AttributeId ATTRIB_TAG = new AttributeId("tag", 83);
// funcdata
public static final AttributeId ATTRIB_NOCODE = new AttributeId("nocode", 84);
// userop
public static final AttributeId ATTRIB_FARPOINTER = new AttributeId("farpointer", 85);
public static final AttributeId ATTRIB_INPUTOP = new AttributeId("inputop", 86);
public static final AttributeId ATTRIB_OUTPUTOP = new AttributeId("outputop", 87);
public static final AttributeId ATTRIB_USEROP = new AttributeId("userop", 88);
// space
public static final AttributeId ATTRIB_BASE = new AttributeId("base", 89);
public static final AttributeId ATTRIB_DEADCODEDELAY = new AttributeId("deadcodedelay", 90);
public static final AttributeId ATTRIB_DELAY = new AttributeId("delay", 91);
public static final AttributeId ATTRIB_LOGICALSIZE = new AttributeId("logicalsize", 92);
public static final AttributeId ATTRIB_PHYSICAL = new AttributeId("physical", 93);
public static final AttributeId ATTRIB_PIECE1 = new AttributeId("piece1", 94); // piece attributes must have sequential ids
public static final AttributeId ATTRIB_PIECE2 = new AttributeId("piece2", 95);
public static final AttributeId ATTRIB_PIECE3 = new AttributeId("piece3", 96);
public static final AttributeId ATTRIB_PIECE4 = new AttributeId("piece4", 97);
public static final AttributeId ATTRIB_PIECE5 = new AttributeId("piece5", 98);
public static final AttributeId ATTRIB_PIECE6 = new AttributeId("piece6", 99);
public static final AttributeId ATTRIB_PIECE7 = new AttributeId("piece7", 100);
public static final AttributeId ATTRIB_PIECE8 = new AttributeId("piece8", 101);
public static final AttributeId ATTRIB_PIECE9 = new AttributeId("piece9", 102);
// architecture
public static final AttributeId ATTRIB_ADJUSTVMA = new AttributeId("adjustvma", 103);
public static final AttributeId ATTRIB_ENABLE = new AttributeId("enable", 104);
public static final AttributeId ATTRIB_GROUP = new AttributeId("group", 105);
public static final AttributeId ATTRIB_GROWTH = new AttributeId("growth", 106);
public static final AttributeId ATTRIB_KEY = new AttributeId("key", 107);
public static final AttributeId ATTRIB_LOADERSYMBOLS = new AttributeId("loadersymbols", 108);
public static final AttributeId ATTRIB_PARENT = new AttributeId("parent", 109);
public static final AttributeId ATTRIB_REGISTER = new AttributeId("register", 110);
public static final AttributeId ATTRIB_REVERSEJUSTIFY = new AttributeId("reversejustify", 111);
public static final AttributeId ATTRIB_SIGNEXT = new AttributeId("signext", 112);
public static final AttributeId ATTRIB_STYLE = new AttributeId("style", 113);
// fspec
public static final AttributeId ATTRIB_CUSTOM = new AttributeId("custom", 114);
public static final AttributeId ATTRIB_DOTDOTDOT = new AttributeId("dotdotdot", 115);
public static final AttributeId ATTRIB_EXTENSION = new AttributeId("extension", 116);
public static final AttributeId ATTRIB_HASTHIS = new AttributeId("hasthis", 117);
public static final AttributeId ATTRIB_INLINE = new AttributeId("inline", 118);
public static final AttributeId ATTRIB_KILLEDBYCALL = new AttributeId("killedbycall", 119);
public static final AttributeId ATTRIB_MAXSIZE = new AttributeId("maxsize", 120);
public static final AttributeId ATTRIB_MINSIZE = new AttributeId("minsize", 121);
public static final AttributeId ATTRIB_MODELLOCK = new AttributeId("modellock", 122);
public static final AttributeId ATTRIB_NORETURN = new AttributeId("noreturn", 123);
public static final AttributeId ATTRIB_POINTERMAX = new AttributeId("pointermax", 124);
public static final AttributeId ATTRIB_SEPARATEFLOAT = new AttributeId("separatefloat", 125);
public static final AttributeId ATTRIB_STACKSHIFT = new AttributeId("stackshift", 126);
public static final AttributeId ATTRIB_STRATEGY = new AttributeId("strategy", 127);
public static final AttributeId ATTRIB_THISBEFORERETPOINTER =
new AttributeId("thisbeforeretpointer", 128);
public static final AttributeId ATTRIB_VOIDLOCK = new AttributeId("voidlock", 129);
// transform
public static final AttributeId ATTRIB_VECTOR_LANE_SIZES =
new AttributeId("vector_lane_sizes", 103);
new AttributeId("vector_lane_sizes", 130);
// translate
public static final AttributeId ATTRIB_CODE = new AttributeId("code", 104);
public static final AttributeId ATTRIB_CONTAIN = new AttributeId("contain", 105);
public static final AttributeId ATTRIB_DEFAULTSPACE = new AttributeId("defaultspace", 106);
public static final AttributeId ATTRIB_UNIQBASE = new AttributeId("uniqbase", 107);
// type
public static final AttributeId ATTRIB_ALIGNMENT = new AttributeId("alignment", 108);
public static final AttributeId ATTRIB_ARRAYSIZE = new AttributeId("arraysize", 109);
public static final AttributeId ATTRIB_CHAR = new AttributeId("char", 110);
public static final AttributeId ATTRIB_CORE = new AttributeId("core", 111);
public static final AttributeId ATTRIB_ENUM = new AttributeId("enum", 112);
public static final AttributeId ATTRIB_ENUMSIGNED = new AttributeId("enumsigned", 113);
public static final AttributeId ATTRIB_ENUMSIZE = new AttributeId("enumsize", 114);
public static final AttributeId ATTRIB_INTSIZE = new AttributeId("intsize", 115);
public static final AttributeId ATTRIB_LONGSIZE = new AttributeId("longsize", 116);
public static final AttributeId ATTRIB_OPAQUESTRING = new AttributeId("opaquestring", 117);
public static final AttributeId ATTRIB_SIGNED = new AttributeId("signed", 118);
public static final AttributeId ATTRIB_STRUCTALIGN = new AttributeId("structalign", 119);
public static final AttributeId ATTRIB_UTF = new AttributeId("utf", 120);
public static final AttributeId ATTRIB_VARLENGTH = new AttributeId("varlength", 121);
// userop
public static final AttributeId ATTRIB_FARPOINTER = new AttributeId("farpointer", 122);
public static final AttributeId ATTRIB_INPUTOP = new AttributeId("inputop", 123);
public static final AttributeId ATTRIB_OUTPUTOP = new AttributeId("outputop", 124);
public static final AttributeId ATTRIB_USEROP = new AttributeId("userop", 125);
// variable
public static final AttributeId ATTRIB_CLASS = new AttributeId("class", 126);
public static final AttributeId ATTRIB_REPREF = new AttributeId("repref", 127);
public static final AttributeId ATTRIB_SYMREF = new AttributeId("symref", 128);
// jumptable
public static final AttributeId ATTRIB_LABEL = new AttributeId("label", 131);
public static final AttributeId ATTRIB_NUM = new AttributeId("num", 132);
// varmap
public static final AttributeId ATTRIB_LOCK = new AttributeId("lock", 129);
public static final AttributeId ATTRIB_MAIN = new AttributeId("main", 130);
public static final AttributeId ATTRIB_LOCK = new AttributeId("lock", 133);
public static final AttributeId ATTRIB_MAIN = new AttributeId("main", 134);
// varnode
public static final AttributeId ATTRIB_ADDRTIED = new AttributeId("addrtied", 131);
public static final AttributeId ATTRIB_GRP = new AttributeId("grp", 132);
public static final AttributeId ATTRIB_INPUT = new AttributeId("input", 133);
public static final AttributeId ATTRIB_PERSISTS = new AttributeId("persists", 134);
public static final AttributeId ATTRIB_UNAFF = new AttributeId("unaff", 135);
// loadimage_xml
// public static final AttributeId ATTRIB_ARCH = new AttributeId("arch", 135);
// prettyprint
public static final AttributeId ATTRIB_BLOCKREF = new AttributeId("blockref", 136);
public static final AttributeId ATTRIB_CLOSE = new AttributeId("close", 137);
public static final AttributeId ATTRIB_COLOR = new AttributeId("color", 138);
public static final AttributeId ATTRIB_INDENT = new AttributeId("indent", 139);
public static final AttributeId ATTRIB_OFF = new AttributeId("off", 140);
public static final AttributeId ATTRIB_OPEN = new AttributeId("open", 141);
public static final AttributeId ATTRIB_OPREF = new AttributeId("opref", 142);
public static final AttributeId ATTRIB_VARREF = new AttributeId("varref", 143);
// sleigh_arch
// public static final AttributeId ATTRIB_DEPRECATED = new AttributeId("deprecated", 136);
// public static final AttributeId ATTRIB_ENDIAN = new AttributeId("endian", 137);
// public static final AttributeId ATTRIB_PROCESSOR = new AttributeId("processor", 138);
// public static final AttributeId ATTRIB_PROCESSORSPEC = new AttributeId("processorspec", 139);
// public static final AttributeId ATTRIB_SLAFILE = new AttributeId("slafile", 140);
// public static final AttributeId ATTRIB_SPEC = new AttributeId("spec", 141);
// public static final AttributeId ATTRIB_TARGET = new AttributeId("target", 142);
// public static final AttributeId ATTRIB_VARIANT = new AttributeId("variant", 143);
// public static final AttributeId ATTRIB_VERSION = new AttributeId("version", 144);
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 147);
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 148);
}

View file

@ -15,8 +15,9 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.lang.UnknownInstructionException;
import ghidra.util.xml.SpecXmlUtils;
/**
* Block representing and '&amp;&amp;' or '||' control flow path within a conditional expression
@ -41,14 +42,14 @@ public class BlockCondition extends BlockGraph {
}
@Override
public void saveXmlHeader(StringBuilder buffer) {
super.saveXmlHeader(buffer);
protected void encodeHeader(Encoder encoder) throws IOException {
super.encodeHeader(encoder);
String opcodename = PcodeOp.getMnemonic(opcode);
SpecXmlUtils.encodeStringAttribute(buffer, "opcode", opcodename);
encoder.writeString(AttributeId.ATTRIB_OPCODE, opcodename);
}
@Override
public void decodeHeader(Decoder decoder) throws PcodeXMLException {
protected void decodeHeader(Decoder decoder) throws PcodeXMLException {
super.decodeHeader(decoder);
String opcodename = decoder.readString(AttributeId.ATTRIB_OPCODE);
try {

View file

@ -15,8 +15,9 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.util.xml.SpecXmlUtils;
/**
* Placeholder for a basic block (BlockBasic) within a structured
@ -78,13 +79,13 @@ public class BlockCopy extends PcodeBlock {
}
@Override
public void saveXmlHeader(StringBuilder buf) {
super.saveXmlHeader(buf);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "altindex", altindex);
protected void encodeHeader(Encoder encoder) throws IOException {
super.encodeHeader(encoder);
encoder.writeSignedInteger(AttributeId.ATTRIB_ALTINDEX, altindex);
}
@Override
public void decodeHeader(Decoder decoder) throws PcodeXMLException {
protected void decodeHeader(Decoder decoder) throws PcodeXMLException {
super.decodeHeader(decoder);
altindex = (int) decoder.readSignedInteger(AttributeId.ATTRIB_ALTINDEX);
}

View file

@ -16,9 +16,6 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import ghidra.util.xml.SpecXmlUtils;
/**
* A "plain" goto block
@ -51,21 +48,19 @@ public class BlockGoto extends BlockGraph {
}
@Override
public void saveXmlBody(Writer writer) throws IOException {
super.saveXmlBody(writer);
StringBuilder buf = new StringBuilder();
buf.append("<target");
protected void encodeBody(Encoder encoder) throws IOException {
super.encodeBody(encoder);
encoder.openElement(ElementId.ELEM_TARGET);
PcodeBlock leaf = gototarget.getFrontLeaf();
int depth = gototarget.calcDepth(leaf);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", leaf.getIndex());
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "depth", depth);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "type", gototype);
buf.append("/>\n");
writer.write(buf.toString());
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, leaf.getIndex());
encoder.writeSignedInteger(AttributeId.ATTRIB_DEPTH, depth);
encoder.writeSignedInteger(AttributeId.ATTRIB_TYPE, gototype);
encoder.closeElement(ElementId.ELEM_TARGET);
}
@Override
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
super.decodeBody(decoder, resolver);
int el = decoder.openElement(ElementId.ELEM_TARGET);
int target = (int) decoder.readSignedInteger(AttributeId.ATTRIB_INDEX);

View file

@ -16,11 +16,8 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import ghidra.util.xml.SpecXmlUtils;
/**
* A block (with in edges and out edges) that contains other blocks
*
@ -141,24 +138,22 @@ public class BlockGraph extends PcodeBlock {
}
@Override
public void saveXmlBody(Writer writer) throws IOException {
super.saveXmlBody(writer);
protected void encodeBody(Encoder encoder) throws IOException {
super.encodeBody(encoder);
for (PcodeBlock bl : list) {
StringBuilder buf = new StringBuilder();
buf.append("<bhead");
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", bl.getIndex());
encoder.openElement(ElementId.ELEM_BHEAD);
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, bl.getIndex());
String name = PcodeBlock.typeToName(bl.blocktype);
SpecXmlUtils.encodeStringAttribute(buf, "type", name);
buf.append("/>\n");
writer.write(buf.toString());
encoder.writeString(AttributeId.ATTRIB_TYPE, name);
encoder.closeElement(ElementId.ELEM_BHEAD);
}
for (PcodeBlock bl : list) {
bl.saveXml(writer);
bl.encode(encoder);
}
}
@Override
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
BlockMap newresolver = new BlockMap(resolver);
super.decodeBody(decoder, newresolver);
ArrayList<PcodeBlock> tmplist = new ArrayList<>();
@ -186,7 +181,7 @@ public class BlockGraph extends PcodeBlock {
* @param decoder is the stream decoder
* @throws PcodeXMLException if there are invalid encodings
*/
public void restoreXml(Decoder decoder) throws PcodeXMLException {
public void decode(Decoder decoder) throws PcodeXMLException {
BlockMap resolver = new BlockMap(decoder.getAddressFactory());
decode(decoder, resolver);
resolver.resolveGotoReferences();

View file

@ -16,9 +16,6 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import ghidra.util.xml.SpecXmlUtils;
/**
* Block representing an if () goto control flow
@ -54,21 +51,19 @@ public class BlockIfGoto extends BlockGraph {
}
@Override
public void saveXmlBody(Writer writer) throws IOException {
super.saveXmlBody(writer);
protected void encodeBody(Encoder encoder) throws IOException {
super.encodeBody(encoder);
PcodeBlock leaf = gototarget.getFrontLeaf();
int depth = gototarget.calcDepth(leaf);
StringBuilder buf = new StringBuilder();
buf.append("<target");
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", leaf.getIndex());
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "depth", depth);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "type", gototype);
buf.append("/>\n");
writer.write(buf.toString());
encoder.openElement(ElementId.ELEM_TARGET);
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, leaf.getIndex());
encoder.writeSignedInteger(AttributeId.ATTRIB_DEPTH, depth);
encoder.writeSignedInteger(AttributeId.ATTRIB_TYPE, gototype);
encoder.closeElement(ElementId.ELEM_TARGET);
}
@Override
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
super.decodeBody(decoder, resolver);
int el = decoder.openElement(ElementId.ELEM_TARGET);
int target = (int) decoder.readSignedInteger(AttributeId.ATTRIB_INDEX);

View file

@ -16,11 +16,8 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import ghidra.util.xml.SpecXmlUtils;
/**
* A block representing a 2-or-more control flow branchpoint
*
@ -45,24 +42,21 @@ public class BlockMultiGoto extends BlockGraph {
}
@Override
public void saveXmlBody(Writer writer) throws IOException {
super.saveXmlBody(writer);
protected void encodeBody(Encoder encoder) throws IOException {
super.encodeBody(encoder);
for (PcodeBlock gototarget : targets) {
StringBuilder buf = new StringBuilder();
buf.append("<target");
encoder.openElement(ElementId.ELEM_TARGET);
PcodeBlock leaf = gototarget.getFrontLeaf();
int depth = gototarget.calcDepth(leaf);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", leaf.getIndex());
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "depth", depth);
// SpecXmlUtils.encodeSignedIntegerAttribute(buf, "type", 2); // Always a break
buf.append("/>\n");
writer.write(buf.toString());
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, leaf.getIndex());
encoder.writeSignedInteger(AttributeId.ATTRIB_DEPTH, depth);
// encoder.writeSignedInteger(AttributeId.ATTRIB_TYPE, 2); // Always a break
encoder.closeElement(ElementId.ELEM_TARGET);
}
}
@Override
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
super.decodeBody(decoder, resolver);
for (;;) {
int el = decoder.peekElement();

View file

@ -33,7 +33,7 @@ import ghidra.program.model.address.AddressSpace;
* one of the read*(void) methods to extract the data. Alternately a read*(AttributeId) call can be used
* to extract data for an attribute known to be in the element. There is a special content attribute
* 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().
* This attribute will not be traversed by getNextAttributeId().
*/
public interface Decoder {
@ -67,7 +67,7 @@ public interface Decoder {
* Open (traverse into) the next child element of the current parent.
* The child becomes the current parent.
* The list of attributes is initialized for use with getNextAttributeId.
* @return the id of the child element
* @return the id of the child element or 0 if there are no additional children
*/
public int openElement();

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Program;
@ -68,9 +70,11 @@ public class DynamicEntry extends SymbolEntry {
}
@Override
public void saveXml(StringBuilder buf) {
buf.append("<hash val=\"0x").append(Long.toHexString(hash)).append("\"/>");
buildRangelistXML(buf);
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_HASH);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_VAL, hash);
encoder.closeElement(ElementId.ELEM_HASH);
encodeRangelist(encoder);
}
@Override

View file

@ -28,21 +28,23 @@ import java.util.HashMap;
* as an attribute.
*/
public class ElementId {
private static HashMap<String, Integer> lookupElementId = new HashMap<>();
private static HashMap<String, ElementId> lookupElementId = new HashMap<>();
private String name; // The name of the element
private int id; // The (internal) id of the element
public ElementId(String nm, int i) {
name = nm;
id = i;
lookupElementId.put(nm, i);
if (null != lookupElementId.put(nm, this)) {
throw new RuntimeException("Duplicate ElementId instance: " + nm);
}
}
public String getName() {
public final String getName() {
return name;
}
public int getId() {
public final int getId() {
return id;
}
@ -52,11 +54,8 @@ public class ElementId {
* @return the associated id
*/
public static int find(String nm) {
Integer res = lookupElementId.get(nm);
if (res != null) {
return res.intValue();
}
return ELEM_UNKNOWN.id;
ElementId res = lookupElementId.getOrDefault(nm, ELEM_UNKNOWN);
return res.id;
}
public static final ElementId ELEM_DATA = new ElementId("data", 1);
@ -69,267 +68,308 @@ public class ElementId {
public static final ElementId ELEM_VAL = new ElementId("val", 8);
public static final ElementId ELEM_VALUE = new ElementId("value", 9);
public static final ElementId ELEM_VOID = new ElementId("void", 10);
public static final ElementId ELEM_ADDR = new ElementId("addr", 11);
// address
public static final ElementId ELEM_ADDR = new ElementId("addr", 11);
public static final ElementId ELEM_RANGE = new ElementId("range", 12);
public static final ElementId ELEM_RANGELIST = new ElementId("rangelist", 13);
public static final ElementId ELEM_REGISTER = new ElementId("register", 14);
public static final ElementId ELEM_SEQNUM = new ElementId("seqnum", 15);
public static final ElementId ELEM_VARNODE = new ElementId("varnode", 16);
// architecture
public static final ElementId ELEM_ADDRESS_SHIFT_AMOUNT =
new ElementId("address_shift_amount", 17);
public static final ElementId ELEM_AGGRESSIVETRIM = new ElementId("aggressivetrim", 18);
public static final ElementId ELEM_COMPILER_SPEC = new ElementId("compiler_spec", 19);
public static final ElementId ELEM_DATA_SPACE = new ElementId("data_space", 20);
public static final ElementId ELEM_DEFAULT_MEMORY_BLOCKS =
new ElementId("default_memory_blocks", 21);
public static final ElementId ELEM_DEFAULT_PROTO = new ElementId("default_proto", 22);
public static final ElementId ELEM_DEFAULT_SYMBOLS = new ElementId("default_symbols", 23);
public static final ElementId ELEM_EVAL_CALLED_PROTOTYPE =
new ElementId("eval_called_prototype", 24);
public static final ElementId ELEM_EVAL_CURRENT_PROTOTYPE =
new ElementId("eval_current_prototype", 25);
public static final ElementId ELEM_EXPERIMENTAL_RULES = new ElementId("experimental_rules", 26);
public static final ElementId ELEM_FLOWOVERRIDELIST = new ElementId("flowoverridelist", 27);
public static final ElementId ELEM_FUNCPTR = new ElementId("funcptr", 28);
public static final ElementId ELEM_GLOBAL = new ElementId("global", 29);
public static final ElementId ELEM_INCIDENTALCOPY = new ElementId("incidentalcopy", 30);
public static final ElementId ELEM_INFERPTRBOUNDS = new ElementId("inferptrbounds", 31);
public static final ElementId ELEM_MODELALIAS = new ElementId("modelalias", 32);
public static final ElementId ELEM_NOHIGHPTR = new ElementId("nohighptr", 33);
public static final ElementId ELEM_PROCESSOR_SPEC = new ElementId("processor_spec", 34);
public static final ElementId ELEM_PROGRAMCOUNTER = new ElementId("programcounter", 35);
public static final ElementId ELEM_PROPERTIES = new ElementId("properties", 36);
public static final ElementId ELEM_READONLY = new ElementId("readonly", 37);
public static final ElementId ELEM_REGISTER_DATA = new ElementId("register_data", 38);
public static final ElementId ELEM_RULE = new ElementId("rule", 39);
public static final ElementId ELEM_SAVE_STATE = new ElementId("save_state", 40);
public static final ElementId ELEM_SEGMENTED_ADDRESS = new ElementId("segmented_address", 41);
public static final ElementId ELEM_SPACEBASE = new ElementId("spacebase", 42);
public static final ElementId ELEM_SPECEXTENSIONS = new ElementId("specextensions", 43);
public static final ElementId ELEM_STACKPOINTER = new ElementId("stackpointer", 44);
public static final ElementId ELEM_VOLATILE = new ElementId("volatile", 45);
// prettyprint
public static final ElementId ELEM_BREAK = new ElementId("break", 17);
public static final ElementId ELEM_CLANG_DOCUMENT = new ElementId("clang_document", 18);
public static final ElementId ELEM_FUNCNAME = new ElementId("funcname", 19);
public static final ElementId ELEM_FUNCPROTO = new ElementId("funcproto", 20);
public static final ElementId ELEM_LABEL = new ElementId("label", 21);
public static final ElementId ELEM_RETURN_TYPE = new ElementId("return_type", 22);
public static final ElementId ELEM_STATEMENT = new ElementId("statement", 23);
public static final ElementId ELEM_SYNTAX = new ElementId("syntax", 24);
public static final ElementId ELEM_VARDECL = new ElementId("vardecl", 25);
public static final ElementId ELEM_VARIABLE = new ElementId("variable", 26);
// block
public static final ElementId ELEM_BHEAD = new ElementId("bhead", 47);
public static final ElementId ELEM_BLOCK = new ElementId("block", 48);
public static final ElementId ELEM_BLOCKEDGE = new ElementId("blockedge", 49);
public static final ElementId ELEM_EDGE = new ElementId("edge", 50);
// callgraph
public static final ElementId ELEM_CALLGRAPH = new ElementId("callgraph", 51);
public static final ElementId ELEM_NODE = new ElementId("node", 52);
// comment
public static final ElementId ELEM_COMMENT = new ElementId("comment", 53);
public static final ElementId ELEM_COMMENTDB = new ElementId("commentdb", 54);
public static final ElementId ELEM_TEXT = new ElementId("text", 55);
// cpool
public static final ElementId ELEM_CONSTANTPOOL = new ElementId("constantpool", 56);
public static final ElementId ELEM_CPOOLREC = new ElementId("cpoolrec", 57);
public static final ElementId ELEM_REF = new ElementId("ref", 58);
public static final ElementId ELEM_TOKEN = new ElementId("token", 59);
// database
public static final ElementId ELEM_COLLISION = new ElementId("collision", 60);
public static final ElementId ELEM_DB = new ElementId("db", 61);
public static final ElementId ELEM_EQUATESYMBOL = new ElementId("equatesymbol", 62);
public static final ElementId ELEM_EXTERNREFSYMBOL = new ElementId("externrefsymbol", 63);
public static final ElementId ELEM_FACETSYMBOL = new ElementId("facetsymbol", 64);
public static final ElementId ELEM_FUNCTIONSHELL = new ElementId("functionshell", 65);
public static final ElementId ELEM_HASH = new ElementId("hash", 66);
public static final ElementId ELEM_HOLE = new ElementId("hole", 67);
public static final ElementId ELEM_LABELSYM = new ElementId("labelsym", 68);
public static final ElementId ELEM_MAPSYM = new ElementId("mapsym", 69);
public static final ElementId ELEM_PARENT = new ElementId("parent", 70);
public static final ElementId ELEM_PROPERTY_CHANGEPOINT =
new ElementId("property_changepoint", 71);
public static final ElementId ELEM_RANGEEQUALSSYMBOLS = new ElementId("rangeequalssymbols", 72);
public static final ElementId ELEM_SCOPE = new ElementId("scope", 73);
public static final ElementId ELEM_SYMBOLLIST = new ElementId("symbollist", 74);
// fspec
public static final ElementId ELEM_GROUP = new ElementId("group", 75);
public static final ElementId ELEM_INTERNALLIST = new ElementId("internallist", 76);
public static final ElementId ELEM_KILLEDBYCALL = new ElementId("killedbycall", 77);
public static final ElementId ELEM_LIKELYTRASH = new ElementId("likelytrash", 78);
public static final ElementId ELEM_LOCALRANGE = new ElementId("localrange", 79);
public static final ElementId ELEM_MODEL = new ElementId("model", 80);
public static final ElementId ELEM_PARAM = new ElementId("param", 81);
public static final ElementId ELEM_PARAMRANGE = new ElementId("paramrange", 82);
public static final ElementId ELEM_PENTRY = new ElementId("pentry", 83);
public static final ElementId ELEM_PROTOTYPE = new ElementId("prototype", 84);
public static final ElementId ELEM_RESOLVEPROTOTYPE = new ElementId("resolveprototype", 85);
public static final ElementId ELEM_RETPARAM = new ElementId("retparam", 86);
public static final ElementId ELEM_RETURNSYM = new ElementId("returnsym", 87);
public static final ElementId ELEM_UNAFFECTED = new ElementId("unaffected", 88);
// funcdata
public static final ElementId ELEM_AST = new ElementId("ast", 89);
public static final ElementId ELEM_FUNCTION = new ElementId("function", 90);
public static final ElementId ELEM_HIGHLIST = new ElementId("highlist", 91);
public static final ElementId ELEM_JUMPTABLELIST = new ElementId("jumptablelist", 92);
public static final ElementId ELEM_VARNODES = new ElementId("varnodes", 93);
// globalcontext
public static final ElementId ELEM_CONTEXT_DATA = new ElementId("context_data", 94);
public static final ElementId ELEM_CONTEXT_POINTS = new ElementId("context_points", 95);
public static final ElementId ELEM_CONTEXT_POINTSET = new ElementId("context_pointset", 96);
public static final ElementId ELEM_CONTEXT_SET = new ElementId("context_set", 97);
public static final ElementId ELEM_SET = new ElementId("set", 98);
public static final ElementId ELEM_TRACKED_POINTSET = new ElementId("tracked_pointset", 99);
public static final ElementId ELEM_TRACKED_SET = new ElementId("tracked_set", 100);
// jumptable
public static final ElementId ELEM_BASICOVERRIDE = new ElementId("basicoverride", 101);
public static final ElementId ELEM_DEST = new ElementId("dest", 102);
public static final ElementId ELEM_JUMPTABLE = new ElementId("jumptable", 103);
public static final ElementId ELEM_LOADTABLE = new ElementId("loadtable", 104);
public static final ElementId ELEM_NORMADDR = new ElementId("normaddr", 105);
public static final ElementId ELEM_NORMHASH = new ElementId("normhash", 106);
public static final ElementId ELEM_STARTVAL = new ElementId("startval", 107);
// op
public static final ElementId ELEM_IOP = new ElementId("iop", 110);
// options
public static final ElementId ELEM_ALIASBLOCK = new ElementId("aliasblock", 111);
public static final ElementId ELEM_ALLOWCONTEXTSET = new ElementId("allowcontextset", 112);
public static final ElementId ELEM_ANALYZEFORLOOPS = new ElementId("analyzeforloops", 113);
public static final ElementId ELEM_COMMENTHEADER = new ElementId("commentheader", 114);
public static final ElementId ELEM_COMMENTINDENT = new ElementId("commentindent", 115);
public static final ElementId ELEM_COMMENTINSTRUCTION =
new ElementId("commentinstruction", 116);
public static final ElementId ELEM_COMMENTSTYLE = new ElementId("commentstyle", 117);
public static final ElementId ELEM_CONVENTIONPRINTING =
new ElementId("conventionprinting", 118);
public static final ElementId ELEM_CURRENTACTION = new ElementId("currentaction", 119);
public static final ElementId ELEM_DEFAULTPROTOTYPE = new ElementId("defaultprototype", 120);
public static final ElementId ELEM_ERRORREINTERPRETED =
new ElementId("errorreinterpreted", 121);
public static final ElementId ELEM_ERRORTOOMANYINSTRUCTIONS =
new ElementId("errortoomanyinstructions", 122);
public static final ElementId ELEM_ERRORUNIMPLEMENTED =
new ElementId("errorunimplemented", 123);
public static final ElementId ELEM_EXTRAPOP = new ElementId("extrapop", 124);
public static final ElementId ELEM_IGNOREUNIMPLEMENTED =
new ElementId("ignoreunimplemented", 125);
public static final ElementId ELEM_INDENTINCREMENT = new ElementId("indentincrement", 126);
public static final ElementId ELEM_INFERCONSTPTR = new ElementId("inferconstptr", 127);
public static final ElementId ELEM_INLINE = new ElementId("inline", 128);
public static final ElementId ELEM_INPLACEOPS = new ElementId("inplaceops", 129);
public static final ElementId ELEM_INTEGERFORMAT = new ElementId("integerformat", 130);
public static final ElementId ELEM_JUMPLOAD = new ElementId("jumpload", 131);
public static final ElementId ELEM_MAXINSTRUCTION = new ElementId("maxinstruction", 132);
public static final ElementId ELEM_MAXLINEWIDTH = new ElementId("maxlinewidth", 133);
public static final ElementId ELEM_NAMESPACESTRATEGY = new ElementId("namespacestrategy", 134);
public static final ElementId ELEM_NOCASTPRINTING = new ElementId("nocastprinting", 135);
public static final ElementId ELEM_NORETURN = new ElementId("noreturn", 136);
public static final ElementId ELEM_NULLPRINTING = new ElementId("nullprinting", 137);
public static final ElementId ELEM_OPTIONSLIST = new ElementId("optionslist", 138);
public static final ElementId ELEM_PARAM1 = new ElementId("param1", 139);
public static final ElementId ELEM_PARAM2 = new ElementId("param2", 140);
public static final ElementId ELEM_PARAM3 = new ElementId("param3", 141);
public static final ElementId ELEM_PROTOEVAL = new ElementId("protoeval", 142);
public static final ElementId ELEM_SETACTION = new ElementId("setaction", 143);
public static final ElementId ELEM_SETLANGUAGE = new ElementId("setlanguage", 144);
public static final ElementId ELEM_STRUCTALIGN = new ElementId("structalign", 145);
public static final ElementId ELEM_TOGGLERULE = new ElementId("togglerule", 146);
public static final ElementId ELEM_WARNING = new ElementId("warning", 147);
// override
public static final ElementId ELEM_DEADCODEDELAY = new ElementId("deadcodedelay", 148);
public static final ElementId ELEM_FLOW = new ElementId("flow", 149);
public static final ElementId ELEM_FORCEGOTO = new ElementId("forcegoto", 150);
public static final ElementId ELEM_INDIRECTOVERRIDE = new ElementId("indirectoverride", 151);
public static final ElementId ELEM_MULTISTAGEJUMP = new ElementId("multistagejump", 152);
public static final ElementId ELEM_OVERRIDE = new ElementId("override", 153);
public static final ElementId ELEM_PROTOOVERRIDE = new ElementId("protooverride", 154);
// paramid
public static final ElementId ELEM_PARAMMEASURES = new ElementId("parammeasures", 155);
public static final ElementId ELEM_PROTO = new ElementId("proto", 156);
public static final ElementId ELEM_RANK = new ElementId("rank", 157);
// pcodeinject
public static final ElementId ELEM_ADDR_PCODE = new ElementId("addr_pcode", 158);
public static final ElementId ELEM_BODY = new ElementId("body", 159);
public static final ElementId ELEM_CALLFIXUP = new ElementId("callfixup", 160);
public static final ElementId ELEM_CALLOTHERFIXUP = new ElementId("callotherfixup", 161);
public static final ElementId ELEM_CASE_PCODE = new ElementId("case_pcode", 162);
public static final ElementId ELEM_CONTEXT = new ElementId("context", 163);
public static final ElementId ELEM_DEFAULT_PCODE = new ElementId("default_pcode", 164);
public static final ElementId ELEM_INJECT = new ElementId("inject", 165);
public static final ElementId ELEM_INJECTDEBUG = new ElementId("injectdebug", 166);
public static final ElementId ELEM_INST = new ElementId("inst", 167);
public static final ElementId ELEM_PAYLOAD = new ElementId("payload", 168);
public static final ElementId ELEM_PCODE = new ElementId("pcode", 169);
public static final ElementId ELEM_SIZE_PCODE = new ElementId("size_pcode", 170);
// prefersplit
public static final ElementId ELEM_PREFERSPLIT = new ElementId("prefersplit", 171);
// stringmanage
public static final ElementId ELEM_BYTES = new ElementId("bytes", 177);
public static final ElementId ELEM_STRING = new ElementId("string", 178);
public static final ElementId ELEM_STRINGMANAGE = new ElementId("stringmanage", 179);
// translate
public static final ElementId ELEM_OP = new ElementId("op", 180);
public static final ElementId ELEM_SLEIGH = new ElementId("sleigh", 181);
public static final ElementId ELEM_SPACE = new ElementId("space", 182);
public static final ElementId ELEM_SPACEID = new ElementId("spaceid", 183);
public static final ElementId ELEM_SPACES = new ElementId("spaces", 184);
public static final ElementId ELEM_SPACE_BASE = new ElementId("space_base", 185);
public static final ElementId ELEM_SPACE_OTHER = new ElementId("space_other", 186);
public static final ElementId ELEM_SPACE_OVERLAY = new ElementId("space_overlay", 187);
public static final ElementId ELEM_SPACE_UNIQUE = new ElementId("space_unique", 188);
public static final ElementId ELEM_TRUNCATE_SPACE = new ElementId("truncate_space", 189);
// transform
public static final ElementId ELEM_OP = new ElementId("op", 27);
public static final ElementId ELEM_SLEIGH = new ElementId("sleigh", 28);
public static final ElementId ELEM_SPACE = new ElementId("space", 29);
public static final ElementId ELEM_SPACEID = new ElementId("spaceid", 30);
public static final ElementId ELEM_SPACES = new ElementId("spaces", 31);
public static final ElementId ELEM_SPACE_BASE = new ElementId("space_base", 32);
public static final ElementId ELEM_SPACE_OTHER = new ElementId("space_other", 33);
public static final ElementId ELEM_SPACE_OVERLAY = new ElementId("space_overlay", 34);
public static final ElementId ELEM_SPACE_UNIQUE = new ElementId("space_unique", 35);
public static final ElementId ELEM_TRUNCATE_SPACE = new ElementId("truncate_space", 36);
// type
public static final ElementId ELEM_CORETYPES = new ElementId("coretypes", 190);
public static final ElementId ELEM_DATA_ORGANIZATION = new ElementId("data_organization", 191);
public static final ElementId ELEM_DEF = new ElementId("def", 192);
public static final ElementId ELEM_ENTRY = new ElementId("entry", 193);
public static final ElementId ELEM_ENUM = new ElementId("enum", 194);
public static final ElementId ELEM_FIELD = new ElementId("field", 195);
public static final ElementId ELEM_INTEGER_SIZE = new ElementId("integer_size", 196);
public static final ElementId ELEM_LONG_SIZE = new ElementId("long_size", 197);
public static final ElementId ELEM_SIZE_ALIGNMENT_MAP =
new ElementId("size_alignment_map", 198);
public static final ElementId ELEM_TYPE = new ElementId("type", 199);
public static final ElementId ELEM_TYPEGRP = new ElementId("typegrp", 200);
public static final ElementId ELEM_TYPEREF = new ElementId("typeref", 201);
public static final ElementId ELEM_ABSOLUTE_MAX_ALIGNMENT =
new ElementId("absolute_max_alignment", 37);
public static final ElementId ELEM_BITFIELD_PACKING = new ElementId("bitfield_packing", 38);
public static final ElementId ELEM_CHAR_SIZE = new ElementId("char_size", 39);
public static final ElementId ELEM_CHAR_TYPE = new ElementId("char_type", 40);
public static final ElementId ELEM_CORETYPES = new ElementId("coretypes", 41);
public static final ElementId ELEM_DATA_ORGANIZATION = new ElementId("data_organization", 42);
public static final ElementId ELEM_DEF = new ElementId("def", 43);
public static final ElementId ELEM_DEFAULT_ALIGNMENT = new ElementId("default_alignment", 44);
public static final ElementId ELEM_DEFAULT_POINTER_ALIGNMENT =
new ElementId("default_pointer_alignment", 45);
public static final ElementId ELEM_DOUBLE_SIZE = new ElementId("double_size", 46);
public static final ElementId ELEM_ENTRY = new ElementId("entry", 47);
public static final ElementId ELEM_ENUM = new ElementId("enum", 48);
public static final ElementId ELEM_FIELD = new ElementId("field", 49);
public static final ElementId ELEM_FLOAT_SIZE = new ElementId("float_size", 50);
public static final ElementId ELEM_INTEGER_SIZE = new ElementId("integer_size", 51);
public static final ElementId ELEM_LONG_DOUBLE_SIZE = new ElementId("long_double_size", 52);
public static final ElementId ELEM_LONG_LONG_SIZE = new ElementId("long_long_size", 53);
public static final ElementId ELEM_LONG_SIZE = new ElementId("long_size", 54);
public static final ElementId ELEM_MACHINE_ALIGNMENT = new ElementId("machine_alignment", 55);
public static final ElementId ELEM_POINTER_SHIFT = new ElementId("pointer_shift", 56);
public static final ElementId ELEM_POINTER_SIZE = new ElementId("pointer_size", 57);
public static final ElementId ELEM_SHORT_SIZE = new ElementId("short_size", 58);
public static final ElementId ELEM_SIZE_ALIGNMENT_MAP = new ElementId("size_alignment_map", 59);
public static final ElementId ELEM_TYPE = new ElementId("type", 60);
public static final ElementId ELEM_TYPE_ALIGNMENT_ENABLED =
new ElementId("type_alignment_enabled", 61);
public static final ElementId ELEM_TYPEGRP = new ElementId("typegrp", 62);
public static final ElementId ELEM_TYPEREF = new ElementId("typeref", 63);
public static final ElementId ELEM_USE_MS_CONVENTION = new ElementId("use_MS_convention", 64);
public static final ElementId ELEM_WCHAR_SIZE = new ElementId("wchar_size", 65);
public static final ElementId ELEM_ZERO_LENGTH_BOUNDARY =
new ElementId("zero_length_boundary", 66);
// userop
public static final ElementId ELEM_CONSTRESOLVE = new ElementId("constresolve", 202);
public static final ElementId ELEM_JUMPASSIST = new ElementId("jumpassist", 203);
public static final ElementId ELEM_SEGMENTOP = new ElementId("segmentop", 204);
// database
public static final ElementId ELEM_COLLISION = new ElementId("collision", 67);
public static final ElementId ELEM_DB = new ElementId("db", 68);
public static final ElementId ELEM_EQUATESYMBOL = new ElementId("equatesymbol", 69);
public static final ElementId ELEM_EXTERNREFSYMBOL = new ElementId("externrefsymbol", 70);
public static final ElementId ELEM_FACETSYMBOL = new ElementId("facetsymbol", 71);
public static final ElementId ELEM_FUNCTIONSHELL = new ElementId("functionshell", 72);
public static final ElementId ELEM_HASH = new ElementId("hash", 73);
public static final ElementId ELEM_HOLE = new ElementId("hole", 74);
public static final ElementId ELEM_LABELSYM = new ElementId("labelsym", 75);
public static final ElementId ELEM_MAPSYM = new ElementId("mapsym", 76);
public static final ElementId ELEM_PARENT = new ElementId("parent", 77);
public static final ElementId ELEM_PROPERTY_CHANGEPOINT =
new ElementId("property_changepoint", 78);
public static final ElementId ELEM_RANGEEQUALSSYMBOLS = new ElementId("rangeequalssymbols", 79);
public static final ElementId ELEM_SCOPE = new ElementId("scope", 80);
public static final ElementId ELEM_SYMBOLLIST = new ElementId("symbollist", 81);
// variable
public static final ElementId ELEM_HIGH = new ElementId("high", 205);
public static final ElementId ELEM_HIGH = new ElementId("high", 82);
// stringmanage
public static final ElementId ELEM_BYTES = new ElementId("bytes", 83);
public static final ElementId ELEM_STRING = new ElementId("string", 84);
public static final ElementId ELEM_STRINGMANAGE = new ElementId("stringmanage", 85);
// comment
public static final ElementId ELEM_COMMENT = new ElementId("comment", 86);
public static final ElementId ELEM_COMMENTDB = new ElementId("commentdb", 87);
public static final ElementId ELEM_TEXT = new ElementId("text", 88);
// pcodeinject
public static final ElementId ELEM_ADDR_PCODE = new ElementId("addr_pcode", 89);
public static final ElementId ELEM_BODY = new ElementId("body", 90);
public static final ElementId ELEM_CALLFIXUP = new ElementId("callfixup", 91);
public static final ElementId ELEM_CALLOTHERFIXUP = new ElementId("callotherfixup", 92);
public static final ElementId ELEM_CASE_PCODE = new ElementId("case_pcode", 93);
public static final ElementId ELEM_CONTEXT = new ElementId("context", 94);
public static final ElementId ELEM_DEFAULT_PCODE = new ElementId("default_pcode", 95);
public static final ElementId ELEM_INJECT = new ElementId("inject", 96);
public static final ElementId ELEM_INJECTDEBUG = new ElementId("injectdebug", 97);
public static final ElementId ELEM_INST = new ElementId("inst", 98);
public static final ElementId ELEM_PAYLOAD = new ElementId("payload", 99);
public static final ElementId ELEM_PCODE = new ElementId("pcode", 100);
public static final ElementId ELEM_SIZE_PCODE = new ElementId("size_pcode", 101);
// block
public static final ElementId ELEM_BHEAD = new ElementId("bhead", 102);
public static final ElementId ELEM_BLOCK = new ElementId("block", 103);
public static final ElementId ELEM_BLOCKEDGE = new ElementId("blockedge", 104);
public static final ElementId ELEM_EDGE = new ElementId("edge", 105);
// paramid
public static final ElementId ELEM_PARAMMEASURES = new ElementId("parammeasures", 106);
public static final ElementId ELEM_PROTO = new ElementId("proto", 107);
public static final ElementId ELEM_RANK = new ElementId("rank", 108);
// cpool
public static final ElementId ELEM_CONSTANTPOOL = new ElementId("constantpool", 109);
public static final ElementId ELEM_CPOOLREC = new ElementId("cpoolrec", 110);
public static final ElementId ELEM_REF = new ElementId("ref", 111);
public static final ElementId ELEM_TOKEN = new ElementId("token", 112);
// op
public static final ElementId ELEM_IOP = new ElementId("iop", 113);
public static final ElementId ELEM_UNIMPL = new ElementId("unimpl", 114);
// funcdata
public static final ElementId ELEM_AST = new ElementId("ast", 115);
public static final ElementId ELEM_FUNCTION = new ElementId("function", 116);
public static final ElementId ELEM_HIGHLIST = new ElementId("highlist", 117);
public static final ElementId ELEM_JUMPTABLELIST = new ElementId("jumptablelist", 118);
public static final ElementId ELEM_VARNODES = new ElementId("varnodes", 119);
// globalcontext
public static final ElementId ELEM_CONTEXT_DATA = new ElementId("context_data", 120);
public static final ElementId ELEM_CONTEXT_POINTS = new ElementId("context_points", 121);
public static final ElementId ELEM_CONTEXT_POINTSET = new ElementId("context_pointset", 122);
public static final ElementId ELEM_CONTEXT_SET = new ElementId("context_set", 123);
public static final ElementId ELEM_SET = new ElementId("set", 124);
public static final ElementId ELEM_TRACKED_POINTSET = new ElementId("tracked_pointset", 125);
public static final ElementId ELEM_TRACKED_SET = new ElementId("tracked_set", 126);
// userop
public static final ElementId ELEM_CONSTRESOLVE = new ElementId("constresolve", 127);
public static final ElementId ELEM_JUMPASSIST = new ElementId("jumpassist", 128);
public static final ElementId ELEM_SEGMENTOP = new ElementId("segmentop", 129);
// architecture
public static final ElementId ELEM_ADDRESS_SHIFT_AMOUNT =
new ElementId("address_shift_amount", 130);
public static final ElementId ELEM_AGGRESSIVETRIM = new ElementId("aggressivetrim", 131);
public static final ElementId ELEM_COMPILER_SPEC = new ElementId("compiler_spec", 132);
public static final ElementId ELEM_DATA_SPACE = new ElementId("data_space", 133);
public static final ElementId ELEM_DEFAULT_MEMORY_BLOCKS =
new ElementId("default_memory_blocks", 134);
public static final ElementId ELEM_DEFAULT_PROTO = new ElementId("default_proto", 135);
public static final ElementId ELEM_DEFAULT_SYMBOLS = new ElementId("default_symbols", 136);
public static final ElementId ELEM_EVAL_CALLED_PROTOTYPE =
new ElementId("eval_called_prototype", 137);
public static final ElementId ELEM_EVAL_CURRENT_PROTOTYPE =
new ElementId("eval_current_prototype", 138);
public static final ElementId ELEM_EXPERIMENTAL_RULES =
new ElementId("experimental_rules", 139);
public static final ElementId ELEM_FLOWOVERRIDELIST = new ElementId("flowoverridelist", 140);
public static final ElementId ELEM_FUNCPTR = new ElementId("funcptr", 141);
public static final ElementId ELEM_GLOBAL = new ElementId("global", 142);
public static final ElementId ELEM_INCIDENTALCOPY = new ElementId("incidentalcopy", 143);
public static final ElementId ELEM_INFERPTRBOUNDS = new ElementId("inferptrbounds", 144);
public static final ElementId ELEM_MODELALIAS = new ElementId("modelalias", 145);
public static final ElementId ELEM_NOHIGHPTR = new ElementId("nohighptr", 146);
public static final ElementId ELEM_PROCESSOR_SPEC = new ElementId("processor_spec", 147);
public static final ElementId ELEM_PROGRAMCOUNTER = new ElementId("programcounter", 148);
public static final ElementId ELEM_PROPERTIES = new ElementId("properties", 149);
public static final ElementId ELEM_PROPERTY = new ElementId("property", 150);
public static final ElementId ELEM_READONLY = new ElementId("readonly", 151);
public static final ElementId ELEM_REGISTER_DATA = new ElementId("register_data", 152);
public static final ElementId ELEM_RULE = new ElementId("rule", 153);
public static final ElementId ELEM_SAVE_STATE = new ElementId("save_state", 154);
public static final ElementId ELEM_SEGMENTED_ADDRESS = new ElementId("segmented_address", 155);
public static final ElementId ELEM_SPACEBASE = new ElementId("spacebase", 156);
public static final ElementId ELEM_SPECEXTENSIONS = new ElementId("specextensions", 157);
public static final ElementId ELEM_STACKPOINTER = new ElementId("stackpointer", 158);
public static final ElementId ELEM_VOLATILE = new ElementId("volatile", 159);
// fspec
public static final ElementId ELEM_GROUP = new ElementId("group", 160);
public static final ElementId ELEM_INTERNALLIST = new ElementId("internallist", 161);
public static final ElementId ELEM_KILLEDBYCALL = new ElementId("killedbycall", 162);
public static final ElementId ELEM_LIKELYTRASH = new ElementId("likelytrash", 163);
public static final ElementId ELEM_LOCALRANGE = new ElementId("localrange", 164);
public static final ElementId ELEM_MODEL = new ElementId("model", 165);
public static final ElementId ELEM_PARAM = new ElementId("param", 166);
public static final ElementId ELEM_PARAMRANGE = new ElementId("paramrange", 167);
public static final ElementId ELEM_PENTRY = new ElementId("pentry", 168);
public static final ElementId ELEM_PROTOTYPE = new ElementId("prototype", 169);
public static final ElementId ELEM_RESOLVEPROTOTYPE = new ElementId("resolveprototype", 170);
public static final ElementId ELEM_RETPARAM = new ElementId("retparam", 171);
public static final ElementId ELEM_RETURNSYM = new ElementId("returnsym", 172);
public static final ElementId ELEM_UNAFFECTED = new ElementId("unaffected", 173);
// options
public static final ElementId ELEM_ALIASBLOCK = new ElementId("aliasblock", 174);
public static final ElementId ELEM_ALLOWCONTEXTSET = new ElementId("allowcontextset", 175);
public static final ElementId ELEM_ANALYZEFORLOOPS = new ElementId("analyzeforloops", 176);
public static final ElementId ELEM_COMMENTHEADER = new ElementId("commentheader", 177);
public static final ElementId ELEM_COMMENTINDENT = new ElementId("commentindent", 178);
public static final ElementId ELEM_COMMENTINSTRUCTION =
new ElementId("commentinstruction", 179);
public static final ElementId ELEM_COMMENTSTYLE = new ElementId("commentstyle", 180);
public static final ElementId ELEM_CONVENTIONPRINTING =
new ElementId("conventionprinting", 181);
public static final ElementId ELEM_CURRENTACTION = new ElementId("currentaction", 182);
public static final ElementId ELEM_DEFAULTPROTOTYPE = new ElementId("defaultprototype", 183);
public static final ElementId ELEM_ERRORREINTERPRETED =
new ElementId("errorreinterpreted", 184);
public static final ElementId ELEM_ERRORTOOMANYINSTRUCTIONS =
new ElementId("errortoomanyinstructions", 185);
public static final ElementId ELEM_ERRORUNIMPLEMENTED =
new ElementId("errorunimplemented", 186);
public static final ElementId ELEM_EXTRAPOP = new ElementId("extrapop", 187);
public static final ElementId ELEM_IGNOREUNIMPLEMENTED =
new ElementId("ignoreunimplemented", 188);
public static final ElementId ELEM_INDENTINCREMENT = new ElementId("indentincrement", 189);
public static final ElementId ELEM_INFERCONSTPTR = new ElementId("inferconstptr", 190);
public static final ElementId ELEM_INLINE = new ElementId("inline", 191);
public static final ElementId ELEM_INPLACEOPS = new ElementId("inplaceops", 192);
public static final ElementId ELEM_INTEGERFORMAT = new ElementId("integerformat", 193);
public static final ElementId ELEM_JUMPLOAD = new ElementId("jumpload", 194);
public static final ElementId ELEM_MAXINSTRUCTION = new ElementId("maxinstruction", 195);
public static final ElementId ELEM_MAXLINEWIDTH = new ElementId("maxlinewidth", 196);
public static final ElementId ELEM_NAMESPACESTRATEGY = new ElementId("namespacestrategy", 197);
public static final ElementId ELEM_NOCASTPRINTING = new ElementId("nocastprinting", 198);
public static final ElementId ELEM_NORETURN = new ElementId("noreturn", 199);
public static final ElementId ELEM_NULLPRINTING = new ElementId("nullprinting", 200);
public static final ElementId ELEM_OPTIONSLIST = new ElementId("optionslist", 201);
public static final ElementId ELEM_PARAM1 = new ElementId("param1", 202);
public static final ElementId ELEM_PARAM2 = new ElementId("param2", 203);
public static final ElementId ELEM_PARAM3 = new ElementId("param3", 204);
public static final ElementId ELEM_PROTOEVAL = new ElementId("protoeval", 205);
public static final ElementId ELEM_SETACTION = new ElementId("setaction", 206);
public static final ElementId ELEM_SETLANGUAGE = new ElementId("setlanguage", 207);
public static final ElementId ELEM_STRUCTALIGN = new ElementId("structalign", 208);
public static final ElementId ELEM_TOGGLERULE = new ElementId("togglerule", 209);
public static final ElementId ELEM_WARNING = new ElementId("warning", 210);
// jumptable
public static final ElementId ELEM_BASICOVERRIDE = new ElementId("basicoverride", 211);
public static final ElementId ELEM_DEST = new ElementId("dest", 212);
public static final ElementId ELEM_JUMPTABLE = new ElementId("jumptable", 213);
public static final ElementId ELEM_LOADTABLE = new ElementId("loadtable", 214);
public static final ElementId ELEM_NORMADDR = new ElementId("normaddr", 215);
public static final ElementId ELEM_NORMHASH = new ElementId("normhash", 216);
public static final ElementId ELEM_STARTVAL = new ElementId("startval", 217);
// override
public static final ElementId ELEM_DEADCODEDELAY = new ElementId("deadcodedelay", 218);
public static final ElementId ELEM_FLOW = new ElementId("flow", 219);
public static final ElementId ELEM_FORCEGOTO = new ElementId("forcegoto", 220);
public static final ElementId ELEM_INDIRECTOVERRIDE = new ElementId("indirectoverride", 221);
public static final ElementId ELEM_MULTISTAGEJUMP = new ElementId("multistagejump", 222);
public static final ElementId ELEM_OVERRIDE = new ElementId("override", 223);
public static final ElementId ELEM_PROTOOVERRIDE = new ElementId("protooverride", 224);
// prefersplit
public static final ElementId ELEM_PREFERSPLIT = new ElementId("prefersplit", 225);
// callgraph
public static final ElementId ELEM_CALLGRAPH = new ElementId("callgraph", 226);
public static final ElementId ELEM_NODE = new ElementId("node", 227);
// varmap
public static final ElementId ELEM_LOCALDB = new ElementId("localdb", 206);
// prettyprint
public static final ElementId ELEM_BREAK = new ElementId("break", 208);
public static final ElementId ELEM_CLANG_DOCUMENT = new ElementId("clang_document", 209);
public static final ElementId ELEM_FUNCNAME = new ElementId("funcname", 210);
public static final ElementId ELEM_FUNCPROTO = new ElementId("funcproto", 211);
public static final ElementId ELEM_LABEL = new ElementId("label", 212);
public static final ElementId ELEM_RETURN_TYPE = new ElementId("return_type", 213);
public static final ElementId ELEM_STATEMENT = new ElementId("statement", 214);
public static final ElementId ELEM_SYNTAX = new ElementId("syntax", 215);
public static final ElementId ELEM_VARDECL = new ElementId("vardecl", 216);
public static final ElementId ELEM_VARIABLE = new ElementId("variable", 217);
public static final ElementId ELEM_LOCALDB = new ElementId("localdb", 228);
// ghidra_process
public static final ElementId ELEM_DOC = new ElementId("doc", 218);
public static final ElementId ELEM_DOC = new ElementId("doc", 229);
public static final ElementId ELEM_UNKNOWN = new ElementId("XMLunknown", 231);
// loadimage_xml
// public static final ElementId ELEM_BINARYIMAGE = new ElementId("binaryimage", 230);
// public static final ElementId ELEM_BYTECHUNK = new ElementId("bytechunk", 231);
// sleigh_arch
// public static final ElementId ELEM_COMPILER = new ElementId("compiler", 232);
// public static final ElementId ELEM_DESCRIPTION = new ElementId("description", 233);
// public static final ElementId ELEM_LANGUAGE = new ElementId("language", 234);
// public static final ElementId ELEM_LANGUAGE_DEFINITIONS =
// new ElementId("language_definitions", 235);
// xml_arch
// public static final ElementId ELEM_XML_SAVEFILE = new ElementId("xml_savefile", 236);
// raw_arch
// public static final ElementId ELEM_RAW_SAVEFILE = new ElementId("raw_savefile", 237);
public static final ElementId ELEM_UNKNOWN = new ElementId("XMLunknown", 251);
}

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.AddressSpace;
/**
@ -42,53 +44,66 @@ public interface Encoder {
* Begin a new element in the encoding
* The element will have the given ElementId annotation and becomes the \e current element.
* @param elemId is the given ElementId annotation
* @throws IOException for errors in the underlying stream
*/
void openElement(ElementId elemId);
void openElement(ElementId elemId) throws IOException;
/**
* End the current element in the encoding
* The current element must match the given annotation or an exception is thrown.
* @param elemId is the given (expected) annotation for the current element
* @throws IOException for errors in the underlying stream
*/
void closeElement(ElementId elemId);
void closeElement(ElementId elemId) throws IOException;
/**
* Write an annotated boolean value into the encoding
* The boolean data is associated with the given AttributeId annotation and the current open element.
* @param attribId is the given AttributeId annotation
* @param val is boolean value to encode
* @throws IOException for errors in the underlying stream
*/
void writeBool(AttributeId attribId, boolean val);
void writeBool(AttributeId attribId, boolean val) throws IOException;
/**
* Write an annotated signed integer value into the encoding
* The integer is associated with the given AttributeId annotation and the current open element.
* @param attribId is the given AttributeId annotation
* @param val is the signed integer value to encode
* @throws IOException for errors in the underlying stream
*/
void writeSignedInteger(AttributeId attribId, long val);
void writeSignedInteger(AttributeId attribId, long val) throws IOException;
/**
* Write an annotated unsigned integer value into the encoding
* The integer is associated with the given AttributeId annotation and the current open element.
* @param attribId is the given AttributeId annotation
* @param val is the unsigned integer value to encode
* @throws IOException for errors in the underlying stream
*/
void writeUnsignedInteger(AttributeId attribId, long val);
void writeUnsignedInteger(AttributeId attribId, long val) throws IOException;
/**
* Write an annotated string into the encoding
* The string is associated with the given AttributeId annotation and the current open element.
* @param attribId is the given AttributeId annotation
* @param val is the string to encode
* @throws IOException for errors in the underlying stream
*/
void writeString(AttributeId attribId, String val);
void writeString(AttributeId attribId, String val) throws IOException;
/**
* 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
* @throws IOException for errors in the underlying stream
*/
void writeSpace(AttributeId attribId, AddressSpace spc);
void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException;
/**
* Return anything written to the encoder (since the last clear) as a byte array.
* @return the array of bytes
*/
byte[] getBytes();
}

View file

@ -15,9 +15,10 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.util.xml.SpecXmlUtils;
public class EquateSymbol extends HighSymbol {
@ -104,9 +105,9 @@ public class EquateSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<equatesymbol");
saveXMLHeader(buf);
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_EQUATESYMBOL);
encodeHeader(encoder);
if (convert != 0) {
String formString = "hex";
if (convert == FORMAT_HEX) {
@ -124,13 +125,12 @@ public class EquateSymbol extends HighSymbol {
else if (convert == FORMAT_CHAR) {
formString = "char";
}
SpecXmlUtils.encodeStringAttribute(buf, "format", formString);
encoder.writeString(AttributeId.ATTRIB_FORMAT, formString);
}
buf.append(">\n");
buf.append(" <value>0x");
buf.append(Long.toHexString(value));
buf.append("</value>\n");
buf.append("</equatesymbol>\n");
encoder.openElement(ElementId.ELEM_VALUE);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_CONTENT, value);
encoder.closeElement(ElementId.ELEM_VALUE);
encoder.closeElement(ElementId.ELEM_EQUATESYMBOL);
}
/**

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.*;
@ -314,49 +316,48 @@ public class FunctionPrototype {
}
/**
* append an XML string representing this function prototype
* @param res is where the string should be appended
* Encode this function prototype to a stream.
* @param encoder is the stream encoder
* @param dtmanage is the DataTypeManager for building type reference tags
* @throws IOException for errors in the underlying stream
*/
public void buildPrototypeXML(StringBuilder res, PcodeDataTypeManager dtmanage) {
res.append("<prototype");
public void encodePrototype(Encoder encoder, PcodeDataTypeManager dtmanage) throws IOException {
encoder.openElement(ElementId.ELEM_PROTOTYPE);
if (extrapop == PrototypeModel.UNKNOWN_EXTRAPOP) {
SpecXmlUtils.encodeStringAttribute(res, "extrapop", "unknown");
encoder.writeString(AttributeId.ATTRIB_EXTRAPOP, "unknown");
}
else {
SpecXmlUtils.encodeSignedIntegerAttribute(res, "extrapop", extrapop);
encoder.writeSignedInteger(AttributeId.ATTRIB_EXTRAPOP, extrapop);
}
SpecXmlUtils.encodeStringAttribute(res, "model", modelname);
encoder.writeString(AttributeId.ATTRIB_MODEL, modelname);
if (modellock) {
SpecXmlUtils.encodeBooleanAttribute(res, "modellock", modellock);
encoder.writeBool(AttributeId.ATTRIB_MODELLOCK, modellock);
}
if (dotdotdot) {
SpecXmlUtils.encodeBooleanAttribute(res, "dotdotdot", dotdotdot);
encoder.writeBool(AttributeId.ATTRIB_DOTDOTDOT, dotdotdot);
}
if (voidinputlock) {
SpecXmlUtils.encodeBooleanAttribute(res, "voidlock", voidinputlock);
encoder.writeBool(AttributeId.ATTRIB_VOIDLOCK, voidinputlock);
}
if (isinline) {
SpecXmlUtils.encodeBooleanAttribute(res, "inline", isinline);
encoder.writeBool(AttributeId.ATTRIB_INLINE, isinline);
}
if (noreturn) {
SpecXmlUtils.encodeBooleanAttribute(res, "noreturn", noreturn);
encoder.writeBool(AttributeId.ATTRIB_NORETURN, noreturn);
}
if (custom) {
SpecXmlUtils.encodeBooleanAttribute(res, "custom", custom);
encoder.writeBool(AttributeId.ATTRIB_CUSTOM, custom);
}
if (isConstruct) {
SpecXmlUtils.encodeBooleanAttribute(res, "constructor", isConstruct);
encoder.writeBool(AttributeId.ATTRIB_CONSTRUCTOR, isConstruct);
}
if (isDestruct) {
SpecXmlUtils.encodeBooleanAttribute(res, "destructor", isDestruct);
encoder.writeBool(AttributeId.ATTRIB_DESTRUCTOR, isDestruct);
}
res.append(">\n");
res.append(" <returnsym");
encoder.openElement(ElementId.ELEM_RETURNSYM);
if (outputlock) {
SpecXmlUtils.encodeBooleanAttribute(res, "typelock", outputlock);
encoder.writeBool(AttributeId.ATTRIB_TYPELOCK, outputlock);
}
res.append(">\n ");
int sz = returntype.getLength();
if (sz < 0) {
Msg.warn(this, "Bad returntype size");
@ -368,46 +369,46 @@ public class FunctionPrototype {
if (sz != returnstorage.size()) { // If the sizes do no match
logicalsize = sz; // force the logical size on the varnode
}
AddressXML.buildXML(res, returnstorage.getVarnodes(), logicalsize);
res.append("\n ");
AddressXML.encode(encoder, returnstorage.getVarnodes(), logicalsize);
}
else {
// Decompiler will use model for storage
res.append("<addr/>\n "); // Don't specify where return type is stored
// Decompiler will use model for storage. Don't specify where return type is stored
encoder.openElement(ElementId.ELEM_ADDR);
encoder.closeElement(ElementId.ELEM_ADDR);
}
dtmanage.buildTypeRef(res, returntype, sz);
res.append(" </returnsym>\n");
dtmanage.encodeTypeRef(encoder, returntype, sz);
encoder.closeElement(ElementId.ELEM_RETURNSYM);
if (injectname != null) {
res.append("<inject>");
res.append(injectname);
res.append("</inject>\n");
encoder.openElement(ElementId.ELEM_INJECT);
encoder.writeString(AttributeId.ATTRIB_CONTENT, injectname);
encoder.closeElement(ElementId.ELEM_INJECT);
}
if (params != null) {
res.append("<internallist>\n");
encoder.openElement(ElementId.ELEM_INTERNALLIST);
for (ParameterDefinition param : params) {
res.append("<param");
encoder.openElement(ElementId.ELEM_PARAM);
String name = param.getName();
DataType dt = param.getDataType();
boolean namelock = false;
if ((name != null) && (name.length() > 0)) {
res.append(" name=\"").append(name).append('\"');
encoder.writeString(AttributeId.ATTRIB_NAME, name);
namelock = true;
}
res.append(" typelock=\"true\" namelock=\"");
res.append(namelock ? "true" : "false");
res.append("\">\n");
res.append(" <addr/>\n "); // Blank address
encoder.writeBool(AttributeId.ATTRIB_TYPELOCK, true);
encoder.writeBool(AttributeId.ATTRIB_NAMELOCK, namelock);
encoder.openElement(ElementId.ELEM_ADDR);
encoder.closeElement(ElementId.ELEM_ADDR); // Blank address
sz = dt.getLength();
if (sz < 0) {
sz = 1;
}
dtmanage.buildTypeRef(res, dt, sz);
res.append("</param>\n");
dtmanage.encodeTypeRef(encoder, dt, sz);
encoder.closeElement(ElementId.ELEM_PARAM);
}
res.append("</internallist>\n");
encoder.closeElement(ElementId.ELEM_INTERNALLIST);
}
res.append("</prototype>\n");
encoder.closeElement(ElementId.ELEM_PROTOTYPE);
}
/**

View file

@ -15,11 +15,12 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.VariableStorage;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
/**
* A symbol, within a decompiler model, for a function without a body in the current Program.
@ -55,13 +56,12 @@ public class HighExternalSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<externrefsymbol");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_EXTERNREFSYMBOL);
if ((name != null) && (name.length() > 0)) { // Give the symbol a name if we can
SpecXmlUtils.xmlEscapeAttribute(buf, "name", name + "_exref");
encoder.writeString(AttributeId.ATTRIB_NAME, name + "_exref");
}
buf.append(">\n");
AddressXML.buildXML(buf, resolveAddress);
buf.append("</externrefsymbol>\n");
AddressXML.encode(encoder, resolveAddress);
encoder.closeElement(ElementId.ELEM_EXTERNREFSYMBOL);
}
}

View file

@ -15,19 +15,19 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ghidra.program.database.function.FunctionDB;
import ghidra.program.database.symbol.CodeSymbol;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.lang.*;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.lang.Language;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
/**
*
@ -58,7 +58,8 @@ public class HighFunction extends PcodeSyntaxTree {
func = function;
this.language = language;
this.compilerSpec = compilerSpec;
localSymbols = new LocalSymbolMap(this, SpaceNames.STACK_SPACE_NAME);
AddressSpace stackSpace = function.getProgram().getAddressFactory().getStackSpace();
localSymbols = new LocalSymbolMap(this, stackSpace);
globalSymbols = new GlobalSymbolMap(this);
proto = new FunctionPrototype(localSymbols, function);
jumpTables = null;
@ -423,70 +424,63 @@ public class HighFunction extends PcodeSyntaxTree {
}
/**
* Build an XML string that represents all the information about this HighFunction. The
* size describes how many bytes starting from the entry point are used by the function, but
* this doesn't need to be strictly accurate as it is only used to associate the function with
* addresses near its entry point.
*
* Encode this HighFunction to a stream. The size describes how many bytes starting from the
* entry point are used by the function, but this doesn't need to be strictly accurate as it
* is only used to associate the function with addresses near its entry point.
* @param encoder is the stream encoder
* @param id is the id associated with the function symbol
* @param namespace is the namespace containing the function symbol
* @param entryPoint pass null to use the function entryPoint, pass an address to force an entry point
* @param size describes how many bytes the function occupies as code
* @return the XML string
* @throws IOException for errors in the underlying stream
*/
public String buildFunctionXML(long id, Namespace namespace, Address entryPoint, int size) {
public void encode(Encoder encoder, long id, Namespace namespace, Address entryPoint, int size)
throws IOException {
// Functions aren't necessarily contiguous with the smallest address being the entry point
// So size needs to be smaller than size of the contiguous chunk containing the entry point
StringBuilder resBuf = new StringBuilder();
resBuf.append("<function");
encoder.openElement(ElementId.ELEM_FUNCTION);
if (id != 0) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", id);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, id);
}
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", func.getName());
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
encoder.writeString(AttributeId.ATTRIB_NAME, func.getName());
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, size);
if (func.isInline()) {
SpecXmlUtils.encodeBooleanAttribute(resBuf, "inline", true);
encoder.writeBool(AttributeId.ATTRIB_INLINE, true);
}
if (func.hasNoReturn()) {
SpecXmlUtils.encodeBooleanAttribute(resBuf, "noreturn", true);
encoder.writeBool(AttributeId.ATTRIB_NORETURN, true);
}
resBuf.append(">\n");
if (entryPoint == null) {
AddressXML.buildXML(resBuf, func.getEntryPoint());
AddressXML.encode(encoder, func.getEntryPoint());
}
else {
AddressXML.buildXML(resBuf, entryPoint); // Address is forced on XML
AddressXML.encode(encoder, entryPoint); // Address is forced on XML
}
localSymbols.buildLocalDbXML(resBuf, namespace);
proto.buildPrototypeXML(resBuf, getDataTypeManager());
localSymbols.encodeLocalDb(encoder, namespace);
proto.encodePrototype(encoder, getDataTypeManager());
if ((jumpTables != null) && (jumpTables.size() > 0)) {
resBuf.append("<jumptablelist>\n");
encoder.openElement(ElementId.ELEM_JUMPTABLELIST);
for (JumpTable jumpTable : jumpTables) {
jumpTable.buildXml(resBuf);
jumpTable.encode(encoder);
}
resBuf.append("</jumptablelist>\n");
encoder.closeElement(ElementId.ELEM_JUMPTABLELIST);
}
boolean hasOverrideTag = ((protoOverrides != null) && (protoOverrides.size() > 0));
if (hasOverrideTag) {
resBuf.append("<override>\n");
}
if ((protoOverrides != null) && (protoOverrides.size() > 0)) {
encoder.openElement(ElementId.ELEM_OVERRIDE);
PcodeDataTypeManager dtmanage = getDataTypeManager();
for (DataTypeSymbol sym : protoOverrides) {
Address addr = sym.getAddress();
FunctionPrototype fproto = new FunctionPrototype(
(FunctionSignature) sym.getDataType(), compilerSpec, false);
resBuf.append("<protooverride>\n");
AddressXML.buildXML(resBuf, addr);
fproto.buildPrototypeXML(resBuf, dtmanage);
resBuf.append("</protooverride>\n");
encoder.openElement(ElementId.ELEM_PROTOOVERRIDE);
AddressXML.encode(encoder, addr);
fproto.encodePrototype(encoder, dtmanage);
encoder.closeElement(ElementId.ELEM_PROTOOVERRIDE);
}
encoder.closeElement(ElementId.ELEM_OVERRIDE);
}
if (hasOverrideTag) {
resBuf.append("</override>\n");
}
resBuf.append("</function>\n");
return resBuf.toString();
encoder.closeElement(ElementId.ELEM_FUNCTION);
}
public static Namespace findOverrideSpace(Function func) {
@ -580,13 +574,14 @@ public class HighFunction extends PcodeSyntaxTree {
}
/**
* Append an XML &lt;parent&gt; tag to the buffer describing the formal path elements
* Encode &lt;parent&gt; element to the stream describing the formal path elements
* from the root (global) namespace up to the given namespace
* @param buf is the buffer to write to
* @param encoder is the stream encoder
* @param namespace is the namespace being described
* @throws IOException for errors in the underlying stream
*/
static public void createNamespaceTag(StringBuilder buf, Namespace namespace) {
buf.append("<parent>\n");
static public void encodeNamespace(Encoder encoder, Namespace namespace) throws IOException {
encoder.openElement(ElementId.ELEM_PARENT);
if (namespace != null) {
ArrayList<Namespace> arr = new ArrayList<>();
Namespace curspc = namespace;
@ -597,17 +592,17 @@ public class HighFunction extends PcodeSyntaxTree {
}
curspc = curspc.getParentNamespace();
}
buf.append("<val/>\n"); // Force global scope to have empty name
encoder.openElement(ElementId.ELEM_VAL); // Force global scope to have empty name
encoder.closeElement(ElementId.ELEM_VAL);
for (int i = 1; i < arr.size(); ++i) {
Namespace curScope = arr.get(i);
buf.append("<val");
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "id", curScope.getID());
buf.append('>');
SpecXmlUtils.xmlEscape(buf, curScope.getName());
buf.append("</val>\n");
encoder.openElement(ElementId.ELEM_VAL);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, curScope.getID());
encoder.writeString(AttributeId.ATTRIB_CONTENT, curScope.getName());
encoder.closeElement(ElementId.ELEM_VAL);
}
}
buf.append("</parent>\n");
encoder.closeElement(ElementId.ELEM_PARENT);
}
/**

View file

@ -15,11 +15,12 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.VariableStorage;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
/**
* A function symbol that represents only a shell of (the name and address) the function,
@ -53,13 +54,12 @@ public class HighFunctionShellSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<function");
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "id", getId());
SpecXmlUtils.xmlEscapeAttribute(buf, "name", name);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "size", 1);
buf.append(">\n");
AddressXML.buildXML(buf, getStorage().getMinAddress());
buf.append("</function>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_FUNCTION);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, getId());
encoder.writeString(AttributeId.ATTRIB_NAME, name);
encoder.writeSignedInteger(AttributeId.ATTRIB_SIZE, 1);
AddressXML.encode(encoder, getStorage().getMinAddress());
encoder.closeElement(ElementId.ELEM_FUNCTION);
}
}

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Function;
@ -70,11 +72,9 @@ public class HighFunctionSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
public void encode(Encoder encoder) throws IOException {
MappedEntry entry = (MappedEntry) getFirstWholeMap();
String funcString =
function.buildFunctionXML(getId(), getNamespace(), entry.getStorage().getMinAddress(),
function.encode(encoder, getId(), getNamespace(), entry.getStorage().getMinAddress(),
entry.getSize());
buf.append(funcString);
}
}

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.VariableStorage;
@ -46,9 +48,9 @@ public class HighLabelSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<labelsym");
saveXMLHeader(buf);
buf.append("/>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_LABELSYM);
encodeHeader(encoder);
encoder.closeElement(ElementId.ELEM_LABELSYM);
}
}

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.DynamicVariableStorage;
@ -22,7 +24,6 @@ import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.xml.SpecXmlUtils;
/**
* A symbol within the decompiler's model of a particular function. The symbol has a name and a data-type
@ -361,46 +362,47 @@ public class HighSymbol {
}
/**
* Write out attributes for the base XML tag
* @param buf is the XML output stream
* Encode attributes for the base symbol element
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
protected void saveXMLHeader(StringBuilder buf) {
protected void encodeHeader(Encoder encoder) throws IOException {
if ((id >> 56) != (ID_BASE >> 56)) { // Don't send down internal ids
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "id", id);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, id);
}
SpecXmlUtils.xmlEscapeAttribute(buf, "name", name);
SpecXmlUtils.encodeBooleanAttribute(buf, "typelock", typelock);
SpecXmlUtils.encodeBooleanAttribute(buf, "namelock", namelock);
SpecXmlUtils.encodeBooleanAttribute(buf, "readonly", isReadOnly());
encoder.writeString(AttributeId.ATTRIB_NAME, name);
encoder.writeBool(AttributeId.ATTRIB_TYPELOCK, typelock);
encoder.writeBool(AttributeId.ATTRIB_NAMELOCK, namelock);
encoder.writeBool(AttributeId.ATTRIB_READONLY, isReadOnly());
boolean isVolatile = entryList[0].isVolatile();
if (isVolatile) {
SpecXmlUtils.encodeBooleanAttribute(buf, "volatile", true);
encoder.writeBool(AttributeId.ATTRIB_VOLATILE, true);
}
if (isIsolated()) {
SpecXmlUtils.encodeBooleanAttribute(buf, "merge", false);
encoder.writeBool(AttributeId.ATTRIB_MERGE, false);
}
if (isThis) {
SpecXmlUtils.encodeBooleanAttribute(buf, "thisptr", true);
encoder.writeBool(AttributeId.ATTRIB_THISPTR, true);
}
if (isHidden) {
SpecXmlUtils.encodeBooleanAttribute(buf, "hiddenretparm", true);
encoder.writeBool(AttributeId.ATTRIB_HIDDENRETPARM, true);
}
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "cat", category);
encoder.writeSignedInteger(AttributeId.ATTRIB_CAT, category);
if (categoryIndex >= 0) {
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "index", categoryIndex);
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, categoryIndex);
}
}
/**
* Save the symbol description as a tag to the XML stream. This does NOT save the mappings.
* @param buf is the XML stream
* Encode the symbol description as an element to the stream. This does NOT save the mappings.
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
public void saveXML(StringBuilder buf) {
buf.append("<symbol");
saveXMLHeader(buf);
buf.append(">\n");
dtmanage.buildTypeRef(buf, type, getSize());
buf.append("</symbol>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_SYMBOL);
encodeHeader(encoder);
dtmanage.encodeTypeRef(encoder, type, getSize());
encoder.closeElement(ElementId.ELEM_SYMBOL);
}
protected void decodeHeader(Decoder decoder) throws PcodeXMLException {
@ -544,16 +546,17 @@ public class HighSymbol {
}
/**
* Write out the given symbol with all its mapping as a &lt;mapsym&gt; tag to the given XML stream.
* @param res is the given XML stream
* Encode the given symbol with all its mapping as a &lt;mapsym&gt; element to the stream.
* @param encoder is the stream encoder
* @param sym is the given symbol
* @throws IOException for errors in the underlying stream
*/
public static void buildMapSymXML(StringBuilder res, HighSymbol sym) {
res.append("<mapsym>\n");
sym.saveXML(res);
public static void encodeMapSym(Encoder encoder, HighSymbol sym) throws IOException {
encoder.openElement(ElementId.ELEM_MAPSYM);
sym.encode(encoder);
for (SymbolEntry entry : sym.entryList) {
entry.saveXml(res);
entry.encode(encoder);
}
res.append("</mapsym>\n");
encoder.closeElement(ElementId.ELEM_MAPSYM);
}
}

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.program.database.symbol.CodeSymbol;
@ -96,16 +97,16 @@ public class JumpTable {
return destlist;
}
public void buildXml(StringBuilder buf) {
buf.append("<basicoverride>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_BASICOVERRIDE);
for (Address element : destlist) {
buf.append("<dest");
AddressXML.appendAttributes(buf, element);
buf.append("/>\n");
encoder.openElement(ElementId.ELEM_DEST);
AddressXML.encodeAttributes(encoder, element);
encoder.closeElement(ElementId.ELEM_DEST);
}
// We could add <normaddr> and <normhash> tags to specify switch variable
// We could add <normaddr> and <normhash> elements to specify switch variable
// We could add a <startval> tag to indicate starting value of the switch variable
buf.append("</basicoverride>\n");
encoder.closeElement(ElementId.ELEM_BASICOVERRIDE);
}
}
@ -177,7 +178,8 @@ public class JumpTable {
}
if (subel == ElementId.ELEM_DEST.getId()) {
decoder.openElement();
Address caseAddr = translateOverlayAddress(AddressXML.decodeFromAttributes(decoder));
Address caseAddr =
translateOverlayAddress(AddressXML.decodeFromAttributes(decoder));
aTable.add(caseAddr);
decoder.rewindAttributes();
for (;;) {
@ -212,21 +214,20 @@ public class JumpTable {
decoder.closeElement(el);
}
public void buildXml(StringBuilder buf) {
buf.append("<jumptable>\n");
AddressXML.buildXML(buf, opAddress);
buf.append('\n');
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_JUMPTABLE);
AddressXML.encode(encoder, opAddress);
if (addressTable != null) {
for (Address element : addressTable) {
buf.append("<dest");
AddressXML.appendAttributes(buf, element);
buf.append("/>\n");
encoder.openElement(ElementId.ELEM_DEST);
AddressXML.encodeAttributes(encoder, element);
encoder.closeElement(ElementId.ELEM_DEST);
}
}
if (override != null) {
override.buildXml(buf);
override.encode(encoder);
}
buf.append("</jumptable>\n");
encoder.closeElement(ElementId.ELEM_JUMPTABLE);
}
public Address getSwitchAddress() {

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.*;
import ghidra.program.model.address.*;
@ -23,7 +24,6 @@ import ghidra.program.model.data.Undefined;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.util.SystemUtilities;
import ghidra.util.xml.SpecXmlUtils;
/**
* A container for local symbols within the decompiler's model of a function. It contains HighSymbol
@ -35,7 +35,7 @@ import ghidra.util.xml.SpecXmlUtils;
*/
public class LocalSymbolMap {
private HighFunction func; // Function to which these variables are local
private String spacename;
private AddressSpace localSpace; // The address space (usually stack) associated with map
private HashMap<MappedVarKey, HighSymbol> addrMappedSymbols; // Hashed by addr and pcaddr
private HashMap<Long, HighSymbol> symbolMap; // Hashed by unique key
private HighSymbol[] paramSymbols;
@ -43,11 +43,11 @@ public class LocalSymbolMap {
/**
* @param highFunc HighFunction the local variables are defined within.
* @param spcname space name the local variables are defined within.
* @param spc the address space the local variables are defined within.
*/
public LocalSymbolMap(HighFunction highFunc, String spcname) {
public LocalSymbolMap(HighFunction highFunc, AddressSpace spc) {
func = highFunc;
spacename = spcname;
localSpace = spc;
addrMappedSymbols = new HashMap<>();
symbolMap = new HashMap<>();
paramSymbols = new HighSymbol[0];
@ -278,7 +278,7 @@ public class LocalSymbolMap {
*/
public void decodeScope(Decoder decoder) throws PcodeXMLException {
int el = decoder.openElement(ElementId.ELEM_LOCALDB);
spacename = decoder.readString(AttributeId.ATTRIB_MAIN);
localSpace = decoder.readSpace(AttributeId.ATTRIB_MAIN);
int scopeel = decoder.openElement(ElementId.ELEM_SCOPE);
decoder.skipElement(); // This is the parent scope path
@ -323,35 +323,35 @@ public class LocalSymbolMap {
}
/**
* Output an XML document representing this local variable map.
* @param resBuf is the buffer to write to
* Encode all the variables in this local variable map to the stream
* @param encoder is the stream encoder
* @param namespace if the namespace of the function
* @throws IOException for errors in the underlying stream
*/
public void buildLocalDbXML(StringBuilder resBuf, Namespace namespace) { // Get memory mapped local variables
resBuf.append("<localdb");
SpecXmlUtils.encodeBooleanAttribute(resBuf, "lock", false);
SpecXmlUtils.encodeStringAttribute(resBuf, "main", spacename);
resBuf.append(">\n");
resBuf.append("<scope");
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", func.getFunction().getName());
resBuf.append(">\n");
resBuf.append("<parent");
public void encodeLocalDb(Encoder encoder, Namespace namespace) throws IOException {
encoder.openElement(ElementId.ELEM_LOCALDB);
encoder.writeBool(AttributeId.ATTRIB_LOCK, false);
encoder.writeSpace(AttributeId.ATTRIB_MAIN, localSpace);
encoder.openElement(ElementId.ELEM_SCOPE);
encoder.writeString(AttributeId.ATTRIB_NAME, func.getFunction().getName());
encoder.openElement(ElementId.ELEM_PARENT);
long parentid = Namespace.GLOBAL_NAMESPACE_ID;
if (!HighFunction.collapseToGlobal(namespace)) {
parentid = namespace.getID();
}
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", parentid);
resBuf.append("/>\n");
resBuf.append("<rangelist/>\n"); // Empty address range
resBuf.append("<symbollist>\n");
encoder.writeUnsignedInteger(AttributeId.ATTRIB_ID, parentid);
encoder.closeElement(ElementId.ELEM_PARENT);
encoder.openElement(ElementId.ELEM_RANGELIST); // Emptry address range
encoder.closeElement(ElementId.ELEM_RANGELIST);
encoder.openElement(ElementId.ELEM_SYMBOLLIST);
Iterator<HighSymbol> iter = symbolMap.values().iterator();
while (iter.hasNext()) {
HighSymbol sym = iter.next();
HighSymbol.buildMapSymXML(resBuf, sym);
HighSymbol.encodeMapSym(encoder, sym);
}
resBuf.append("</symbollist>\n");
resBuf.append("</scope>\n");
resBuf.append("</localdb>\n");
encoder.closeElement(ElementId.ELEM_SYMBOLLIST);
encoder.closeElement(ElementId.ELEM_SCOPE);
encoder.closeElement(ElementId.ELEM_LOCALDB);
}
/**

View file

@ -15,6 +15,8 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.AbstractFloatDataType;
@ -82,14 +84,14 @@ public class MappedEntry extends SymbolEntry {
}
@Override
public void saveXml(StringBuilder buf) {
public void encode(Encoder encoder) throws IOException {
int logicalsize = 0; // Assume datatype size and storage size are the same
int typeLength = symbol.type.getLength();
if (typeLength != storage.size() && symbol.type instanceof AbstractFloatDataType) {
logicalsize = typeLength; // Force a logicalsize
}
AddressXML.buildXML(buf, storage.getVarnodes(), logicalsize);
buildRangelistXML(buf);
AddressXML.encode(encoder, storage.getVarnodes(), logicalsize);
encodeRangelist(encoder);
}
@Override

View file

@ -16,11 +16,9 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import ghidra.program.model.address.Address;
import ghidra.util.xml.SpecXmlUtils;
/**
*
@ -146,15 +144,19 @@ public class PcodeBlock {
}
/**
* Save edge as XML assuming we already know what block we are in
* @param buffer to write tag to
* Encode edge to stream assuming we already know what block we are in
* @param encoder is the stream encoder
* @throws IOException for errors writing to underlying stream
*/
public void saveXml(StringBuilder buffer) {
buffer.append("<edge");
// We are not saving label currently
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "end", point.getIndex()); // Reference to other end of edge
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "rev", reverse_index); // Position within other blocks edgelist
buffer.append("/>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_EDGE);
// We are not encoding label currently
// Reference to other end of edge
encoder.writeSignedInteger(AttributeId.ATTRIB_END, point.getIndex());
// Position within other blocks edgelist
encoder.writeSignedInteger(AttributeId.ATTRIB_REV, reverse_index);
encoder.closeElement(ElementId.ELEM_EDGE);
}
/**
@ -344,30 +346,38 @@ public class PcodeBlock {
return bl;
}
public void saveXmlHeader(StringBuilder buffer) {
SpecXmlUtils.encodeSignedIntegerAttribute(buffer, "index", index);
/**
* Encode basic attributes to stream. Assume this block's element is already started.
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
protected void encodeHeader(Encoder encoder) throws IOException {
encoder.writeSignedInteger(AttributeId.ATTRIB_INDEX, index);
}
public void decodeHeader(Decoder decoder) throws PcodeXMLException {
protected void decodeHeader(Decoder decoder) throws PcodeXMLException {
index = (int) decoder.readSignedInteger(AttributeId.ATTRIB_INDEX);
}
/**
* Serialize information about the block to XML,
* Encode information about the block to stream,
* other than header and edge info
* @param writer is where to serialize to
* @throws IOException if there is a problem with the stream
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void saveXmlBody(Writer writer) throws IOException {
protected void encodeBody(Encoder encoder) throws IOException {
// No body by default
}
public void saveXmlEdges(Writer writer) throws IOException {
StringBuilder buf = new StringBuilder();
/**
* Encode information about this blocks edges to stream
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
protected void encodeEdges(Encoder encoder) throws IOException {
for (BlockEdge element : intothis) {
element.saveXml(buf);
element.encode(encoder);
}
writer.write(buf.toString());
}
/**
@ -376,11 +386,11 @@ public class PcodeBlock {
* @param resolver is for looking up edge references
* @throws PcodeXMLException for invalid encoding
*/
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
// No body to restore by default
}
public void decodeEdges(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeEdges(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
for (;;) {
int el = decoder.peekElement();
if (el != ElementId.ELEM_EDGE.getId()) {
@ -390,17 +400,25 @@ public class PcodeBlock {
}
}
public void saveXml(Writer writer) throws IOException {
StringBuilder buf = new StringBuilder();
buf.append("<block");
saveXmlHeader(buf);
buf.append(">\n");
writer.write(buf.toString());
saveXmlBody(writer);
saveXmlEdges(writer);
writer.write("</block>\n");
/**
* Encode this block to a stream
* @param encoder is the stream encoder
* @throws IOException for errors writing to the underlying stream
*/
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_BLOCK);
encodeHeader(encoder);
encodeBody(encoder);
encodeEdges(encoder);
encoder.closeElement(ElementId.ELEM_BLOCK);
}
/**
* Decode this block from a stream
* @param decoder is the stream decoder
* @param resolver is the map from reference to block object
* @throws PcodeXMLException for errors in the encoding
*/
public void decode(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
int el = decoder.openElement(ElementId.ELEM_BLOCK);
decodeHeader(decoder);

View file

@ -16,11 +16,9 @@
package ghidra.program.model.pcode;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import ghidra.program.model.address.*;
import ghidra.util.xml.SpecXmlUtils;
/**
*
@ -110,25 +108,23 @@ public class PcodeBlockBasic extends PcodeBlock {
}
@Override
public void saveXmlBody(Writer writer) throws IOException {
writer.append("<rangelist>\n");
protected void encodeBody(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_RANGELIST);
AddressRangeIterator iter = cover.getAddressRanges(true);
while (iter.hasNext()) {
AddressRange range = iter.next();
StringBuilder buffer = new StringBuilder();
buffer.append("<range");
SpecXmlUtils.encodeStringAttribute(buffer, "space", range.getAddressSpace().getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "first",
encoder.openElement(ElementId.ELEM_RANGE);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, range.getAddressSpace());
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST,
range.getMinAddress().getOffset());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buffer, "last",
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST,
range.getMaxAddress().getOffset());
writer.append(buffer);
}
writer.append("</rangelist>\n");
encoder.closeElement(ElementId.ELEM_RANGELIST);
}
@Override
public void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
protected void decodeBody(Decoder decoder, BlockMap resolver) throws PcodeXMLException {
int rangelistel = decoder.openElement(ElementId.ELEM_RANGELIST);
for (;;) {
int rangeel = decoder.peekElement();

View file

@ -15,11 +15,11 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.*;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.UnknownInstructionException;
import ghidra.util.xml.SpecXmlUtils;
/**
*
@ -416,31 +416,37 @@ public class PcodeOp {
output = vn;
}
public void buildXML(StringBuilder resBuf, AddressFactory addrFactory) {
resBuf.append("<op");
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "code", opcode);
resBuf.append('>');
resBuf.append(seqnum.buildXML());
/**
* Encode this PcodeOp to a stream as an \<op> element
* @param encoder is the stream encoder
* @param addrFactory is a factory for looking up encoded address spaces
* @throws IOException for errors in the underlying stream
*/
public void encode(Encoder encoder, AddressFactory addrFactory) throws IOException {
encoder.openElement(ElementId.ELEM_OP);
encoder.writeSignedInteger(AttributeId.ATTRIB_CODE, opcode);
seqnum.encode(encoder);
if (output == null) {
resBuf.append("<void/>");
encoder.openElement(ElementId.ELEM_VOID);
encoder.closeElement(ElementId.ELEM_VOID);
}
else {
output.buildXML(resBuf);
output.encode(encoder);
}
if ((opcode == PcodeOp.LOAD) || (opcode == PcodeOp.STORE)) {
int spaceId = (int) input[0].getOffset();
resBuf.append("<spaceid");
encoder.openElement(ElementId.ELEM_SPACEID);
AddressSpace space = addrFactory.getAddressSpace(spaceId);
SpecXmlUtils.encodeStringAttribute(resBuf, "name", space.getName());
resBuf.append("/>");
encoder.writeSpace(AttributeId.ATTRIB_NAME, space);
encoder.closeElement(ElementId.ELEM_SPACEID);
}
else if (input.length > 0) {
input[0].buildXML(resBuf);
input[0].encode(encoder);
}
for (int i = 1; i < input.length; ++i) {
input[i].buildXML(resBuf);
input[i].encode(encoder);
}
resBuf.append("</op>");
encoder.closeElement(ElementId.ELEM_OP);
}
/**

View file

@ -15,9 +15,10 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.util.xml.SpecXmlUtils;
/**
*
@ -125,19 +126,19 @@ public class SequenceNumber implements Comparable<SequenceNumber> {
}
/**
* @return Build XML tag for SequenceNumber
* Encode this sequence number to the stream
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
public StringBuilder buildXML() {
StringBuilder resBuf = new StringBuilder();
resBuf.append("<seqnum");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_SEQNUM);
AddressSpace space = pc.getAddressSpace();
SpecXmlUtils.encodeStringAttribute(resBuf, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "offset", pc.getOffset());
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_OFFSET, pc.getOffset());
if (uniq != -1) {
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "uniq", uniq);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_UNIQ, uniq);
}
resBuf.append("/>");
return resBuf;
encoder.closeElement(ElementId.ELEM_SEQNUM);
}
/**

View file

@ -15,10 +15,11 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.VariableStorage;
import ghidra.util.xml.SpecXmlUtils;
/**
* A mapping from a HighSymbol object to the storage that holds the symbol's value.
@ -44,10 +45,11 @@ public abstract class SymbolEntry {
public abstract void decode(Decoder decoder) throws PcodeXMLException;
/**
* Save this entry as (a set of) XML tags to the given stream
* @param buf is the given stream
* Encode this entry as (a set of) elements to the given stream
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
public abstract void saveXml(StringBuilder buf);
public abstract void encode(Encoder encoder) throws IOException;
/**
* Get the storage associated with this particular mapping of the Symbol
@ -98,12 +100,12 @@ public abstract class SymbolEntry {
decoder.closeElement(rangelistel);
}
protected void buildRangelistXML(StringBuilder res) {
protected void encodeRangelist(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_RANGELIST);
if (pcaddr == null || pcaddr.isExternalAddress()) {
res.append("<rangelist/>");
encoder.closeElement(ElementId.ELEM_RANGELIST);
return;
}
res.append("<rangelist>");
AddressSpace space = pcaddr.getAddressSpace();
long off;
if (space.isOverlaySpace()) {
@ -113,11 +115,11 @@ public abstract class SymbolEntry {
else {
off = pcaddr.getUnsignedOffset();
}
res.append("<range");
SpecXmlUtils.encodeStringAttribute(res, "space", space.getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(res, "first", off);
SpecXmlUtils.encodeUnsignedIntegerAttribute(res, "last", off);
res.append("/>");
res.append("</rangelist>\n");
encoder.openElement(ElementId.ELEM_RANGE);
encoder.writeSpace(AttributeId.ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_FIRST, off);
encoder.writeUnsignedInteger(AttributeId.ATTRIB_LAST, off);
encoder.closeElement(ElementId.ELEM_RANGE);
encoder.closeElement(ElementId.ELEM_RANGELIST);
}
}

View file

@ -15,9 +15,10 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.util.xml.SpecXmlUtils;
/**
* A specialized HighSymbol that directs the decompiler to use a specific field of a union,
@ -39,13 +40,12 @@ public class UnionFacetSymbol extends HighSymbol {
}
@Override
public void saveXML(StringBuilder buf) {
buf.append("<facetsymbol");
saveXMLHeader(buf);
SpecXmlUtils.encodeSignedIntegerAttribute(buf, "field", fieldNumber);
buf.append(">\n");
dtmanage.buildTypeRef(buf, type, getSize());
buf.append("</facetsymbol>\n");
public void encode(Encoder encoder) throws IOException {
encoder.openElement(ElementId.ELEM_FACETSYMBOL);
encodeHeader(encoder);
encoder.writeSignedInteger(AttributeId.ATTRIB_FIELD, fieldNumber);
dtmanage.encodeTypeRef(encoder, type, getSize());
encoder.closeElement(ElementId.ELEM_FACETSYMBOL);
}
/**

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import java.util.Iterator;
import ghidra.program.model.address.*;
@ -312,10 +313,11 @@ public class Varnode {
}
/**
* @param buf is the builder to which to append XML
* @param encoder is the stream encoder
* @throws IOException for errors in the underlying stream
*/
public void buildXML(StringBuilder buf) {
AddressXML.buildXML(buf, address, size);
public void encode(Encoder encoder) throws IOException {
AddressXML.encode(encoder, address, size);
}
/**
@ -348,7 +350,7 @@ public class Varnode {
}
else if (attribId == AttributeId.ATTRIB_REF.getId()) { // If we have a reference
ref = (int) decoder.readUnsignedInteger();
Varnode vn = factory.getRef(ref); // The varnode may already exit
Varnode vn = factory.getRef(ref); // The varnode may already exist
if (vn != null) {
decoder.closeElement(el);
return vn;

View file

@ -119,6 +119,8 @@ public class XmlDecode implements Decoder {
throw new PcodeXMLException("Expecting end, but got start <" + el.getName() + '>');
}
currentEl = null;
// Only one possible element can be closed as enforced by SAXParser
// so additional checks are somewhat redundant
// int elemId = ElementId.find(el.getName());
// if (elemId != id) {
// throw new PcodeXMLException("Unexpected end, <" + el.getName() + '>');

View file

@ -0,0 +1,172 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.AddressSpace;
import ghidra.util.xml.SpecXmlUtils;
/**
* An XML based encoder
* The underlying transfer encoding is an XML document.
* The encoder is initialized with a StringBuilder which will receive the XML document as calls
* are made on the encoder.
*/
public class XmlEncode implements Encoder {
private StringBuilder buffer;
private boolean elementTagIsOpen;
public XmlEncode() {
buffer = new StringBuilder();
elementTagIsOpen = false;
}
@Override
public String toString() {
return buffer.toString();
}
@Override
public void clear() {
buffer = new StringBuilder();
elementTagIsOpen = false;
}
@Override
public void openElement(ElementId elemId) throws IOException {
if (elementTagIsOpen) {
buffer.append('>');
}
else {
elementTagIsOpen = true;
}
buffer.append('<');
buffer.append(elemId.getName());
}
@Override
public void closeElement(ElementId elemId) throws IOException {
if (elementTagIsOpen) {
buffer.append("/>");
elementTagIsOpen = false;
}
else {
buffer.append("</");
buffer.append(elemId.getName());
buffer.append('>');
}
}
@Override
public void writeBool(AttributeId attribId, boolean val) throws IOException {
if (attribId == AttributeId.ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
buffer.append('>');
elementTagIsOpen = false;
}
buffer.append(val ? "true" : "false");
return;
}
buffer.append(' ');
buffer.append(attribId.getName());
buffer.append("=\"");
buffer.append(val ? "true" : "false");
buffer.append("\"");
}
@Override
public void writeSignedInteger(AttributeId attribId, long val) throws IOException {
if (attribId == AttributeId.ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
buffer.append('>');
elementTagIsOpen = false;
}
buffer.append(Long.toString(val, 10));
return;
}
buffer.append(' ');
buffer.append(attribId.getName());
buffer.append("=\"");
buffer.append(Long.toString(val, 10));
buffer.append("\"");
}
@Override
public void writeUnsignedInteger(AttributeId attribId, long val) throws IOException {
if (attribId == AttributeId.ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
buffer.append('>');
elementTagIsOpen = false;
}
buffer.append("0x");
buffer.append(Long.toHexString(val));
return;
}
buffer.append(' ');
buffer.append(attribId.getName());
buffer.append("=\"0x");
buffer.append(Long.toHexString(val));
buffer.append("\"");
}
@Override
public void writeString(AttributeId attribId, String val) throws IOException {
if (attribId == AttributeId.ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
buffer.append('>');
elementTagIsOpen = false;
}
SpecXmlUtils.xmlEscape(buffer, val);
return;
}
buffer.append(' ');
buffer.append(attribId.getName());
buffer.append("=\"");
SpecXmlUtils.xmlEscape(buffer, val);
buffer.append("\"");
}
@Override
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
String spcName;
if (spc.getType() == AddressSpace.TYPE_VARIABLE) {
spcName = "join";
}
else {
spcName = spc.getName();
}
if (attribId == AttributeId.ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
buffer.append('>');
elementTagIsOpen = false;
}
SpecXmlUtils.xmlEscape(buffer, spcName);
return;
}
buffer.append(' ');
buffer.append(attribId.getName());
buffer.append("=\"");
SpecXmlUtils.xmlEscape(buffer, spcName);
buffer.append("\"");
}
@Override
public byte[] getBytes() {
return buffer.toString().getBytes();
}
}

View file

@ -15,6 +15,7 @@
*/
package ghidra.program.util;
import java.io.IOException;
import java.util.*;
import ghidra.program.model.address.*;
@ -22,6 +23,7 @@ import ghidra.program.model.data.DataOrganization;
import ghidra.program.model.data.GenericCallingConvention;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.Encoder;
import ghidra.util.Msg;
import ghidra.util.datastruct.RangeMap;
import ghidra.util.exception.CancelledException;
@ -681,7 +683,7 @@ class TemporaryCompilerSpec implements CompilerSpec {
}
@Override
public void saveXml(StringBuilder buffer) {
public void encode(Encoder encoder) throws IOException {
throw new UnsupportedOperationException();
}

View file

@ -28,8 +28,7 @@ import ghidra.program.model.lang.InjectContext;
import ghidra.program.model.lang.InjectPayload;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.Msg;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@ -178,12 +177,12 @@ public class InjectPayloadDexParameters implements InjectPayload {
}
@Override
public void saveXml(StringBuilder buffer) {
public void encode(Encoder encoder) throws IOException {
// Provide a minimal tag so decompiler can call-back
buffer.append("<pcode");
SpecXmlUtils.encodeStringAttribute(buffer, "inject", "uponentry");
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_PCODE);
encoder.writeString(AttributeId.ATTRIB_INJECT, "uponentry");
encoder.writeBool(AttributeId.ATTRIB_DYNAMIC, true);
encoder.closeElement(ElementId.ELEM_PCODE);
}
@Override

View file

@ -28,8 +28,7 @@ import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.InjectContext;
import ghidra.program.model.lang.InjectPayload;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.pcode.*;
import ghidra.util.Msg;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@ -111,12 +110,12 @@ public class InjectPayloadJavaParameters implements InjectPayload {
}
@Override
public void saveXml(StringBuilder buffer) {
public void encode(Encoder encoder) throws IOException {
// Provide a minimal tag so decompiler can call-back
buffer.append("<pcode");
SpecXmlUtils.encodeStringAttribute(buffer, "inject", "uponentry");
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
buffer.append("/>\n");
encoder.openElement(ElementId.ELEM_PCODE);
encoder.writeString(AttributeId.ATTRIB_INJECT, "uponentry");
encoder.writeBool(AttributeId.ATTRIB_DYNAMIC, true);
encoder.closeElement(ElementId.ELEM_PCODE);
}
@Override