GP-4285 Compressed SLEIGH

This commit is contained in:
caheckman 2024-01-10 22:53:12 +00:00
parent b380fd5fa6
commit 8fbd171cdf
207 changed files with 15233 additions and 6055 deletions

View file

@ -50,9 +50,9 @@ YACC=bison
# libraries
#INCLUDES=-I$(BFDHOME)/include
INCLUDES=
BFDLIB=-lbfd -lz
BFDLIB=-lbfd
LNK=
LNK=-lz
# Source files
ALL_SOURCE= $(wildcard *.cc)
@ -87,7 +87,7 @@ DECCORE=capability architecture options graph cover block cast typeop database c
printlanguage printc printjava memstate opbehavior paramid signature $(COREEXT_NAMES)
# Files used for any project that use the sleigh decoder
SLEIGH= sleigh pcodeparse pcodecompile sleighbase slghsymbol \
slghpatexpress slghpattern semantics context filemanage
slghpatexpress slghpattern semantics context slaformat compression filemanage
# Additional files for the GHIDRA specific build
GHIDRA= ghidra_arch inject_ghidra ghidra_translate loadimage_ghidra \
typegrp_ghidra database_ghidra ghidra_context cpool_ghidra \
@ -260,10 +260,10 @@ test: ghidra_test_dbg
./ghidra_test_dbg
ghidra_dbg: $(GHIDRA_DBG_OBJS)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_dbg $(GHIDRA_DBG_OBJS) $(LNK)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_dbg $(GHIDRA_DBG_OBJS)
ghidra_opt: $(GHIDRA_OPT_OBJS)
$(CXX) $(OPT_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_opt $(GHIDRA_OPT_OBJS) $(LNK)
$(CXX) $(OPT_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o ghidra_opt $(GHIDRA_OPT_OBJS)
sleigh_dbg: $(SLEIGH_DBG_OBJS)
$(CXX) $(DBG_CXXFLAGS) $(ADDITIONAL_FLAGS) $(MAKE_STATIC) $(ARCH_TYPE) -o sleigh_dbg $(SLEIGH_DBG_OBJS) $(LNK)

View file

@ -98,10 +98,10 @@ public:
void encode(Encoder &encoder) const; ///< Encode \b this to a stream
void encode(Encoder &encoder,int4 size) const; ///< Encode \b this and a size to a stream
/// Restore an address from parsed XML
/// Decode an address from a stream
static Address decode(Decoder &decoder);
/// Restore an address and size from parsed XML
/// Decode an address and size from a stream
static Address decode(Decoder &decoder,int4 &size);
};
@ -221,7 +221,7 @@ class RangeProperties {
bool seenLast; ///< End of the range is actively specified
public:
RangeProperties(void) { first = 0; last = 0; isRegister = false; seenLast = false; }
void decode(Decoder &decoder); ///< Restore \b this from an XML stream
void decode(Decoder &decoder); ///< Decode \b this from a stream
};
/// \brief A disjoint set of Ranges, possibly across multiple address spaces

View file

@ -236,7 +236,7 @@ public:
void setPrototype(const PrototypePieces &pieces); ///< Set the prototype for a particular function
void setPrintLanguage(const string &nm); ///< Establish a particular output language
void globalify(void); ///< Mark \e all spaces as global
void decodeFlowOverride(Decoder &decoder); ///< Set flow overrides from XML
void decodeFlowOverride(Decoder &decoder); ///< Decode flow overrides from a stream
virtual ~Architecture(void); ///< Destructor
/// \brief Get a string describing \b this architecture

View file

@ -132,7 +132,7 @@ private:
// the result of the condition being false
static void replaceEdgeMap(vector<BlockEdge> &vec); ///< Update block references in edges with copy map
void addInEdge(FlowBlock *b,uint4 lab); ///< Add an edge coming into \b this
void decodeNextInEdge(Decoder &decoder,BlockMap &resolver); ///< Restore the next input edge from XML
void decodeNextInEdge(Decoder &decoder,BlockMap &resolver); ///< Decode the next input edge from stream
void halfDeleteInEdge(int4 slot); ///< Delete the \e in half of an edge, correcting indices
void halfDeleteOutEdge(int4 slot); ///< Delete the \e out half of an edge, correcting indices
void removeInEdge(int4 slot); ///< Remove an incoming edge

View file

@ -68,7 +68,7 @@ public:
int4 getUniq(void) const { return uniq; } ///< Get the sub-sorting index
const string &getText(void) const { return text; } ///< Get the body of the comment
void encode(Encoder &encoder) const; ///< Encode the comment to a stream
void decode(Decoder &decoder); ///< Restore the comment from XML
void decode(Decoder &decoder); ///< Decode the comment from a stream
static uint4 encodeCommentType(const string &name); ///< Convert name string to comment property
static string decodeCommentType(uint4 val); ///< Convert comment property to string
};
@ -146,7 +146,7 @@ public:
/// \param encoder is the stream encoder
virtual void encode(Encoder &encoder) const=0;
/// \brief Restore all comments from a \<commentdb> element
/// \brief Decode all comments from a \<commentdb> element
///
/// \param decoder is the stream decoder
virtual void decode(Decoder &decoder)=0;

View file

@ -0,0 +1,165 @@
/* ###
* 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.
*/
#include "compression.hh"
namespace ghidra {
/// The compression \b level ranges from 1-9 from faster/least compression to slower/most compression.
/// Use a \b level of 0 for no compression and -1 for the \e default compression level.
/// \param level is the compression level
Compress::Compress(int4 level)
{
compStream.zalloc = Z_NULL;
compStream.zfree = Z_NULL;
compStream.opaque = Z_NULL;
int4 ret = deflateInit(&compStream, level);
if (ret != Z_OK)
throw LowlevelError("Could not initialize deflate stream state");
}
Compress::~Compress(void)
{
deflateEnd(&compStream);
}
/// Return the number of bytes of output space still available. Output may be limited by the amount
/// of space in the output buffer or the amount of data available in the current input buffer.
/// \param buffer is where compressed bytes are stored
/// \param sz is the size, in bytes, of the buffer
/// \param finish is set to \b true if this is the final buffer to add to the stream
/// \return the number of output bytes still available
int4 Compress::deflate(uint1 *buffer,int4 sz,bool finish)
{
int flush = finish ? Z_FINISH : Z_NO_FLUSH;
compStream.avail_out = sz;
compStream.next_out = buffer;
int ret = ::deflate(&compStream, flush);
if (ret == Z_STREAM_ERROR)
throw LowlevelError("Error compressing stream");
return compStream.avail_out;
}
Decompress::Decompress(void)
{
streamFinished = false;
compStream.zalloc = Z_NULL;
compStream.zfree = Z_NULL;
compStream.opaque = Z_NULL;
compStream.avail_in = 0;
compStream.next_in = Z_NULL;
int ret = inflateInit(&compStream);
if (ret != Z_OK)
throw LowlevelError("Could not initialize inflate stream state");
}
/// Return the number of bytes of output space still available. Output may be limited by the amount
/// of space in the output buffer or the amount of data available in the current input buffer.
/// \param buffer is where uncompressed bytes are stored
/// \param sz is the size, in bytes, of the buffer
/// \return the number of output bytes still available
int4 Decompress::inflate(uint1 *buffer,int4 sz)
{
compStream.avail_out = sz;
compStream.next_out = buffer;
int ret = ::inflate(&compStream, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
case Z_STREAM_ERROR:
throw LowlevelError("Error decompressing stream");
case Z_STREAM_END:
streamFinished = true;
break;
default:
break;
}
return compStream.avail_out;
}
Decompress::~Decompress(void)
{
inflateEnd(&compStream);
}
const int4 CompressBuffer::IN_BUFFER_SIZE = 4096;
const int4 CompressBuffer::OUT_BUFFER_SIZE = 4096;
/// \param s is the backing output stream
/// \param level is the level of compression
CompressBuffer::CompressBuffer(ostream &s,int4 level)
: outStream(s), compressor(level)
{
inBuffer = new uint1[IN_BUFFER_SIZE];
outBuffer = new uint1[OUT_BUFFER_SIZE];
setp((char *)inBuffer,(char *)inBuffer + IN_BUFFER_SIZE-1);
}
CompressBuffer::~CompressBuffer(void)
{
delete [] inBuffer;
delete [] outBuffer;
}
/// The compressor is called repeatedly and its output is written to the backing stream
/// until the compressor can no longer fill the \e output buffer.
/// \param lastBuffer is \b true if this is the final set of bytes to add to the compressed stream
void CompressBuffer::flushInput(bool lastBuffer)
{
int len = pptr() - pbase();
compressor.input((uint1 *)pbase(),len);
int4 outAvail;
do {
outAvail = OUT_BUFFER_SIZE;
outAvail = compressor.deflate(outBuffer,outAvail,lastBuffer);
outStream.write((char *)outBuffer,OUT_BUFFER_SIZE-outAvail);
} while(outAvail == 0);
pbump(-len);
}
/// \param c is the final character filling the buffer
/// \return the written character
int CompressBuffer::overflow(int c)
{
if (c != EOF) {
*pptr() = c;
pbump(1);
}
flushInput(false);
return c;
}
/// \return 0 for success
int CompressBuffer::sync(void)
{
flushInput(true);
return 0;
}
}

View file

@ -0,0 +1,100 @@
/* ###
* 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.
*/
/// \file compression.hh
/// \brief The Compress and Decompress classes wrapping the deflate and inflate algorithms
#ifndef __COMPRESSION__
#define __COMPRESSION__
#include "error.hh"
#ifdef LOCAL_ZLIB
#include "../zlib/zlib.h"
#else
#include <zlib.h>
#endif
namespace ghidra {
/// \brief Wrapper for the deflate algorithm
///
/// Initialize/free algorithm resources. Provide successive arrays of bytes to compress via
/// the input() method. Compute successive arrays of compressed bytes via the deflate() method.
class Compress {
z_stream compStream; ///< The zlib deflate algorithm state
public:
Compress(int4 level); ///< Initialize the deflate algorithm state
~Compress(void); ///< Free algorithm state resources
/// \brief Provide the next sequence of bytes to be compressed
///
/// \param buffer is a pointer to the bytes to compress
/// \param sz is the number of bytes
void input(uint1 *buffer,int4 sz) {
compStream.avail_in = sz;
compStream.next_in = buffer;
}
int4 deflate(uint1 *buffer,int4 sz,bool finish); ///< Deflate as much as possible into given buffer
};
/// \brief Wrapper for the inflate algorithm
///
/// Initialize/free algorithm resources. Provide successive arrays of compressed bytes via
/// the input() method. Compute successive arrays of uncompressed bytes via the inflate() method.
class Decompress {
z_stream compStream; ///< The zlib inflate algorithm state
bool streamFinished; ///< Set to \b true if the end of the compressed stream has been reached
public:
Decompress(void); ///< Initialize the inflate algorithm state
~Decompress(void); ///< Free algorithm state resources
/// \brief Provide the next sequence of compressed bytes
///
/// \param buffer is a pointer to the compressed bytes
/// \param sz is the number of bytes
void input(uint1 *buffer,int4 sz) {
compStream.next_in = buffer;
compStream.avail_in = sz;
}
bool isFinished(void) const { return streamFinished; } ///< Return \b if end of compressed stream is reached
int4 inflate(uint1 *buffer,int4 sz); ///< Inflate as much as possible into given buffer
};
/// \brief Stream buffer that performs compression
///
/// Provides an ostream filter that compresses the stream using the \e deflate algorithm.
/// The stream buffer is provided a backing stream that is the ultimate destination of the compressed bytes.
/// A front-end stream is initialized with \b this stream buffer.
/// After writing the full sequence of bytes to compressed to the front-end stream, make sure to
/// call the stream's flush() method to emit the final compressed bytes to the backing stream.
class CompressBuffer : public std::streambuf {
static const int4 IN_BUFFER_SIZE; ///< Number of bytes in the \e input buffer
static const int4 OUT_BUFFER_SIZE; ///< Number of bytes in the \e output buffer
ostream &outStream; ///< The backing stream receiving compressed bytes
uint1 *inBuffer; ///< The \e input buffer
uint1 *outBuffer; ///< The \e output buffer
Compress compressor; ///< Compressor state
protected:
void flushInput(bool lastBuffer); ///< Compress the current set of bytes in the \e input buffer
virtual int overflow(int c); ///< Pass the filled input buffer to the compressor
virtual int sync(void); ///< Pass remaining bytes in the input buffer to the compressor
public:
CompressBuffer(ostream &s,int4 level); ///< Constructor
~CompressBuffer(void); ///< Destructor
};
}
#endif

View file

@ -628,66 +628,4 @@ uintb FloatFormat::opRound(uintb a) const
return getEncoding(round(val)); // round half away from zero
}
/// Write the format out to a \<floatformat> XML tag.
/// \param s is the output stream
void FloatFormat::saveXml(ostream &s) const
{
s << "<floatformat";
a_v_i(s,"size",size);
a_v_i(s,"signpos",signbit_pos);
a_v_i(s,"fracpos",frac_pos);
a_v_i(s,"fracsize",frac_size);
a_v_i(s,"exppos",exp_pos);
a_v_i(s,"expsize",exp_size);
a_v_i(s,"bias",bias);
a_v_b(s,"jbitimplied",jbitimplied);
s << "/>\n";
}
/// Restore \b object from a \<floatformat> XML tag
/// \param el is the element
void FloatFormat::restoreXml(const Element *el)
{
{
istringstream s(el->getAttributeValue("size"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> size;
}
{
istringstream s(el->getAttributeValue("signpos"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> signbit_pos;
}
{
istringstream s(el->getAttributeValue("fracpos"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> frac_pos;
}
{
istringstream s(el->getAttributeValue("fracsize"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> frac_size;
}
{
istringstream s(el->getAttributeValue("exppos"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> exp_pos;
}
{
istringstream s(el->getAttributeValue("expsize"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> exp_size;
}
{
istringstream s(el->getAttributeValue("bias"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> bias;
}
jbitimplied = xml_readbool(el->getAttributeValue("jbitimplied"));
maxexponent = (1<<exp_size)-1;
calcPrecision();
}
} // End namespace ghidra

View file

@ -19,7 +19,7 @@
#ifndef __FLOAT_HH__
#define __FLOAT_HH__
#include "xml.hh"
#include "error.hh"
namespace ghidra {
@ -61,7 +61,6 @@ private:
uintb getNaNEncoding(bool sgn) const; ///< Get an encoded NaN value
void calcPrecision(void); ///< Calculate the decimal precision of this format
public:
FloatFormat(void) {} ///< Construct for use with restoreXml()
FloatFormat(int4 sz); ///< Construct default IEEE 754 standard settings
int4 getSize(void) const { return size; } ///< Get the size of the encoding in bytes
double getHostFloat(uintb encoding,floatclass *type) const; ///< Convert an encoding into host's double
@ -93,9 +92,6 @@ public:
uintb opRound(uintb a) const; ///< Round
uintb opInt2Float(uintb a,int4 sizein) const; ///< Convert integer to floating-point
uintb opFloat2Float(uintb a,const FloatFormat &outformat) const; ///< Convert between floating-point precisions
void saveXml(ostream &s) const; ///< Save the format to an XML stream
void restoreXml(const Element *el); ///< Restore the format from XML
};
} // End namespace ghidra

View file

@ -1959,7 +1959,7 @@ const string FspecSpace::NAME = "fspec";
/// \param t is the associated processor translator
/// \param ind is the index associated with the space
FspecSpace::FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
: AddrSpace(m,t,IPTR_FSPEC,NAME,sizeof(void *),1,ind,0,1)
: AddrSpace(m,t,IPTR_FSPEC,NAME,false,sizeof(void *),1,ind,0,1,1)
{
clearFlags(heritaged|does_deadcode|big_endian);
if (HOST_ENDIAN==1) // Endianness always set by host
@ -2008,12 +2008,6 @@ void FspecSpace::printRaw(ostream &s,uintb offset) const
}
}
void FspecSpace::saveXml(ostream &s) const
{
throw LowlevelError("Should never encode fspec space to stream");
}
void FspecSpace::decode(Decoder &decoder)
{

View file

@ -345,7 +345,6 @@ public:
virtual void encodeAttributes(Encoder &encoder,uintb offset) const;
virtual void encodeAttributes(Encoder &encoder,uintb offset,int4 size) const;
virtual void printRaw(ostream &s,uintb offset) const;
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
static const string NAME; ///< Reserved name for the fspec space
};

View file

@ -197,7 +197,7 @@ public:
void printBlockTree(ostream &s) const; ///< Print a description of control-flow structuring to a stream
void printLocalRange(ostream &s) const; ///< Print description of memory ranges associated with local scopes
void encode(Encoder &encoder,uint8 id,bool savetree) const; ///< Encode a description of \b this function to stream
uint8 decode(Decoder &decoder); ///< Restore the state of \b this function from an XML description
uint8 decode(Decoder &decoder); ///< Restore the state of \b this function from a stream
void encodeJumpTable(Encoder &encoder) const; ///< Encode a description of jump-tables to stream
void decodeJumpTable(Decoder &decoder); ///< Decode jump-tables from a stream
void encodeTree(Encoder &encoder) const; ///< Encode a description of the p-code tree to stream

View file

@ -321,7 +321,7 @@ void IfcOption::execute(istream &s)
}
try {
string res = dcp->conf->options->set(ElementId::find(optname),p1,p2,p3);
string res = dcp->conf->options->set(ElementId::find(optname,0),p1,p2,p3);
*status->optr << res << endl;
}
catch(ParseError &err) {

View file

@ -91,7 +91,8 @@ void InjectPayloadSleigh::decode(Decoder &decoder)
void InjectPayloadSleigh::printTemplate(ostream &s) const
{
tpl->saveXml(s,-1);
XmlEncode encoder(s);
tpl->encode(encoder,-1);
}
void InjectPayloadSleigh::checkParameterRestrictions(InjectContextSleigh &con,
@ -247,7 +248,8 @@ void ExecutablePcodeSleigh::decode(Decoder &decoder)
void ExecutablePcodeSleigh::printTemplate(ostream &s) const
{
tpl->saveXml(s,-1);
XmlEncode encoder(s);
tpl->encode(encoder,-1);
}
InjectPayloadDynamic::~InjectPayloadDynamic(void)

View file

@ -24,6 +24,9 @@ unordered_map<string,uint4> AttributeId::lookupAttributeId;
const int4 PackedDecode::BUFFER_SIZE = 1024;
const char XmlEncode::spaces[] = "\n ";
const int4 XmlEncode::MAX_SPACES = 24+1;
/// Access static vector of AttributeId objects that are registered during static initialization
/// The list itself is created once on the first call to this method.
/// \return a reference to the vector
@ -38,11 +41,13 @@ vector<AttributeId *> &AttributeId::getList(void)
/// in the global hashtable.
/// \param nm is the name of the attribute
/// \param i is an id to associate with the attribute
AttributeId::AttributeId(const string &nm,uint4 i)
/// \param scope is an id for the scope of this attribute
AttributeId::AttributeId(const string &nm,uint4 i,int4 scope)
: name(nm)
{
id = i;
getList().push_back(this);
if (scope == 0)
getList().push_back(this);
}
/// Fill the hashtable mapping attribute names to their id, from registered attribute objects
@ -78,11 +83,13 @@ vector<ElementId *> &ElementId::getList(void)
/// in the global hashtable.
/// \param nm is the name of the element
/// \param i is an id to associate with the element
ElementId::ElementId(const string &nm,uint4 i)
/// \param scope is an id for the scope of this element
ElementId::ElementId(const string &nm,uint4 i,int4 scope)
: name(nm)
{
id = i;
getList().push_back(this);
if (scope == 0)
getList().push_back(this);
}
/// Fill the hashtable mapping element names to their id, from registered element objects
@ -132,7 +139,7 @@ uint4 XmlDecode::peekElement(void)
return 0;
el = *iter;
}
return ElementId::find(el->getName());
return ElementId::find(el->getName(),scope);
}
uint4 XmlDecode::openElement(void)
@ -156,7 +163,7 @@ uint4 XmlDecode::openElement(void)
elStack.push_back(el);
iterStack.push_back(el->getChildren().begin());
attributeIndex = -1;
return ElementId::find(el->getName());
return ElementId::find(el->getName(),scope);
}
uint4 XmlDecode::openElement(const ElementId &elemId)
@ -194,7 +201,7 @@ void XmlDecode::closeElement(uint4 id)
const Element *el = elStack.back();
if (iterStack.back() != el->getChildren().end())
throw DecoderError("Closing element <" + el->getName() + "> with additional children");
if (ElementId::find(el->getName()) != id)
if (ElementId::find(el->getName(), scope) != id)
throw DecoderError("Trying to close <" + el->getName() + "> with mismatching id");
#endif
elStack.pop_back();
@ -207,7 +214,7 @@ void XmlDecode::closeElementSkipping(uint4 id)
{
#ifdef CPUI_DEBUG
const Element *el = elStack.back();
if (ElementId::find(el->getName()) != id)
if (ElementId::find(el->getName(), scope) != id)
throw DecoderError("Trying to close <" + el->getName() + "> with mismatching id");
#endif
elStack.pop_back();
@ -228,7 +235,7 @@ uint4 XmlDecode::getNextAttributeId(void)
int4 nextIndex = attributeIndex + 1;
if (nextIndex < el->getNumAttributes()) {
attributeIndex = nextIndex;
return AttributeId::find(el->getAttributeName(attributeIndex));
return AttributeId::find(el->getAttributeName(attributeIndex),scope);
}
return 0;
}
@ -419,40 +426,89 @@ AddrSpace *XmlDecode::readSpace(const AttributeId &attribId)
return res;
}
OpCode XmlDecode::readOpcode(void)
{
const Element *el = elStack.back();
string nm = el->getAttributeValue(attributeIndex);
OpCode opc = get_opcode(nm);
if (opc == (OpCode)0)
throw DecoderError("Bad encoded OpCode");
return opc;
}
OpCode XmlDecode::readOpcode(AttributeId &attribId)
{
const Element *el = elStack.back();
string nm;
if (attribId == ATTRIB_CONTENT) {
nm = el->getContent();
}
else {
int4 index = findMatchingAttribute(el, attribId.getName());
nm = el->getAttributeValue(index);
}
OpCode opc = get_opcode(nm);
if (opc == (OpCode)0)
throw DecoderError("Bad encoded OpCode");
return opc;
}
void XmlEncode::newLine(void)
{
if (!doFormatting)
return;
int numSpaces = depth * 2 + 1;
if (numSpaces > MAX_SPACES) {
numSpaces = MAX_SPACES;
}
outStream.write(spaces,numSpaces);
}
void XmlEncode::openElement(const ElementId &elemId)
{
if (elementTagIsOpen)
if (tagStatus == tag_start)
outStream << '>';
else
elementTagIsOpen = true;
tagStatus = tag_start;
newLine();
outStream << '<' << elemId.getName();
depth += 1;
}
void XmlEncode::closeElement(const ElementId &elemId)
{
if (elementTagIsOpen) {
depth -= 1;
if (tagStatus == tag_start) {
outStream << "/>";
elementTagIsOpen = false;
}
else {
outStream << "</" << elemId.getName() << '>';
tagStatus = tag_stop;
return;
}
if (tagStatus != tag_content)
newLine();
else
tagStatus = tag_stop;
outStream << "</" << elemId.getName() << '>';
}
void XmlEncode::writeBool(const AttributeId &attribId,bool val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
if (val)
outStream << "true";
else
outStream << "false";
tagStatus = tag_content;
return;
}
a_v_b(outStream, attribId.getName(), val);
@ -462,11 +518,11 @@ void XmlEncode::writeSignedInteger(const AttributeId &attribId,intb val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
outStream << dec << val;
tagStatus = tag_content;
return;
}
a_v_i(outStream, attribId.getName(), val);
@ -476,11 +532,11 @@ void XmlEncode::writeUnsignedInteger(const AttributeId &attribId,uintb val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
outStream << hex << "0x" << val;
tagStatus = tag_content;
return;
}
a_v_u(outStream, attribId.getName(), val);
@ -490,11 +546,11 @@ void XmlEncode::writeString(const AttributeId &attribId,const string &val)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
xml_escape(outStream, val.c_str());
tagStatus = tag_content;
return;
}
a_v(outStream,attribId.getName(),val);
@ -514,16 +570,33 @@ void XmlEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
{
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (elementTagIsOpen) {
if (tagStatus == tag_start) {
outStream << '>';
elementTagIsOpen = false;
}
xml_escape(outStream, spc->getName().c_str());
tagStatus = tag_content;
return;
}
a_v(outStream,attribId.getName(),spc->getName());
}
void XmlEncode::writeOpcode(const AttributeId &attribId,OpCode opc)
{
const char *name = get_opname(opc);
if (attribId == ATTRIB_CONTENT) { // Special id indicating, text value
if (tagStatus == tag_start) {
outStream << '>';
}
outStream << name;
tagStatus = tag_content;
return;
}
outStream << ' ' << attribId.getName() << "=\"";
outStream << name;
outStream << "\"";
}
/// The integer is encoded, 7-bits per byte, starting with the most significant 7-bits.
/// The integer is decode from the \e current position, and the position is advanced.
/// \param len is the number of bytes to extract
@ -598,6 +671,27 @@ void PackedDecode::skipAttributeRemaining(uint1 typeByte)
advancePosition(curPos, length); // Skip -length- data
}
/// Set decoder to beginning of the stream. Add padding to end of the stream.
/// \param bufPos is the number of bytes used by the last input buffer
void PackedDecode::endIngest(int4 bufPos)
{
endPos.seqIter = inStream.begin(); // Set position to beginning of stream
if (endPos.seqIter != inStream.end()) {
endPos.current = (*endPos.seqIter).start;
endPos.end = (*endPos.seqIter).end;
// Make sure there is at least one character after ingested buffer
if (bufPos == BUFFER_SIZE) {
// Last buffer was entirely filled
uint1 *endbuf = new uint1[1]; // Add one more buffer
inStream.emplace_back(endbuf,endbuf + 1);
bufPos = 0;
}
uint1 *buf = inStream.back().start;
buf[bufPos] = ELEMENT_END;
}
}
PackedDecode::~PackedDecode(void)
{
@ -612,25 +706,11 @@ void PackedDecode::ingestStream(istream &s)
{
int4 gcount = 0;
while(s.peek() > 0) {
uint1 *buf = new uint1[BUFFER_SIZE + 1];
inStream.emplace_back(buf,buf+BUFFER_SIZE);
uint1 *buf = allocateNextInputBuffer(1);
s.get((char *)buf,BUFFER_SIZE+1,'\0');
gcount = s.gcount();
}
endPos.seqIter = inStream.begin();
if (endPos.seqIter != inStream.end()) {
endPos.current = (*endPos.seqIter).start;
endPos.end = (*endPos.seqIter).end;
// Make sure there is at least one character after ingested buffer
if (gcount == BUFFER_SIZE) {
// Last buffer was entirely filled
uint1 *endbuf = new uint1[1]; // Add one more buffer
inStream.emplace_back(endbuf,endbuf + 1);
gcount = 0;
}
uint1 *buf = inStream.back().start;
buf[gcount] = ELEMENT_END;
}
endIngest(gcount);
}
uint4 PackedDecode::peekElement(void)
@ -959,6 +1039,24 @@ AddrSpace *PackedDecode::readSpace(const AttributeId &attribId)
return res;
}
OpCode PackedDecode::readOpcode(void)
{
int4 val = (int4)readSignedInteger();
if (val < 0 || val >= CPUI_MAX)
throw DecoderError("Bad encoded OpCode");
return (OpCode)val;
}
OpCode PackedDecode::readOpcode(AttributeId &attribId)
{
findMatchingAttribute(attribId);
OpCode opc = readOpcode();
curPos = startPos;
return opc;
}
/// The value is either an unsigned integer, an address space index, or (the absolute value of) a signed integer.
/// A type header is passed in with the particular type code for the value already filled in.
/// This method then fills in the length code, outputs the full type header and the encoded bytes of the integer.
@ -973,7 +1071,7 @@ void PackedEncode::writeInteger(uint1 typeByte,uint8 val)
lenCode = 0;
sa = -1;
}
if (val < 0x800000000) {
else if (val < 0x800000000) {
if (val < 0x200000) {
if (val < 0x80) {
lenCode = 1; // 7-bits
@ -1119,6 +1217,13 @@ void PackedEncode::writeSpace(const AttributeId &attribId,const AddrSpace *spc)
}
}
void PackedEncode::writeOpcode(const AttributeId &attribId,OpCode opc)
{
writeHeader(ATTRIBUTE, attribId.getId());
writeInteger((TYPECODE_SIGNEDINT_POSITIVE << TYPECODE_SHIFT), opc);
}
// Common attributes. Attributes with multiple uses
AttributeId ATTRIB_CONTENT = AttributeId("XMLcontent",1);
AttributeId ATTRIB_ALIGN = AttributeId("align",2);

View file

@ -17,6 +17,7 @@
#define __MARSHAL_HH__
#include "xml.hh"
#include "opcodes.hh"
#include <list>
#include <unordered_map>
@ -43,11 +44,11 @@ class AttributeId {
string name; ///< The name of the attribute
uint4 id; ///< The (internal) id of the attribute
public:
AttributeId(const string &nm,uint4 i); ///< Construct given a name and id
AttributeId(const string &nm,uint4 i,int4 scope=0); ///< Construct given a name and id
const string &getName(void) const { return name; } ///< Get the attribute's name
uint4 getId(void) const { return id; } ///< Get the attribute's id
bool operator==(const AttributeId &op2) const { return (id == op2.id); } ///< Test equality with another AttributeId
static uint4 find(const string &nm); ///< Find the id associated with a specific attribute name
static uint4 find(const string &nm,int4 scope); ///< Find the id associated with a specific attribute name
static void initialize(void); ///< Populate a hashtable with all AttributeId objects
friend bool operator==(uint4 id,const AttributeId &op2) { return (id == op2.id); } ///< Test equality of a raw integer id with an AttributeId
friend bool operator==(const AttributeId &op1,uint4 id) { return (op1.id == id); } ///< Test equality of an AttributeId with a raw integer id
@ -67,11 +68,11 @@ class ElementId {
string name; ///< The name of the element
uint4 id; ///< The (internal) id of the attribute
public:
ElementId(const string &nm,uint4 i); ///< Construct given a name and id
ElementId(const string &nm,uint4 i,int4 scope=0); ///< Construct given a name and id
const string &getName(void) const { return name; } ///< Get the element's name
uint4 getId(void) const { return id; } ///< Get the element's id
bool operator==(const ElementId &op2) const { return (id == op2.id); } ///< Test equality with another ElementId
static uint4 find(const string &nm); ///< Find the id associated with a specific element name
static uint4 find(const string &nm,int4 scope); ///< Find the id associated with a specific element name
static void initialize(void); ///< Populate a hashtable with all ElementId objects
friend bool operator==(uint4 id,const ElementId &op2) { return (id == op2.id); } ///< Test equality of a raw integer id with an ElementId
friend bool operator==(const ElementId &op1,uint4 id) { return (op1.id == id); } ///< Test equality of an ElementId with a raw integer id
@ -269,6 +270,21 @@ public:
/// \return the address space associated with the attribute
virtual AddrSpace *readSpace(const AttributeId &attribId)=0;
/// \brief Parse the current attribute as a p-code OpCode
///
/// The last attribute, as returned by getNextAttributeId, is returned as an OpCode.
/// \return the OpCode associated with the current attribute
virtual OpCode readOpcode(void)=0;
/// \brief Find the specific attribute in the current element and return it as an OpCode
///
/// Search attributes from the current element for a match to the given attribute id.
/// Return this attribute as an OpCode. If there is no matching attribute id, an exception is thrown.
/// Parse via getNextAttributeId is reset.
/// \param attribId is the specific attribute id to match
/// \return the OpCode associated with the attribute
virtual OpCode readOpcode(AttributeId &attribId)=0;
/// \brief Skip parsing of the next element
///
/// The element skipped is the one that would be opened by the next call to openElement.
@ -350,6 +366,13 @@ public:
/// \param attribId is the given AttributeId annotation
/// \param spc is the address space to encode
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc)=0;
/// \brief Write a p-code operation opcode into the encoding, associating it with the given annotation
///
/// \param attribId is the given annotation
/// \param opc is the opcode
virtual void writeOpcode(const AttributeId &attribId,OpCode opc)=0;
};
/// \brief An XML based decoder
@ -363,12 +386,13 @@ class XmlDecode : public Decoder {
vector<const Element *> elStack; ///< Stack of currently \e open elements
vector<List::const_iterator> iterStack; ///< Index of next child for each \e open element
int4 attributeIndex; ///< Position of \e current attribute to parse (in \e current element)
int4 scope; ///< Scope of element/attribute tags to look up
int4 findMatchingAttribute(const Element *el,const string &attribName);
public:
XmlDecode(const AddrSpaceManager *spc,const Element *root) : Decoder(spc) {
document = (Document *)0; rootElement = root; attributeIndex = -1; } ///< Constructor with preparsed root
XmlDecode(const AddrSpaceManager *spc) : Decoder(spc) {
document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; } ///< Constructor for use with ingestStream
XmlDecode(const AddrSpaceManager *spc,const Element *root,int4 sc=0) : Decoder(spc) {
document = (Document *)0; rootElement = root; attributeIndex = -1; scope = sc; } ///< Constructor with preparsed root
XmlDecode(const AddrSpaceManager *spc,int4 sc=0) : Decoder(spc) {
document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; scope=sc; } ///< Constructor for use with ingestStream
const Element *getCurrentXmlElement(void) const { return elStack.back(); } ///< Get pointer to underlying XML element object
virtual ~XmlDecode(void);
virtual void ingestStream(istream &s);
@ -392,6 +416,8 @@ public:
virtual string readString(const AttributeId &attribId);
virtual AddrSpace *readSpace(void);
virtual AddrSpace *readSpace(const AttributeId &attribId);
virtual OpCode readOpcode(void);
virtual OpCode readOpcode(AttributeId &attribId);
};
/// \brief An XML based encoder
@ -400,10 +426,20 @@ public:
/// receive the XML document as calls are made on the encoder.
class XmlEncode : public Encoder {
friend class XmlDecode;
enum {
tag_start = 0, ///< Tag has been opened, attributes can be written
tag_content = 1, ///< Opening tag and content have been written
tag_stop = 2 ///< No tag is currently being written
};
static const char spaces[]; ///< Array of ' ' characters for emitting indents
static const int4 MAX_SPACES;
ostream &outStream; ///< The stream receiving the encoded data
bool elementTagIsOpen; ///< If \b true, new attributes can be written to the current element
int4 tagStatus; ///< Stage of writing an element tag
int4 depth; ///< Depth of open elements
bool doFormatting; ///< \b true if encoder should indent and emit newlines
void newLine(void); ///< Emit a newline and proper indenting for the next tag
public:
XmlEncode(ostream &s) : outStream(s) { elementTagIsOpen = false; } ///< Construct from a stream
XmlEncode(ostream &s,bool doFormat=true) : outStream(s) { depth=0; tagStatus=tag_stop; doFormatting=doFormat; } ///< Construct from a stream
virtual void openElement(const ElementId &elemId);
virtual void closeElement(const ElementId &elemId);
virtual void writeBool(const AttributeId &attribId,bool val);
@ -412,6 +448,7 @@ public:
virtual void writeString(const AttributeId &attribId,const string &val);
virtual void writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val);
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
virtual void writeOpcode(const AttributeId &attribId,OpCode opc);
};
/// \brief Protocol format for PackedEncode and PackedDecode classes
@ -505,6 +542,9 @@ private:
void findMatchingAttribute(const AttributeId &attribId); ///< Find attribute matching the given id in open element
void skipAttribute(void); ///< Skip over the attribute at the current position
void skipAttributeRemaining(uint1 typeByte); ///< Skip over remaining attribute data, after a mismatch
protected:
uint1 *allocateNextInputBuffer(int4 pad); ///< Allocate the next chunk of space in the input stream
void endIngest(int4 bufPos); ///< Finish set up for reading input stream
public:
PackedDecode(const AddrSpaceManager *spcManager) : Decoder(spcManager) {} ///< Constructor
virtual ~PackedDecode(void);
@ -529,6 +569,8 @@ public:
virtual string readString(const AttributeId &attribId);
virtual AddrSpace *readSpace(void);
virtual AddrSpace *readSpace(const AttributeId &attribId);
virtual OpCode readOpcode(void);
virtual OpCode readOpcode(AttributeId &attribId);
};
/// \brief A byte-based encoder designed to marshal from the decompiler efficiently
@ -548,6 +590,7 @@ public:
virtual void writeString(const AttributeId &attribId,const string &val);
virtual void writeStringIndexed(const AttributeId &attribId,uint4 index,const string &val);
virtual void writeSpace(const AttributeId &attribId,const AddrSpace *spc);
virtual void writeOpcode(const AttributeId &attribId,OpCode opc);
};
/// An exception is thrown if the position currently points to the last byte in the stream
@ -602,6 +645,17 @@ inline void PackedDecode::advancePosition(Position &pos,int4 skip)
pos.current += skip;
}
/// Allocate an array of BUFFER_SIZE bytes and add it to the in-memory stream
/// \param pad is the number of bytes of padding to add to the allocation size, above BUFFER_SIZE
/// \return the newly allocated buffer
inline uint1 *PackedDecode::allocateNextInputBuffer(int4 pad)
{
uint1 *buf = new uint1[BUFFER_SIZE + pad];
inStream.emplace_back(buf,buf+BUFFER_SIZE);
return buf;
}
/// \param header is the type of header
/// \param id is the id associated with the element or attribute
inline void PackedEncode::writeHeader(uint1 header,uint4 id)
@ -624,29 +678,35 @@ extern ElementId ELEM_UNKNOWN; ///< Special element to represent an element wit
extern AttributeId ATTRIB_UNKNOWN; ///< Special attribute to represent an attribute with an unrecognized name
extern AttributeId ATTRIB_CONTENT; ///< Special attribute for XML text content of an element
/// The name is looked up in the global list of all attributes. If the attribute is not in the list, a special
/// The name is looked up in the scoped list of attributes. If the attribute is not in the list, a special
/// placeholder attribute, ATTRIB_UNKNOWN, is returned as a placeholder for attributes with unrecognized names.
/// \param nm is the name of the attribute
/// \param scope is the id of the scope in which to lookup of the name
/// \return the associated id
inline uint4 AttributeId::find(const string &nm)
inline uint4 AttributeId::find(const string &nm,int4 scope)
{
unordered_map<string,uint4>::const_iterator iter = lookupAttributeId.find(nm);
if (iter != lookupAttributeId.end())
return (*iter).second;
if (scope == 0) { // Current only support reverse look up for scope 0
unordered_map<string,uint4>::const_iterator iter = lookupAttributeId.find(nm);
if (iter != lookupAttributeId.end())
return (*iter).second;
}
return ATTRIB_UNKNOWN.id;
}
/// The name is looked up in the global list of all elements. If the element is not in the list, a special
/// The name is looked up in the scoped list of elements. If the element is not in the list, a special
/// placeholder element, ELEM_UNKNOWN, is returned as a placeholder for elements with unrecognized names.
/// \param nm is the name of the element
/// \param scope is the id of the scope in which to search
/// \return the associated id
inline uint4 ElementId::find(const string &nm)
inline uint4 ElementId::find(const string &nm,int4 scope)
{
unordered_map<string,uint4>::const_iterator iter = lookupElementId.find(nm);
if (iter != lookupElementId.end())
return (*iter).second;
if (scope == 0) {
unordered_map<string,uint4>::const_iterator iter = lookupElementId.find(nm);
if (iter != lookupElementId.end())
return (*iter).second;
}
return ELEM_UNKNOWN.id;
}

View file

@ -31,7 +31,7 @@ const string IopSpace::NAME = "iop";
/// \param t is the associated processor translator
/// \param ind is the associated index
IopSpace::IopSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
: AddrSpace(m,t,IPTR_IOP,NAME,sizeof(void *),1,ind,0,1)
: AddrSpace(m,t,IPTR_IOP,NAME,false,sizeof(void *),1,ind,0,1,1)
{
clearFlags(heritaged|does_deadcode|big_endian);
if (HOST_ENDIAN==1) // Endianness always set to host
@ -58,12 +58,6 @@ void IopSpace::printRaw(ostream &s,uintb offset) const
bl->getStart().printRaw(s);
}
void IopSpace::saveXml(ostream &s) const
{
throw LowlevelError("Should never encode iop space to stream");
}
void IopSpace::decode(Decoder &decoder)
{

View file

@ -40,7 +40,6 @@ public:
virtual void encodeAttributes(Encoder &encoder,uintb offset) const { encoder.writeString(ATTRIB_SPACE, "iop"); }
virtual void encodeAttributes(Encoder &encoder,uintb offset,int4 size) const { encoder.writeString(ATTRIB_SPACE, "iop"); }
virtual void printRaw(ostream &s,uintb offset) const;
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
static const string NAME; ///< Reserved name for the iop space
};

View file

@ -84,7 +84,7 @@ bool ArchOption::onOrOff(const string &p)
void OptionDatabase::registerOption(ArchOption *option)
{
uint4 id = ElementId::find(option->getName()); // Option name must match a known element name
uint4 id = ElementId::find(option->getName(),0); // Option name must match a known element name
optionmap[id] = option;
}

View file

@ -290,39 +290,6 @@ void ConstTpl::transfer(const vector<HandleTpl *> &params)
}
}
void ConstTpl::printHandleSelector(ostream &s,v_field val)
{
switch(val) {
case v_space:
s << "space";
break;
case v_offset:
s << "offset";
break;
case v_size:
s << "size";
break;
case v_offset_plus:
s << "offset_plus";
break;
}
}
ConstTpl::v_field ConstTpl::readHandleSelector(const string &name)
{
if (name == "space")
return v_space;
if (name == "offset")
return v_offset;
if (name == "size")
return v_size;
if (name == "offset_plus")
return v_offset_plus;
throw LowlevelError("Bad handle selector");
}
void ConstTpl::changeHandleIndex(const vector<int4> &handmap)
{
@ -330,120 +297,129 @@ void ConstTpl::changeHandleIndex(const vector<int4> &handmap)
value.handle_index = handmap[value.handle_index];
}
void ConstTpl::saveXml(ostream &s) const
void ConstTpl::encode(Encoder &encoder) const
{
s << "<const_tpl type=\"";
switch(type) {
case real:
s << "real\" val=\"0x" << hex << value_real << "\"/>";
encoder.openElement(sla::ELEM_CONST_REAL);
encoder.writeUnsignedInteger(sla::ATTRIB_VAL, value_real);
encoder.closeElement(sla::ELEM_CONST_REAL);
break;
case handle:
s << "handle\" val=\"" << dec << value.handle_index << "\" ";
s << "s=\"";
printHandleSelector(s,select);
s << "\"";
encoder.openElement(sla::ELEM_CONST_HANDLE);
encoder.writeSignedInteger(sla::ATTRIB_VAL, value.handle_index);
encoder.writeSignedInteger(sla::ATTRIB_S, select);
if (select == v_offset_plus)
s << " plus=\"0x" << hex << value_real << "\"";
s << "/>";
encoder.writeUnsignedInteger(sla::ATTRIB_PLUS, value_real);
encoder.closeElement(sla::ELEM_CONST_HANDLE);
break;
case j_start:
s << "start\"/>";
encoder.openElement(sla::ELEM_CONST_START);
encoder.closeElement(sla::ELEM_CONST_START);
break;
case j_next:
s << "next\"/>";
encoder.openElement(sla::ELEM_CONST_NEXT);
encoder.closeElement(sla::ELEM_CONST_NEXT);
break;
case j_next2:
s << "next2\"/>";
encoder.openElement(sla::ELEM_CONST_NEXT2);
encoder.closeElement(sla::ELEM_CONST_NEXT2);
break;
case j_curspace:
s << "curspace\"/>";
encoder.openElement(sla::ELEM_CONST_CURSPACE);
encoder.closeElement(sla::ELEM_CONST_CURSPACE);
break;
case j_curspace_size:
s << "curspace_size\"/>";
encoder.openElement(sla::ELEM_CONST_CURSPACE_SIZE);
encoder.closeElement(sla::ELEM_CONST_CURSPACE_SIZE);
break;
case spaceid:
s << "spaceid\" name=\"" << value.spaceid->getName() << "\"/>";
encoder.openElement(sla::ELEM_CONST_SPACEID);
encoder.writeSpace(sla::ATTRIB_SPACE, value.spaceid);
encoder.closeElement(sla::ELEM_CONST_SPACEID);
break;
case j_relative:
s << "relative\" val=\"0x" << hex << value_real << "\"/>";
encoder.openElement(sla::ELEM_CONST_RELATIVE);
encoder.writeUnsignedInteger(sla::ATTRIB_VAL, value_real);
encoder.closeElement(sla::ELEM_CONST_RELATIVE);
break;
case j_flowref:
s << "flowref\"/>";
encoder.openElement(sla::ELEM_CONST_FLOWREF);
encoder.closeElement(sla::ELEM_CONST_FLOWREF);
break;
case j_flowref_size:
s << "flowref_size\"/>";
encoder.openElement(sla::ELEM_CONST_FLOWREF_SIZE);
encoder.closeElement(sla::ELEM_CONST_FLOWREF_SIZE);
break;
case j_flowdest:
s << "flowdest\"/>";
encoder.openElement(sla::ELEM_CONST_FLOWDEST);
encoder.closeElement(sla::ELEM_CONST_FLOWDEST);
break;
case j_flowdest_size:
s << "flowdest_size\"/>";
encoder.openElement(sla::ELEM_CONST_FLOWDEST_SIZE);
encoder.closeElement(sla::ELEM_CONST_FLOWDEST_SIZE);
break;
}
}
void ConstTpl::restoreXml(const Element *el,const AddrSpaceManager *manage)
void ConstTpl::decode(Decoder &decoder)
{
const string &typestring(el->getAttributeValue("type"));
if (typestring == "real") {
uint4 el = decoder.openElement();
if (el == sla::ELEM_CONST_REAL) {
type = real;
istringstream s(el->getAttributeValue("val"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> value_real;
value_real = decoder.readUnsignedInteger(sla::ATTRIB_VAL);
}
else if (typestring=="handle") {
else if (el == sla::ELEM_CONST_HANDLE) {
type = handle;
istringstream s(el->getAttributeValue("val"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> value.handle_index;
select = readHandleSelector(el->getAttributeValue("s"));
value.handle_index = decoder.readSignedInteger(sla::ATTRIB_VAL);
uint4 selectInt = decoder.readSignedInteger(sla::ATTRIB_S);
if (selectInt > v_offset_plus)
throw DecoderError("Bad handle selector encoding");
select = (v_field)selectInt;
if (select == v_offset_plus) {
istringstream s2(el->getAttributeValue("plus"));
s2.unsetf(ios::dec | ios::hex | ios::oct);
s2 >> value_real;
value_real = decoder.readUnsignedInteger(sla::ATTRIB_PLUS);
}
}
else if (typestring=="start") {
else if (el == sla::ELEM_CONST_START) {
type = j_start;
}
else if (typestring=="next") {
else if (el == sla::ELEM_CONST_NEXT) {
type = j_next;
}
else if (typestring=="next2") {
else if (el == sla::ELEM_CONST_NEXT2) {
type = j_next2;
}
else if (typestring=="curspace") {
else if (el == sla::ELEM_CONST_CURSPACE) {
type = j_curspace;
}
else if (typestring=="curspace_size") {
else if (el == sla::ELEM_CONST_CURSPACE_SIZE) {
type = j_curspace_size;
}
else if (typestring=="spaceid") {
else if (el == sla::ELEM_CONST_SPACEID) {
type = spaceid;
value.spaceid = manage->getSpaceByName(el->getAttributeValue("name"));
value.spaceid = decoder.readSpace(sla::ATTRIB_SPACE);
}
else if (typestring=="relative") {
else if (el == sla::ELEM_CONST_RELATIVE) {
type = j_relative;
istringstream s(el->getAttributeValue("val"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> value_real;
value_real = decoder.readUnsignedInteger(sla::ATTRIB_VAL);
}
else if (typestring == "flowref") {
else if (el == sla::ELEM_CONST_FLOWREF) {
type = j_flowref;
}
else if (typestring == "flowref_size") {
else if (el == sla::ELEM_CONST_FLOWREF_SIZE) {
type = j_flowref_size;
}
else if (typestring == "flowdest") {
else if (el == sla::ELEM_CONST_FLOWDEST) {
type = j_flowdest;
}
else if (typestring == "flowdest_size") {
else if (el == sla::ELEM_CONST_FLOWDEST_SIZE) {
type = j_flowdest_size;
}
else
throw LowlevelError("Bad constant type");
decoder.closeElement(el);
}
VarnodeTpl::VarnodeTpl(int4 hand,bool zerosize) :
@ -544,27 +520,24 @@ bool VarnodeTpl::adjustTruncation(int4 sz,bool isbigendian)
return true;
}
void VarnodeTpl::saveXml(ostream &s) const
void VarnodeTpl::encode(Encoder &encoder) const
{
s << "<varnode_tpl>";
space.saveXml(s);
offset.saveXml(s);
size.saveXml(s);
s << "</varnode_tpl>\n";
encoder.openElement(sla::ELEM_VARNODE_TPL);
space.encode(encoder);
offset.encode(encoder);
size.encode(encoder);
encoder.closeElement(sla::ELEM_VARNODE_TPL);
}
void VarnodeTpl::restoreXml(const Element *el,const AddrSpaceManager *manage)
void VarnodeTpl::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
space.restoreXml(*iter,manage);
++iter;
offset.restoreXml(*iter,manage);
++iter;
size.restoreXml(*iter,manage);
uint4 el = decoder.openElement(sla::ELEM_VARNODE_TPL);
space.decode(decoder);
offset.decode(decoder);
size.decode(decoder);
decoder.closeElement(el);
}
bool VarnodeTpl::operator<(const VarnodeTpl &op2) const
@ -633,39 +606,32 @@ void HandleTpl::changeHandleIndex(const vector<int4> &handmap)
temp_offset.changeHandleIndex(handmap);
}
void HandleTpl::saveXml(ostream &s) const
void HandleTpl::encode(Encoder &encoder) const
{
s << "<handle_tpl>";
space.saveXml(s);
size.saveXml(s);
ptrspace.saveXml(s);
ptroffset.saveXml(s);
ptrsize.saveXml(s);
temp_space.saveXml(s);
temp_offset.saveXml(s);
s << "</handle_tpl>\n";
encoder.openElement(sla::ELEM_HANDLE_TPL);
space.encode(encoder);
size.encode(encoder);
ptrspace.encode(encoder);
ptroffset.encode(encoder);
ptrsize.encode(encoder);
temp_space.encode(encoder);
temp_offset.encode(encoder);
encoder.closeElement(sla::ELEM_HANDLE_TPL);
}
void HandleTpl::restoreXml(const Element *el,const AddrSpaceManager *manage)
void HandleTpl::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
space.restoreXml(*iter,manage);
++iter;
size.restoreXml(*iter,manage);
++iter;
ptrspace.restoreXml(*iter,manage);
++iter;
ptroffset.restoreXml(*iter,manage);
++iter;
ptrsize.restoreXml(*iter,manage);
++iter;
temp_space.restoreXml(*iter,manage);
++iter;
temp_offset.restoreXml(*iter,manage);
uint4 el = decoder.openElement(sla::ELEM_HANDLE_TPL);
space.decode(decoder);
size.decode(decoder);
ptrspace.decode(decoder);
ptroffset.decode(decoder);
ptrsize.decode(decoder);
temp_space.decode(decoder);
temp_offset.decode(decoder);
decoder.closeElement(el);
}
OpTpl::~OpTpl(void)
@ -710,39 +676,43 @@ void OpTpl::changeHandleIndex(const vector<int4> &handmap)
(*iter)->changeHandleIndex(handmap);
}
void OpTpl::saveXml(ostream &s) const
void OpTpl::encode(Encoder &encoder) const
{
s << "<op_tpl code=\"" << get_opname(opc) << "\">";
if (output == (VarnodeTpl *)0)
s << "<null/>\n";
encoder.openElement(sla::ELEM_OP_TPL);
encoder.writeOpcode(sla::ATTRIB_CODE, opc);
if (output == (VarnodeTpl *)0) {
encoder.openElement(sla::ELEM_NULL);
encoder.closeElement(sla::ELEM_NULL);
}
else
output->saveXml(s);
output->encode(encoder);
for(int4 i=0;i<input.size();++i)
input[i]->saveXml(s);
s << "</op_tpl>\n";
input[i]->encode(encoder);
encoder.closeElement(sla::ELEM_OP_TPL);
}
void OpTpl::restoreXml(const Element *el,const AddrSpaceManager *manage)
void OpTpl::decode(Decoder &decoder)
{
opc = get_opcode(el->getAttributeValue("code"));
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
if ((*iter)->getName() == "null")
uint4 el = decoder.openElement(sla::ELEM_OP_TPL);
opc = decoder.readOpcode(sla::ATTRIB_CODE);
uint4 subel = decoder.peekElement();
if (subel == sla::ELEM_NULL) {
decoder.openElement();
decoder.closeElement(subel);
output = (VarnodeTpl *)0;
}
else {
output = new VarnodeTpl();
output->restoreXml(*iter,manage);
output->decode(decoder);
}
++iter;
while(iter != list.end()) {
while(decoder.peekElement() != 0) {
VarnodeTpl *vn = new VarnodeTpl();
vn->restoreXml(*iter,manage);
vn->decode(decoder);
input.push_back(vn);
++iter;
}
decoder.closeElement(el);
}
ConstructTpl::~ConstructTpl(void)
@ -882,63 +852,61 @@ void ConstructTpl::deleteOps(const vector<int4> &indices)
vec.pop_back();
}
void ConstructTpl::saveXml(ostream &s,int4 sectionid) const
void ConstructTpl::encode(Encoder &encoder,int4 sectionid) const
{
s << "<construct_tpl";
encoder.openElement(sla::ELEM_CONSTRUCT_TPL);
if (sectionid >=0 )
s << " section=\"" << dec << sectionid << "\"";
encoder.writeSignedInteger(sla::ATTRIB_SECTION, sectionid);
if (delayslot != 0)
s << " delay=\"" << dec << delayslot << "\"";
encoder.writeSignedInteger(sla::ATTRIB_DELAY, delayslot);
if (numlabels != 0)
s << " labels=\"" << dec << numlabels << "\"";
s << ">\n";
encoder.writeSignedInteger(sla::ATTRIB_LABELS, numlabels);
if (result != (HandleTpl *)0)
result->saveXml(s);
else
s << "<null/>";
result->encode(encoder);
else {
encoder.openElement(sla::ELEM_NULL);
encoder.closeElement(sla::ELEM_NULL);
}
for(int4 i=0;i<vec.size();++i)
vec[i]->saveXml(s);
s << "</construct_tpl>\n";
vec[i]->encode(encoder);
encoder.closeElement(sla::ELEM_CONSTRUCT_TPL);
}
int4 ConstructTpl::restoreXml(const Element *el,const AddrSpaceManager *manage)
int4 ConstructTpl::decode(Decoder &decoder)
{
uint4 el = decoder.openElement(sla::ELEM_CONSTRUCT_TPL);
int4 sectionid = -1;
for(int4 i=0;i<el->getNumAttributes();++i) {
if (el->getAttributeName(i)=="delay") {
istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> delayslot;
uint4 attrib = decoder.getNextAttributeId();
while(attrib != 0) {
if (attrib == sla::ATTRIB_DELAY) {
delayslot = decoder.readSignedInteger();
}
else if (el->getAttributeName(i)=="labels") {
istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> numlabels;
else if (attrib == sla::ATTRIB_LABELS) {
numlabels = decoder.readSignedInteger();
}
else if (el->getAttributeName(i)=="section") {
istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> sectionid;
else if (attrib == sla::ATTRIB_SECTION) {
sectionid = decoder.readSignedInteger();
}
attrib = decoder.getNextAttributeId();
}
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
if ((*iter)->getName() == "null")
uint4 subel = decoder.peekElement();
if (subel == sla::ELEM_NULL) {
decoder.openElement();
decoder.closeElement(subel);
result = (HandleTpl *)0;
}
else {
result = new HandleTpl();
result->restoreXml(*iter,manage);
result->decode(decoder);
}
++iter;
while(iter != list.end()) {
while(decoder.peekElement() != 0) {
OpTpl *op = new OpTpl();
op->restoreXml(*iter,manage);
op->decode(decoder);
vec.push_back(op);
++iter;
}
decoder.closeElement(el);
return sectionid;
}

View file

@ -17,6 +17,7 @@
#define __SEMANTICS_HH__
#include "context.hh"
#include "slaformat.hh"
namespace ghidra {
@ -45,8 +46,6 @@ private:
} value;
uintb value_real;
v_field select; // Which part of handle to use as constant
static void printHandleSelector(ostream &s,v_field val);
static v_field readHandleSelector(const string &name);
public:
ConstTpl(void) { type = real; value_real = 0; }
ConstTpl(const ConstTpl &op2) {
@ -72,8 +71,8 @@ public:
void changeHandleIndex(const vector<int4> &handmap);
void fillinSpace(FixedHandle &hand,const ParserWalker &walker) const;
void fillinOffset(FixedHandle &hand,const ParserWalker &walker) const;
void saveXml(ostream &s) const;
void restoreXml(const Element *el,const AddrSpaceManager *manage);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder);
};
class VarnodeTpl {
@ -102,8 +101,8 @@ public:
bool isRelative(void) const { return (offset.getType() == ConstTpl::j_relative); }
void changeHandleIndex(const vector<int4> &handmap);
bool adjustTruncation(int4 sz,bool isbigendian);
void saveXml(ostream &s) const;
void restoreXml(const Element *el,const AddrSpaceManager *manage);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder);
};
class HandleTpl {
@ -132,8 +131,8 @@ public:
void setTempOffset(uintb val) { temp_offset = ConstTpl(ConstTpl::real,val); }
void fix(FixedHandle &hand,const ParserWalker &walker) const;
void changeHandleIndex(const vector<int4> &handmap);
void saveXml(ostream &s) const;
void restoreXml(const Element *el,const AddrSpaceManager *manage);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder);
};
class OpTpl {
@ -156,8 +155,8 @@ public:
void setInput(VarnodeTpl *vt,int4 slot) { input[slot] = vt; }
void removeInput(int4 index);
void changeHandleIndex(const vector<int4> &handmap);
void saveXml(ostream &s) const;
void restoreXml(const Element *el,const AddrSpaceManager *manage);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder);
};
class ConstructTpl {
@ -185,8 +184,8 @@ public:
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
void setOutput(VarnodeTpl *vn,int4 index);
void deleteOps(const vector<int4> &indices);
void saveXml(ostream &s,int4 sectionid) const;
int4 restoreXml(const Element *el,const AddrSpaceManager *manage);
void encode(Encoder &encoder,int4 sectionid) const;
int4 decode(Decoder &decoder);
};
class PcodeEmit; // Forward declaration for emitter

View file

@ -0,0 +1,258 @@
/* ###
* 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.
*/
#include "slaformat.hh"
namespace ghidra {
namespace sla {
const int4 FORMAT_SCOPE = 1;
const int4 FORMAT_VERSION = 4;
// ATTRIB_CONTEXT = 1 is reserved
AttributeId ATTRIB_VAL = AttributeId("val", 2, FORMAT_SCOPE);
AttributeId ATTRIB_ID = AttributeId("id", 3, FORMAT_SCOPE);
AttributeId ATTRIB_SPACE = AttributeId("space", 4, FORMAT_SCOPE);
AttributeId ATTRIB_S = AttributeId("s", 5, FORMAT_SCOPE);
AttributeId ATTRIB_OFF = AttributeId("off", 6, FORMAT_SCOPE);
AttributeId ATTRIB_CODE = AttributeId("code", 7, FORMAT_SCOPE);
AttributeId ATTRIB_MASK = AttributeId("mask", 8, FORMAT_SCOPE);
AttributeId ATTRIB_INDEX = AttributeId("index", 9, FORMAT_SCOPE);
AttributeId ATTRIB_NONZERO = AttributeId("nonzero", 10, FORMAT_SCOPE);
AttributeId ATTRIB_PIECE = AttributeId("piece", 11, FORMAT_SCOPE);
AttributeId ATTRIB_NAME = AttributeId("name", 12, FORMAT_SCOPE);
AttributeId ATTRIB_SCOPE = AttributeId("scope", 13, FORMAT_SCOPE);
AttributeId ATTRIB_STARTBIT = AttributeId("startbit", 14, FORMAT_SCOPE);
AttributeId ATTRIB_SIZE = AttributeId("size", 15, FORMAT_SCOPE);
AttributeId ATTRIB_TABLE = AttributeId("table", 16, FORMAT_SCOPE);
AttributeId ATTRIB_CT = AttributeId("ct", 17, FORMAT_SCOPE);
AttributeId ATTRIB_MINLEN = AttributeId("minlen", 18, FORMAT_SCOPE);
AttributeId ATTRIB_BASE = AttributeId("base", 19, FORMAT_SCOPE);
AttributeId ATTRIB_NUMBER = AttributeId("number", 20, FORMAT_SCOPE);
AttributeId ATTRIB_CONTEXT = AttributeId("context", 21, FORMAT_SCOPE);
AttributeId ATTRIB_PARENT = AttributeId("parent", 22, FORMAT_SCOPE);
AttributeId ATTRIB_SUBSYM = AttributeId("subsym", 23, FORMAT_SCOPE);
AttributeId ATTRIB_LINE = AttributeId("line", 24, FORMAT_SCOPE);
AttributeId ATTRIB_SOURCE = AttributeId("source", 25, FORMAT_SCOPE);
AttributeId ATTRIB_LENGTH = AttributeId("length", 26, FORMAT_SCOPE);
AttributeId ATTRIB_FIRST = AttributeId("first", 27, FORMAT_SCOPE);
AttributeId ATTRIB_PLUS = AttributeId("plus", 28, FORMAT_SCOPE);
AttributeId ATTRIB_SHIFT = AttributeId("shift", 29, FORMAT_SCOPE);
AttributeId ATTRIB_ENDBIT = AttributeId("endbit", 30, FORMAT_SCOPE);
AttributeId ATTRIB_SIGNBIT = AttributeId("signbit", 31, FORMAT_SCOPE);
AttributeId ATTRIB_ENDBYTE = AttributeId("endbyte", 32, FORMAT_SCOPE);
AttributeId ATTRIB_STARTBYTE = AttributeId("startbyte", 33, FORMAT_SCOPE);
AttributeId ATTRIB_VERSION = AttributeId("version", 34, FORMAT_SCOPE);
AttributeId ATTRIB_BIGENDIAN = AttributeId("bigendian", 35, FORMAT_SCOPE);
AttributeId ATTRIB_ALIGN = AttributeId("align", 36, FORMAT_SCOPE);
AttributeId ATTRIB_UNIQBASE = AttributeId("uniqbase", 37, FORMAT_SCOPE);
AttributeId ATTRIB_MAXDELAY = AttributeId("maxdelay", 38, FORMAT_SCOPE);
AttributeId ATTRIB_UNIQMASK = AttributeId("uniqmask", 39, FORMAT_SCOPE);
AttributeId ATTRIB_NUMSECTIONS = AttributeId("numsections", 40, FORMAT_SCOPE);
AttributeId ATTRIB_DEFAULTSPACE = AttributeId("defaultspace", 41, FORMAT_SCOPE);
AttributeId ATTRIB_DELAY = AttributeId("delay", 42, FORMAT_SCOPE);
AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize", 43, FORMAT_SCOPE);
AttributeId ATTRIB_PHYSICAL = AttributeId("physical", 44, FORMAT_SCOPE);
AttributeId ATTRIB_SCOPESIZE = AttributeId("scopesize", 45, FORMAT_SCOPE);
AttributeId ATTRIB_SYMBOLSIZE = AttributeId("symbolsize", 46, FORMAT_SCOPE);
AttributeId ATTRIB_VARNODE = AttributeId("varnode", 47, FORMAT_SCOPE);
AttributeId ATTRIB_LOW = AttributeId("low", 48, FORMAT_SCOPE);
AttributeId ATTRIB_HIGH = AttributeId("high", 49, FORMAT_SCOPE);
AttributeId ATTRIB_FLOW = AttributeId("flow", 50, FORMAT_SCOPE);
AttributeId ATTRIB_CONTAIN = AttributeId("contain", 51, FORMAT_SCOPE);
AttributeId ATTRIB_I = AttributeId("i", 52, FORMAT_SCOPE);
AttributeId ATTRIB_NUMCT = AttributeId("numct", 53, FORMAT_SCOPE);
AttributeId ATTRIB_SECTION = AttributeId("section", 54, FORMAT_SCOPE);
AttributeId ATTRIB_LABELS = AttributeId("labels", 55, FORMAT_SCOPE);
ElementId ELEM_CONST_REAL = ElementId("const_real", 1, FORMAT_SCOPE);
ElementId ELEM_VARNODE_TPL = ElementId("varnode_tpl", 2, FORMAT_SCOPE);
ElementId ELEM_CONST_SPACEID = ElementId("const_spaceid", 3, FORMAT_SCOPE);
ElementId ELEM_CONST_HANDLE = ElementId("const_handle", 4, FORMAT_SCOPE);
ElementId ELEM_OP_TPL = ElementId("op_tpl", 5, FORMAT_SCOPE);
ElementId ELEM_MASK_WORD = ElementId("mask_word", 6, FORMAT_SCOPE);
ElementId ELEM_PAT_BLOCK = ElementId("pat_block", 7, FORMAT_SCOPE);
ElementId ELEM_PRINT = ElementId("print", 8, FORMAT_SCOPE);
ElementId ELEM_PAIR = ElementId("pair", 9, FORMAT_SCOPE);
ElementId ELEM_CONTEXT_PAT = ElementId("context_pat", 10, FORMAT_SCOPE);
ElementId ELEM_NULL = ElementId("null", 11, FORMAT_SCOPE);
ElementId ELEM_OPERAND_EXP = ElementId("operand_exp", 12, FORMAT_SCOPE);
ElementId ELEM_OPERAND_SYM = ElementId("operand_sym", 13, FORMAT_SCOPE);
ElementId ELEM_OPERAND_SYM_HEAD = ElementId("operand_sym_head", 14, FORMAT_SCOPE);
ElementId ELEM_OPER = ElementId("oper", 15, FORMAT_SCOPE);
ElementId ELEM_DECISION = ElementId("decision", 16, FORMAT_SCOPE);
ElementId ELEM_OPPRINT = ElementId("opprint", 17, FORMAT_SCOPE);
ElementId ELEM_INSTRUCT_PAT = ElementId("instruct_pat", 18, FORMAT_SCOPE);
ElementId ELEM_COMBINE_PAT = ElementId("combine_pat", 19, FORMAT_SCOPE);
ElementId ELEM_CONSTRUCTOR = ElementId("constructor", 20, FORMAT_SCOPE);
ElementId ELEM_CONSTRUCT_TPL = ElementId("construct_tpl", 21, FORMAT_SCOPE);
ElementId ELEM_SCOPE = ElementId("scope", 22, FORMAT_SCOPE);
ElementId ELEM_VARNODE_SYM = ElementId("varnode_sym", 23, FORMAT_SCOPE);
ElementId ELEM_VARNODE_SYM_HEAD = ElementId("varnode_sym_head", 24, FORMAT_SCOPE);
ElementId ELEM_USEROP = ElementId("userop", 25, FORMAT_SCOPE);
ElementId ELEM_USEROP_HEAD = ElementId("userop_head", 26, FORMAT_SCOPE);
ElementId ELEM_TOKENFIELD = ElementId("tokenfield", 27, FORMAT_SCOPE);
ElementId ELEM_VAR = ElementId("var", 28, FORMAT_SCOPE);
ElementId ELEM_CONTEXTFIELD = ElementId("contextfield", 29, FORMAT_SCOPE);
ElementId ELEM_HANDLE_TPL = ElementId("handle_tpl", 30, FORMAT_SCOPE);
ElementId ELEM_CONST_RELATIVE = ElementId("const_relative", 31, FORMAT_SCOPE);
ElementId ELEM_CONTEXT_OP = ElementId("context_op", 32, FORMAT_SCOPE);
ElementId ELEM_SLEIGH = ElementId("sleigh", 33, FORMAT_SCOPE);
ElementId ELEM_SPACES = ElementId("spaces", 34, FORMAT_SCOPE);
ElementId ELEM_SOURCEFILES = ElementId("sourcefiles", 35, FORMAT_SCOPE);
ElementId ELEM_SOURCEFILE = ElementId("sourcefile", 36, FORMAT_SCOPE);
ElementId ELEM_SPACE = ElementId("space", 37, FORMAT_SCOPE);
ElementId ELEM_SYMBOL_TABLE = ElementId("symbol_table", 38, FORMAT_SCOPE);
ElementId ELEM_VALUE_SYM = ElementId("value_sym", 39, FORMAT_SCOPE);
ElementId ELEM_VALUE_SYM_HEAD = ElementId("value_sym_head", 40, FORMAT_SCOPE);
ElementId ELEM_CONTEXT_SYM = ElementId("context_sym", 41, FORMAT_SCOPE);
ElementId ELEM_CONTEXT_SYM_HEAD = ElementId("context_sym_head", 42, FORMAT_SCOPE);
ElementId ELEM_END_SYM = ElementId("end_sym", 43, FORMAT_SCOPE);
ElementId ELEM_END_SYM_HEAD = ElementId("end_sym_head", 44, FORMAT_SCOPE);
ElementId ELEM_SPACE_OTHER = ElementId("space_other", 45, FORMAT_SCOPE);
ElementId ELEM_SPACE_UNIQUE = ElementId("space_unique", 46, FORMAT_SCOPE);
ElementId ELEM_AND_EXP = ElementId("and_exp", 47, FORMAT_SCOPE);
ElementId ELEM_DIV_EXP = ElementId("div_exp", 48, FORMAT_SCOPE);
ElementId ELEM_LSHIFT_EXP = ElementId("lshift_exp", 49, FORMAT_SCOPE);
ElementId ELEM_MINUS_EXP = ElementId("minus_exp", 50, FORMAT_SCOPE);
ElementId ELEM_MULT_EXP = ElementId("mult_exp", 51, FORMAT_SCOPE);
ElementId ELEM_NOT_EXP = ElementId("not_exp", 52, FORMAT_SCOPE);
ElementId ELEM_OR_EXP = ElementId("or_exp", 53, FORMAT_SCOPE);
ElementId ELEM_PLUS_EXP = ElementId("plus_exp", 54, FORMAT_SCOPE);
ElementId ELEM_RSHIFT_EXP = ElementId("rshift_exp", 55, FORMAT_SCOPE);
ElementId ELEM_SUB_EXP = ElementId("sub_exp", 56, FORMAT_SCOPE);
ElementId ELEM_XOR_EXP = ElementId("xor_exp", 57, FORMAT_SCOPE);
ElementId ELEM_INTB = ElementId("intb", 58, FORMAT_SCOPE);
ElementId ELEM_END_EXP = ElementId("end_exp", 59, FORMAT_SCOPE);
ElementId ELEM_NEXT2_EXP = ElementId("next2_exp", 60, FORMAT_SCOPE);
ElementId ELEM_START_EXP = ElementId("start_exp", 61, FORMAT_SCOPE);
ElementId ELEM_EPSILON_SYM = ElementId("epsilon_sym", 62, FORMAT_SCOPE);
ElementId ELEM_EPSILON_SYM_HEAD = ElementId("epsilon_sym_head", 63, FORMAT_SCOPE);
ElementId ELEM_NAME_SYM = ElementId("name_sym", 64, FORMAT_SCOPE);
ElementId ELEM_NAME_SYM_HEAD = ElementId("name_sym_head", 65, FORMAT_SCOPE);
ElementId ELEM_NAMETAB = ElementId("nametab", 66, FORMAT_SCOPE);
ElementId ELEM_NEXT2_SYM = ElementId("next2_sym", 67, FORMAT_SCOPE);
ElementId ELEM_NEXT2_SYM_HEAD = ElementId("next2_sym_head", 68, FORMAT_SCOPE);
ElementId ELEM_START_SYM = ElementId("start_sym", 69, FORMAT_SCOPE);
ElementId ELEM_START_SYM_HEAD = ElementId("start_sym_head", 70, FORMAT_SCOPE);
ElementId ELEM_SUBTABLE_SYM = ElementId("subtable_sym", 71, FORMAT_SCOPE);
ElementId ELEM_SUBTABLE_SYM_HEAD = ElementId("subtable_sym_head", 72, FORMAT_SCOPE);
ElementId ELEM_VALUEMAP_SYM = ElementId("valuemap_sym", 73, FORMAT_SCOPE);
ElementId ELEM_VALUEMAP_SYM_HEAD = ElementId("valuemap_sym_head", 74, FORMAT_SCOPE);
ElementId ELEM_VALUETAB = ElementId("valuetab", 75, FORMAT_SCOPE);
ElementId ELEM_VARLIST_SYM = ElementId("varlist_sym", 76, FORMAT_SCOPE);
ElementId ELEM_VARLIST_SYM_HEAD = ElementId("varlist_sym_head", 77, FORMAT_SCOPE);
ElementId ELEM_OR_PAT = ElementId("or_pat", 78, FORMAT_SCOPE);
ElementId ELEM_COMMIT = ElementId("commit", 79, FORMAT_SCOPE);
ElementId ELEM_CONST_START = ElementId("const_start", 80, FORMAT_SCOPE);
ElementId ELEM_CONST_NEXT = ElementId("const_next", 81, FORMAT_SCOPE);
ElementId ELEM_CONST_NEXT2 = ElementId("const_next2", 82, FORMAT_SCOPE);
ElementId ELEM_CONST_CURSPACE = ElementId("const_curspace", 83, FORMAT_SCOPE);
ElementId ELEM_CONST_CURSPACE_SIZE = ElementId("const_curspace_size", 84, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWREF = ElementId("const_flowref", 85, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWREF_SIZE = ElementId("const_flowref_size", 86, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWDEST = ElementId("const_flowdest", 87, FORMAT_SCOPE);
ElementId ELEM_CONST_FLOWDEST_SIZE = ElementId("const_flowdest_size", 88, FORMAT_SCOPE);
/// The bytes of the header are read from the stream and verified against the required form and current version.
/// If the form matches, \b true is returned. No additional bytes are read.
/// \param s is the given stream
/// \return \b true if a valid header is present
bool isSlaFormat(istream &s)
{
uint1 header[4];
s.read((char *)header,4);
if (!s)
return false;
if (header[0] != 's' || header[1] != 'l' || header[2] != 'a')
return false;
if (header[3] != FORMAT_VERSION)
return false;
return true;
}
/// A valid header, including the format version number, is written to the stream.
/// \param s is the given stream
void writeSlaHeader(ostream &s)
{
char header[4];
header[0] = 's';
header[1] = 'l';
header[2] = 'a';
header[3] = FORMAT_VERSION;
s.write(header,4);
}
/// \param s is the backing stream that will receive the final bytes of the .sla file
/// \param level is the compression level
FormatEncode::FormatEncode(ostream &s,int4 level)
: PackedEncode(compStream), compBuffer(s,level), compStream(&compBuffer)
{
writeSlaHeader(s);
}
void FormatEncode::flush(void)
{
compStream.flush();
}
const int4 FormatDecode::IN_BUFFER_SIZE = 4096;
/// \param spcManager is the (uninitialized) manager that will hold decoded address spaces
FormatDecode::FormatDecode(const AddrSpaceManager *spcManager)
: PackedDecode(spcManager)
{
inBuffer = new uint1[IN_BUFFER_SIZE];
}
FormatDecode::~FormatDecode(void)
{
delete [] inBuffer;
}
void FormatDecode::ingestStream(istream &s)
{
if (!isSlaFormat(s))
throw LowlevelError("Missing SLA format header");
Decompress decompressor;
uint1 *outBuf;
int4 outAvail = 0;
while(!decompressor.isFinished()) {
s.read((char *)inBuffer,IN_BUFFER_SIZE);
int4 gcount = s.gcount();
if (gcount == 0)
break;
decompressor.input(inBuffer,gcount);
do {
if (outAvail == 0) {
outBuf = allocateNextInputBuffer(0);
outAvail = BUFFER_SIZE;
}
outAvail = decompressor.inflate(outBuf + (BUFFER_SIZE - outAvail), outAvail);
} while(outAvail == 0);
}
endIngest(BUFFER_SIZE - outAvail);
}
} // End sla namespace
} // End ghidra namespace

View file

@ -0,0 +1,205 @@
/* ###
* 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.
*/
/// \file slaformat.hh
/// \brief Encoding values for the SLA file format
#ifndef __SLAFORMAT__
#define __SLAFORMAT__
#include "compression.hh"
#include "marshal.hh"
namespace ghidra {
namespace sla {
extern const int4 FORMAT_SCOPE; ///< Grouping elements/attributes for SLA file format
extern const int4 FORMAT_VERSION; ///< Current version of the .sla file
extern AttributeId ATTRIB_VAL; ///< SLA format attribute "val"
extern AttributeId ATTRIB_ID; ///< SLA format attribute "id"
extern AttributeId ATTRIB_SPACE; ///< SLA format attribute "space"
extern AttributeId ATTRIB_S; ///< SLA format attribute "s"
extern AttributeId ATTRIB_OFF; ///< SLA format attribute "off"
extern AttributeId ATTRIB_CODE; ///< SLA format attribute "code"
extern AttributeId ATTRIB_MASK; ///< SLA format attribute "mask"
extern AttributeId ATTRIB_INDEX; ///< SLA format attribute "index"
extern AttributeId ATTRIB_NONZERO; ///< SLA format attribute "nonzero"
extern AttributeId ATTRIB_PIECE; ///< SLA format attribute "piece"
extern AttributeId ATTRIB_NAME; ///< SLA format attribute "name"
extern AttributeId ATTRIB_SCOPE; ///< SLA format attribute "scope"
extern AttributeId ATTRIB_STARTBIT; ///< SLA format attribute "startbit"
extern AttributeId ATTRIB_SIZE; ///< SLA format attribute "size"
extern AttributeId ATTRIB_TABLE; ///< SLA format attribute "table"
extern AttributeId ATTRIB_CT; ///< SLA format attribute "ct"
extern AttributeId ATTRIB_MINLEN; ///< SLA format attribute "minlen"
extern AttributeId ATTRIB_BASE; ///< SLA format attribute "base"
extern AttributeId ATTRIB_NUMBER; ///< SLA format attribute "number"
extern AttributeId ATTRIB_CONTEXT; ///< SLA format attribute "context"
extern AttributeId ATTRIB_PARENT; ///< SLA format attribute "parent"
extern AttributeId ATTRIB_SUBSYM; ///< SLA format attribute "subsym"
extern AttributeId ATTRIB_LINE; ///< SLA format attribute "line"
extern AttributeId ATTRIB_SOURCE; ///< SLA format attribute "source"
extern AttributeId ATTRIB_LENGTH; ///< SLA format attribute "length"
extern AttributeId ATTRIB_FIRST; ///< SLA format attribute "first"
extern AttributeId ATTRIB_PLUS; ///< SLA format attribute "plus"
extern AttributeId ATTRIB_SHIFT; ///< SLA format attribute "shift"
extern AttributeId ATTRIB_ENDBIT; ///< SLA format attribute "endbit"
extern AttributeId ATTRIB_SIGNBIT; ///< SLA format attribute "signbit"
extern AttributeId ATTRIB_ENDBYTE; ///< SLA format attribute "endbyte"
extern AttributeId ATTRIB_STARTBYTE; ///< SLA format attribute "startbyte"
extern AttributeId ATTRIB_VERSION; ///< SLA format attribute "version"
extern AttributeId ATTRIB_BIGENDIAN; ///< SLA format attribute "bigendian"
extern AttributeId ATTRIB_ALIGN; ///< SLA format attribute "align"
extern AttributeId ATTRIB_UNIQBASE; ///< SLA format attribute "uniqbase"
extern AttributeId ATTRIB_MAXDELAY; ///< SLA format attribute "maxdelay"
extern AttributeId ATTRIB_UNIQMASK; ///< SLA format attribute "uniqmask"
extern AttributeId ATTRIB_NUMSECTIONS; ///< SLA format attribute "numsections"
extern AttributeId ATTRIB_DEFAULTSPACE; ///< SLA format attribute "defaultspace"
extern AttributeId ATTRIB_DELAY; ///< SLA format attribute "delay"
extern AttributeId ATTRIB_WORDSIZE; ///< SLA format attribute "wordsize"
extern AttributeId ATTRIB_PHYSICAL; ///< SLA format attribute "physical"
extern AttributeId ATTRIB_SCOPESIZE; ///< SLA format attribute "scopesize"
extern AttributeId ATTRIB_SYMBOLSIZE; ///< SLA format attribute "symbolsize"
extern AttributeId ATTRIB_VARNODE; ///< SLA format attribute "varnode"
extern AttributeId ATTRIB_LOW; ///< SLA format attribute "low"
extern AttributeId ATTRIB_HIGH; ///< SLA format attribute "high"
extern AttributeId ATTRIB_FLOW; ///< SLA format attribute "flow"
extern AttributeId ATTRIB_CONTAIN; ///< SLA format attribute "contain"
extern AttributeId ATTRIB_I; ///< SLA format attribute "i"
extern AttributeId ATTRIB_NUMCT; ///< SLA format attribute "numct"
extern AttributeId ATTRIB_SECTION; ///< SLA format attribute "section"
extern AttributeId ATTRIB_LABELS; ///< SLA format attribute "labels"
extern ElementId ELEM_CONST_REAL; ///< SLA format element "const_real"
extern ElementId ELEM_VARNODE_TPL; ///< SLA format element "varnode_tpl"
extern ElementId ELEM_CONST_SPACEID; ///< SLA format element "const_spaceid"
extern ElementId ELEM_CONST_HANDLE; ///< SLA format element "const_handle"
extern ElementId ELEM_OP_TPL; ///< SLA format element "op_tpl"
extern ElementId ELEM_MASK_WORD; ///< SLA format element "mask_word"
extern ElementId ELEM_PAT_BLOCK; ///< SLA format element "pat_block"
extern ElementId ELEM_PRINT; ///< SLA format element "print"
extern ElementId ELEM_PAIR; ///< SLA format element "pair"
extern ElementId ELEM_CONTEXT_PAT; ///< SLA format element "context_pat"
extern ElementId ELEM_NULL; ///< SLA format element "null"
extern ElementId ELEM_OPERAND_EXP; ///< SLA format element "operand_exp"
extern ElementId ELEM_OPERAND_SYM; ///< SLA format element "operand_sym"
extern ElementId ELEM_OPERAND_SYM_HEAD; ///< SLA format element "operand_sym_head"
extern ElementId ELEM_OPER; ///< SLA format element "oper"
extern ElementId ELEM_DECISION; ///< SLA format element "decision"
extern ElementId ELEM_OPPRINT; ///< SLA format element "opprint"
extern ElementId ELEM_INSTRUCT_PAT; ///< SLA format element "instruct_pat"
extern ElementId ELEM_COMBINE_PAT; ///< SLA format element "combine_pat"
extern ElementId ELEM_CONSTRUCTOR; ///< SLA format element "constructor"
extern ElementId ELEM_CONSTRUCT_TPL; ///< SLA format element "construct_tpl"
extern ElementId ELEM_SCOPE; ///< SLA format element "scope"
extern ElementId ELEM_VARNODE_SYM; ///< SLA format element "varnode_sym"
extern ElementId ELEM_VARNODE_SYM_HEAD; ///< SLA format element "varnode_sym_head"
extern ElementId ELEM_USEROP; ///< SLA format element "userop"
extern ElementId ELEM_USEROP_HEAD; ///< SLA format element "userop_head"
extern ElementId ELEM_TOKENFIELD; ///< SLA format element "tokenfield"
extern ElementId ELEM_VAR; ///< SLA format element "var"
extern ElementId ELEM_CONTEXTFIELD; ///< SLA format element "contextfield"
extern ElementId ELEM_HANDLE_TPL; ///< SLA format element "handle_tpl"
extern ElementId ELEM_CONST_RELATIVE; ///< SLA format element "const_relative"
extern ElementId ELEM_CONTEXT_OP; ///< SLA format element "context_op"
extern ElementId ELEM_SLEIGH; ///< SLA format element "sleigh"
extern ElementId ELEM_SPACES; ///< SLA format element "spaces"
extern ElementId ELEM_SOURCEFILES; ///< SLA format element "sourcefiles"
extern ElementId ELEM_SOURCEFILE; ///< SLA format element "sourcefile"
extern ElementId ELEM_SPACE; ///< SLA format element "space"
extern ElementId ELEM_SYMBOL_TABLE; ///< SLA format element "symbol_table"
extern ElementId ELEM_VALUE_SYM; ///< SLA format element "value_sym"
extern ElementId ELEM_VALUE_SYM_HEAD; ///< SLA format element "value_sym_head"
extern ElementId ELEM_CONTEXT_SYM; ///< SLA format element "context_sym"
extern ElementId ELEM_CONTEXT_SYM_HEAD; ///< SLA format element "context_sym_head"
extern ElementId ELEM_END_SYM; ///< SLA format element "end_sym"
extern ElementId ELEM_END_SYM_HEAD; ///< SLA format element "end_sym_head"
extern ElementId ELEM_SPACE_OTHER; ///< SLA format element "space_other"
extern ElementId ELEM_SPACE_UNIQUE; ///< SLA format element "space_unique"
extern ElementId ELEM_AND_EXP; ///< SLA format element "and_exp"
extern ElementId ELEM_DIV_EXP; ///< SLA format element "div_exp"
extern ElementId ELEM_LSHIFT_EXP; ///< SLA format element "lshift_exp"
extern ElementId ELEM_MINUS_EXP; ///< SLA format element "minus_exp"
extern ElementId ELEM_MULT_EXP; ///< SLA format element "mult_exp"
extern ElementId ELEM_NOT_EXP; ///< SLA format element "not_exp"
extern ElementId ELEM_OR_EXP; ///< SLA format element "or_exp"
extern ElementId ELEM_PLUS_EXP; ///< SLA format element "plus_exp"
extern ElementId ELEM_RSHIFT_EXP; ///< SLA format element "rshift_exp"
extern ElementId ELEM_SUB_EXP; ///< SLA format element "sub_exp"
extern ElementId ELEM_XOR_EXP; ///< SLA format element "xor_exp"
extern ElementId ELEM_INTB; ///< SLA format element "intb"
extern ElementId ELEM_END_EXP; ///< SLA format element "end_exp"
extern ElementId ELEM_NEXT2_EXP; ///< SLA format element "next2_exp"
extern ElementId ELEM_START_EXP; ///< SLA format element "start_exp"
extern ElementId ELEM_EPSILON_SYM; ///< SLA format element "epsilon_sym"
extern ElementId ELEM_EPSILON_SYM_HEAD; ///< SLA format element "epsilon_sym_head"
extern ElementId ELEM_NAME_SYM; ///< SLA format element "name_sym"
extern ElementId ELEM_NAME_SYM_HEAD; ///< SLA format element "name_sym_head"
extern ElementId ELEM_NAMETAB; ///< SLA format element "nametab"
extern ElementId ELEM_NEXT2_SYM; ///< SLA format element "next2_sym"
extern ElementId ELEM_NEXT2_SYM_HEAD; ///< SLA format element "next2_sym_head"
extern ElementId ELEM_START_SYM; ///< SLA format element "start_sym"
extern ElementId ELEM_START_SYM_HEAD; ///< SLA format element "start_sym_head"
extern ElementId ELEM_SUBTABLE_SYM; ///< SLA format element "subtable_sym"
extern ElementId ELEM_SUBTABLE_SYM_HEAD; ///< SLA format element "subtable_sym_head"
extern ElementId ELEM_VALUEMAP_SYM; ///< SLA format element "valuemap_sym"
extern ElementId ELEM_VALUEMAP_SYM_HEAD; ///< SLA format element "valuemap_sym_head"
extern ElementId ELEM_VALUETAB; ///< SLA format element "valuetab"
extern ElementId ELEM_VARLIST_SYM; ///< SLA format element "varlist_sym"
extern ElementId ELEM_VARLIST_SYM_HEAD; ///< SLA format element "varlist_sym_head"
extern ElementId ELEM_OR_PAT; ///< SLA format element "or_pat"
extern ElementId ELEM_COMMIT; ///< SLA format element "commit"
extern ElementId ELEM_CONST_START; ///< SLA format element "const_start"
extern ElementId ELEM_CONST_NEXT; ///< SLA format element "const_next"
extern ElementId ELEM_CONST_NEXT2; ///< SLA format element "const_next2"
extern ElementId ELEM_CONST_CURSPACE; ///< SLA format element "curspace"
extern ElementId ELEM_CONST_CURSPACE_SIZE; ///< SLA format element "curspace_size"
extern ElementId ELEM_CONST_FLOWREF; ///< SLA format element "const_flowref"
extern ElementId ELEM_CONST_FLOWREF_SIZE; ///< SLA format element "const_flowref_size"
extern ElementId ELEM_CONST_FLOWDEST; ///< SLA format element "const_flowdest"
extern ElementId ELEM_CONST_FLOWDEST_SIZE; ///< SLA format element "const_flowdest_size"
extern bool isSlaFormat(istream &s); ///< Verify a .sla file header at the current point of the given stream
extern void writeSlaHeader(ostream &s); ///< Write a .sla file header to the given stream
/// \brief The encoder for the .sla file format
///
/// This provides the format header, does compression, and encodes the raw data elements/attributes.
class FormatEncode : public PackedEncode {
CompressBuffer compBuffer; ///< The compression stream filter
ostream compStream; ///< The front-end stream receiving uncompressed bytes
public:
FormatEncode(ostream &s,int4 level); ///< Initialize an encoder at a specific compression level
void flush(void); ///< Flush any buffered bytes in the encoder to the backing stream
};
/// \brief The decoder for the .sla file format
///
/// This verifies the .sla file header, does decompression, and decodes the raw data elements/attributes.
class FormatDecode : public PackedDecode {
static const int4 IN_BUFFER_SIZE; ///< The size of the \e input buffer
uint1 *inBuffer; ///< The \e input buffer
public:
FormatDecode(const AddrSpaceManager *spcManager); ///< Initialize the decoder
virtual ~FormatDecode(void); ///< Destructor
virtual void ingestStream(istream &s);
};
} // End namespace sla
} // End namespace ghidra
#endif

View file

@ -559,7 +559,13 @@ void Sleigh::initialize(DocumentStorage &store)
const Element *el = store.getTag("sleigh");
if (el == (const Element *)0)
throw LowlevelError("Could not find sleigh tag");
restoreXml(el);
sla::FormatDecode decoder(this);
ifstream s(el->getContent());
if (!s)
throw LowlevelError("Could not open .sla file: " + el->getContent());
decoder.ingestStream(s);
s.close();
decode(decoder);
}
else
reregisterContext();

View file

@ -356,8 +356,11 @@ void SleighArchitecture::buildSpecFile(DocumentStorage &store)
specpaths.findFile(processorfile,language.getProcessorSpec());
specpaths.findFile(compilerfile,compilertag.getSpec());
if (!language_reuse)
if (!language_reuse) {
specpaths.findFile(slafile,language.getSlaFile());
if (slafile.empty())
throw SleighError("Could not find .sla file for " + archid);
}
try {
Document *doc = store.openDocument(processorfile);
@ -394,16 +397,11 @@ void SleighArchitecture::buildSpecFile(DocumentStorage &store)
}
if (!language_reuse) {
istringstream s("<sleigh>" + slafile + "</sleigh>");
try {
Document *doc = store.openDocument(slafile);
Document *doc = store.parseDocument(s);
store.registerTag(doc->getRoot());
}
catch(DecoderError &err) {
ostringstream serr;
serr << "XML error parsing SLEIGH file: " << slafile;
serr << "\n " << err.explain;
throw SleighError(serr.str());
}
catch(LowlevelError &err) {
ostringstream serr;
serr << "Error reading SLEIGH file: " << slafile;

View file

@ -17,8 +17,6 @@
namespace ghidra {
const int4 SleighBase::SLA_FORMAT_VERSION = 3;
const uint4 SleighBase::MAX_UNIQUE_SIZE = 128;
int4 SourceFileIndexer::index(const string filename){
@ -39,26 +37,32 @@ string SourceFileIndexer::getFilename(int4 index){
return indexToFile[index];
}
void SourceFileIndexer::restoreXml(const Element *el){
const List &sourceFiles(el->getChildren());
List::const_iterator iter = sourceFiles.begin();
for (; iter != sourceFiles.end(); ++iter){
string filename = (*iter)->getAttributeValue("name");
int4 index = stoi((*iter)->getAttributeValue("index"),NULL,10);
fileToIndex[filename] = index;
indexToFile[index] = filename;
}
void SourceFileIndexer::decode(Decoder &decoder)
{
uint4 el = decoder.openElement(sla::ELEM_SOURCEFILES);
while(decoder.peekElement() == sla::ELEM_SOURCEFILE) {
int4 subel = decoder.openElement();
string filename = decoder.readString(sla::ATTRIB_NAME);
int4 index = decoder.readSignedInteger(sla::ATTRIB_INDEX);
decoder.closeElement(subel);
fileToIndex[filename] = index;
indexToFile[index] = filename;
}
decoder.closeElement(el);
}
void SourceFileIndexer::saveXml(ostream& s) const {
s << "<sourcefiles>\n";
for (int4 i = 0; i < leastUnusedIndex; ++i){
s << ("<sourcefile name=\"");
const char *str = indexToFile.at(i).c_str();
xml_escape(s,str);
s << "\" index=\"" << dec << i << "\"/>\n";
}
s << "</sourcefiles>\n";
void SourceFileIndexer::encode(Encoder &encoder) const
{
encoder.openElement(sla::ELEM_SOURCEFILES);
for (int4 i = 0; i < leastUnusedIndex; ++i){
encoder.openElement(sla::ELEM_SOURCEFILE);
encoder.writeString(sla::ATTRIB_NAME, indexToFile.at(i));
encoder.writeSignedInteger(sla::ATTRIB_INDEX, i);
encoder.closeElement(sla::ELEM_SOURCEFILE);
}
encoder.closeElement(sla::ELEM_SOURCEFILES);
}
SleighBase::SleighBase(void)
@ -175,27 +179,55 @@ void SleighBase::getUserOpNames(vector<string> &res) const
res = userop; // Return list of all language defined user ops (with index)
}
/// This does the bulk of the work of creating a .sla file
/// \param s is the output stream
void SleighBase::saveXml(ostream &s) const
/// Write a tag fully describing the details of the space.
/// \param encoder is the stream being written
/// \param spc is the given address space
void SleighBase::encodeSlaSpace(Encoder &encoder,AddrSpace *spc) const
{
s << "<sleigh";
a_v_i(s,"version",SLA_FORMAT_VERSION);
a_v_b(s,"bigendian",isBigEndian());
a_v_i(s,"align",alignment);
a_v_u(s,"uniqbase",getUniqueBase());
if (spc->getType() == IPTR_INTERNAL)
encoder.openElement(sla::ELEM_SPACE_UNIQUE);
else if (spc->isOtherSpace())
encoder.openElement(sla::ELEM_SPACE_OTHER);
else
encoder.openElement(sla::ELEM_SPACE);
encoder.writeString(sla::ATTRIB_NAME,spc->getName());
encoder.writeSignedInteger(sla::ATTRIB_INDEX, spc->getIndex());
encoder.writeBool(sla::ATTRIB_BIGENDIAN, isBigEndian());
encoder.writeSignedInteger(sla::ATTRIB_DELAY, spc->getDelay());
// if (spc->getDelay() != spc->getDeadcodeDelay())
// encoder.writeSignedInteger(sla::ATTRIB_DEADCODEDELAY, spc->getDeadcodeDelay());
encoder.writeSignedInteger(sla::ATTRIB_SIZE, spc->getAddrSize());
if (spc->getWordSize() > 1)
encoder.writeSignedInteger(sla::ATTRIB_WORDSIZE, spc->getWordSize());
encoder.writeBool(sla::ATTRIB_PHYSICAL, spc->hasPhysical());
if (spc->getType() == IPTR_INTERNAL)
encoder.closeElement(sla::ELEM_SPACE_UNIQUE);
else if (spc->isOtherSpace())
encoder.closeElement(sla::ELEM_SPACE_OTHER);
else
encoder.closeElement(sla::ELEM_SPACE);
}
/// This does the bulk of the work of creating a .sla file
/// \param encoder is the stream encoder
void SleighBase::encode(Encoder &encoder) const
{
encoder.openElement(sla::ELEM_SLEIGH);
encoder.writeSignedInteger(sla::ATTRIB_VERSION, sla::FORMAT_VERSION);
encoder.writeBool(sla::ATTRIB_BIGENDIAN, isBigEndian());
encoder.writeSignedInteger(sla::ATTRIB_ALIGN, alignment);
encoder.writeUnsignedInteger(sla::ATTRIB_UNIQBASE, getUniqueBase());
if (maxdelayslotbytes > 0)
a_v_u(s,"maxdelay",maxdelayslotbytes);
encoder.writeUnsignedInteger(sla::ATTRIB_MAXDELAY, maxdelayslotbytes);
if (unique_allocatemask != 0)
a_v_u(s,"uniqmask",unique_allocatemask);
encoder.writeUnsignedInteger(sla::ATTRIB_UNIQMASK, unique_allocatemask);
if (numSections != 0)
a_v_u(s,"numsections",numSections);
s << ">\n";
indexer.saveXml(s);
s << "<spaces";
a_v(s,"defaultspace",getDefaultCodeSpace()->getName());
s << ">\n";
encoder.writeUnsignedInteger(sla::ATTRIB_NUMSECTIONS, numSections);
indexer.encode(encoder);
encoder.openElement(sla::ELEM_SPACES);
encoder.writeString(sla::ATTRIB_DEFAULTSPACE, getDefaultCodeSpace()->getName());
for(int4 i=0;i<numSpaces();++i) {
AddrSpace *spc = getSpace(i);
if (spc == (AddrSpace *)0) continue;
@ -204,76 +236,129 @@ void SleighBase::saveXml(ostream &s) const
(spc->getType()==IPTR_IOP)||
(spc->getType()==IPTR_JOIN))
continue;
spc->saveXml(s);
encodeSlaSpace(encoder,spc);
}
s << "</spaces>\n";
symtab.saveXml(s);
s << "</sleigh>\n";
encoder.closeElement(sla::ELEM_SPACES);
symtab.encode(encoder);
encoder.closeElement(sla::ELEM_SLEIGH);
}
/// This is identical to the functionality of decodeSpace, but the AddrSpace information is stored
/// in the .sla file format.
/// \param decoder is the stream decoder
/// \param trans is the translator object to be associated with the new space
/// \return a pointer to the initialized AddrSpace
AddrSpace *SleighBase::decodeSlaSpace(Decoder &decoder,const Translate *trans)
{
uint4 elemId = decoder.openElement();
AddrSpace *res;
int4 index = 0;
int4 addressSize = 0;
int4 delay = -1;
int4 deadcodedelay = -1;
string name;
int4 wordsize = 1;
bool bigEnd = false;
uint4 flags = 0;
for (;;) {
uint4 attribId = decoder.getNextAttributeId();
if (attribId == 0) break;
if (attribId == sla::ATTRIB_NAME) {
name = decoder.readString();
}
if (attribId == sla::ATTRIB_INDEX)
index = decoder.readSignedInteger();
else if (attribId == sla::ATTRIB_SIZE)
addressSize = decoder.readSignedInteger();
else if (attribId == sla::ATTRIB_WORDSIZE)
wordsize = decoder.readUnsignedInteger();
else if (attribId == sla::ATTRIB_BIGENDIAN) {
bigEnd = decoder.readBool();
}
else if (attribId == sla::ATTRIB_DELAY)
delay = decoder.readSignedInteger();
else if (attribId == sla::ATTRIB_PHYSICAL) {
if (decoder.readBool())
flags |= AddrSpace::hasphysical;
}
}
decoder.closeElement(elemId);
if (deadcodedelay == -1)
deadcodedelay = delay; // If deadcodedelay attribute not present, set it to delay
if (index == 0)
throw LowlevelError("Expecting index attribute");
if (elemId == sla::ELEM_SPACE_UNIQUE)
res = new UniqueSpace(this,trans,index,flags);
else if (elemId == sla::ELEM_SPACE_OTHER)
res = new OtherSpace(this,trans,index);
else {
if (addressSize == 0 || delay == -1 || name.size() == 0)
throw LowlevelError("Expecting size/delay/name attributes");
res = new AddrSpace(this,trans,IPTR_PROCESSOR,name,bigEnd,addressSize,wordsize,index,flags,delay,deadcodedelay);
}
return res;
}
/// This is identical in functionality to decodeSpaces but the AddrSpace information
/// is stored in the .sla file format.
/// \param decoder is the stream decoder
/// \param trans is the processor translator to be associated with the spaces
void SleighBase::decodeSlaSpaces(Decoder &decoder,const Translate *trans)
{
// The first space should always be the constant space
insertSpace(new ConstantSpace(this,trans));
uint4 elemId = decoder.openElement(sla::ELEM_SPACES);
string defname = decoder.readString(sla::ATTRIB_DEFAULTSPACE);
while(decoder.peekElement() != 0) {
AddrSpace *spc = decodeSlaSpace(decoder,trans);
insertSpace(spc);
}
decoder.closeElement(elemId);
AddrSpace *spc = getSpaceByName(defname);
if (spc == (AddrSpace *)0)
throw LowlevelError("Bad 'defaultspace' attribute: "+defname);
setDefaultCodeSpace(spc->getIndex());
}
/// This parses the main \<sleigh> tag (from a .sla file), which includes the description
/// of address spaces and the symbol table, with its associated decoding tables
/// \param el is the root XML element
void SleighBase::restoreXml(const Element *el)
/// \param decoder is the stream to decode
void SleighBase::decode(Decoder &decoder)
{
maxdelayslotbytes = 0;
unique_allocatemask = 0;
numSections = 0;
int4 version = 0;
setBigEndian(xml_readbool(el->getAttributeValue("bigendian")));
{
istringstream s(el->getAttributeValue("align"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> alignment;
uint4 el = decoder.openElement(sla::ELEM_SLEIGH);
uint4 attrib = decoder.getNextAttributeId();
while(attrib != 0) {
if (attrib == sla::ATTRIB_BIGENDIAN)
setBigEndian(decoder.readBool());
else if (attrib == sla::ATTRIB_ALIGN)
alignment = decoder.readSignedInteger();
else if (attrib == sla::ATTRIB_UNIQBASE)
setUniqueBase(decoder.readUnsignedInteger());
else if (attrib == sla::ATTRIB_MAXDELAY)
maxdelayslotbytes = decoder.readUnsignedInteger();
else if (attrib == sla::ATTRIB_UNIQMASK)
unique_allocatemask = decoder.readUnsignedInteger();
else if (attrib == sla::ATTRIB_NUMSECTIONS)
numSections = decoder.readUnsignedInteger();
else if (attrib == sla::ATTRIB_VERSION)
version = decoder.readSignedInteger();
attrib = decoder.getNextAttributeId();
}
{
istringstream s(el->getAttributeValue("uniqbase"));
s.unsetf(ios::dec | ios::hex | ios::oct);
uintm ubase;
s >> ubase;
setUniqueBase(ubase);
}
int4 numattr = el->getNumAttributes();
for(int4 i=0;i<numattr;++i) {
const string &attrname( el->getAttributeName(i) );
if (attrname == "maxdelay") {
istringstream s1(el->getAttributeValue(i));
s1.unsetf(ios::dec | ios::hex | ios::oct);
s1 >> maxdelayslotbytes;
}
else if (attrname == "uniqmask") {
istringstream s2(el->getAttributeValue(i));
s2.unsetf(ios::dec | ios::hex | ios::oct);
s2 >> unique_allocatemask;
}
else if (attrname == "numsections") {
istringstream s3(el->getAttributeValue(i));
s3.unsetf(ios::dec | ios::hex | ios::oct);
s3 >> numSections;
}
else if (attrname == "version") {
istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> version;
}
}
if (version != SLA_FORMAT_VERSION)
if (version != sla::FORMAT_VERSION)
throw LowlevelError(".sla file has wrong format");
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
while((*iter)->getName() == "floatformat") {
floatformats.emplace_back();
floatformats.back().restoreXml(*iter);
++iter;
}
indexer.restoreXml(*iter);
iter++;
XmlDecode decoder(this,*iter);
decodeSpaces(decoder,this);
iter++;
symtab.restoreXml(*iter,this);
indexer.decode(decoder);
decodeSlaSpaces(decoder,this);
symtab.decode(decoder,this);
decoder.closeElement(el);
root = (SubtableSymbol *)symtab.getGlobalScope()->findSymbol("instruction");
vector<string> errorPairs;
buildXrefs(errorPairs);

View file

@ -19,6 +19,7 @@
#define __SLEIGHBASE_HH__
#include "translate.hh"
#include "slaformat.hh"
#include "slghsymbol.hh"
namespace ghidra {
@ -41,8 +42,8 @@ public:
int4 index(const string filename);
int4 getIndex(const string); ///< get the index of a file. Error if the file is not in the index.
string getFilename(int4); ///< get the filename corresponding to an index
void restoreXml(const Element *el); ///< read a stored index mapping from an XML file
void saveXml(ostream&) const; ///< save the index mapping to an XML file
void decode(Decoder &decoder); ///< decode a stored index mapping from a stream
void encode(Encoder &encoder) const; ///< Encode the index mapping to stream
private:
int4 leastUnusedIndex; ///< one-up count for assigning indices to files
@ -57,7 +58,6 @@ private:
/// - Reading the various SLEIGH specification files
/// - Building and writing out SLEIGH specification files
class SleighBase : public Translate {
static const int4 SLA_FORMAT_VERSION; ///< Current version of the .sla file read/written by SleighBash
vector<string> userop; ///< Names of user-define p-code ops for \b this Translate object
map<VarnodeData,string> varnode_xref; ///< A map from Varnodes in the \e register space to register names
protected:
@ -69,7 +69,9 @@ protected:
SourceFileIndexer indexer; ///< source file index used when generating SLEIGH constructor debug info
void buildXrefs(vector<string> &errorPairs); ///< Build register map. Collect user-ops and context-fields.
void reregisterContext(void); ///< Reregister context fields for a new executable
void restoreXml(const Element *el); ///< Read a SLEIGH specification from XML
AddrSpace *decodeSlaSpace(Decoder &decoder,const Translate *trans); ///< Add a space parsed from a .sla file
void decodeSlaSpaces(Decoder &decoder,const Translate *trans); ///< Restore address spaces from a .sla file
void decode(Decoder &decoder); /// Decode a SELIGH specification from a stream
public:
static const uint4 MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java)
SleighBase(void); ///< Construct an uninitialized translator
@ -83,7 +85,8 @@ public:
SleighSymbol *findSymbol(const string &nm) const { return symtab.findSymbol(nm); } ///< Find a specific SLEIGH symbol by name in the current scope
SleighSymbol *findSymbol(uintm id) const { return symtab.findSymbol(id); } ///< Find a specific SLEIGH symbol by id
SleighSymbol *findGlobalSymbol(const string &nm) const { return symtab.findGlobalSymbol(nm); } ///< Find a specific global SLEIGH symbol by name
void saveXml(ostream &s) const; ///< Write out the SLEIGH specification as an XML \<sleigh> tag.
void encodeSlaSpace(Encoder &encoder,AddrSpace *spc) const; ///< Write the details of given space in .sla format
void encode(Encoder &encoder) const; ///< Write out the SLEIGH specification as a \<sleigh> tag.
};
} // End namespace ghidra

View file

@ -1789,6 +1789,7 @@ SleighCompile::SleighCompile(void)
warnalllocalcollisions = false;
warnallnops = false;
failinsensitivedups = true;
debugoutput = false;
root = (SubtableSymbol *)0;
curmacro = (MacroSymbol *)0;
curct = (Constructor *)0;
@ -2301,7 +2302,7 @@ uint4 SleighCompile::getUniqueAddr(void)
/// A number of checks are also performed, which may generate errors or warnings, including
/// size restriction checks, pattern conflict checks, NOP constructor checks, and
/// local collision checks. Once this method is run, \b this SleighCompile is ready for the
/// saveXml method.
/// encode method.
void SleighCompile::process(void)
{
@ -2546,7 +2547,8 @@ void SleighCompile::newSpace(SpaceQuality *qual)
}
int4 delay = (qual->type == SpaceQuality::registertype) ? 0 : 1;
AddrSpace *spc = new AddrSpace(this,this,IPTR_PROCESSOR,qual->name,qual->size,qual->wordsize,numSpaces(),AddrSpace::hasphysical,delay);
AddrSpace *spc = new AddrSpace(this,this,IPTR_PROCESSOR,qual->name,isBigEndian(),
qual->size,qual->wordsize,numSpaces(),AddrSpace::hasphysical,delay,delay);
insertSpace(spc);
if (qual->isdefault) {
if (getDefaultCodeSpace() != (AddrSpace *)0)
@ -3594,13 +3596,23 @@ int4 SleighCompile::run_compilation(const string &filein,const string &fileout)
if (parseres==0)
process(); // Do all the post-processing
if ((parseres==0)&&(numErrors()==0)) { // If no errors
ofstream s(fileout);
ofstream s(fileout,ios::binary);
if (!s) {
ostringstream errs;
errs << "Unable to open output file: " << fileout;
throw SleighError(errs.str());
}
saveXml(s); // Dump output xml
if (debugoutput) {
// If the debug output format was requested, use the XML encoder
XmlEncode encoder(s);
encode(encoder);
}
else {
// Use the standard .sla format encoder
sla::FormatEncode encoder(s,-1);
encode(encoder);
encoder.flush();
}
s.close();
}
else {
@ -3697,7 +3709,7 @@ static void findSlaSpecs(vector<string> &res, const string &dir, const string &s
void SleighCompile::setAllOptions(const map<string,string> &defines, bool unnecessaryPcodeWarning,
bool lenientConflict, bool allCollisionWarning,
bool allNopWarning,bool deadTempWarning,bool enforceLocalKeyWord,
bool largeTemporaryWarning, bool caseSensitiveRegisterNames)
bool largeTemporaryWarning, bool caseSensitiveRegisterNames,bool debugOutput)
{
map<string,string>::const_iterator iter = defines.begin();
for (iter = defines.begin(); iter != defines.end(); iter++) {
@ -3711,6 +3723,7 @@ void SleighCompile::setAllOptions(const map<string,string> &defines, bool unnece
setEnforceLocalKeyWord(enforceLocalKeyWord);
setLargeTemporaryWarning(largeTemporaryWarning);
setInsensitiveDuplicateError(!caseSensitiveRegisterNames);
setDebugOutput(debugOutput);
}
static void segvHandler(int sig) {
@ -3736,6 +3749,7 @@ int main(int argc,char **argv)
cerr << "USAGE: sleigh [-x] [-dNAME=VALUE] inputfile [outputfile]" << endl;
cerr << " -a scan for all slaspec files recursively where inputfile is a directory" << endl;
cerr << " -x turns on parser debugging" << endl;
cerr << " -y write .sla using XML debug format" << endl;
cerr << " -u print warnings for unnecessary pcode instructions" << endl;
cerr << " -l report pattern conflicts" << endl;
cerr << " -n print warnings for all NOP constructors" << endl;
@ -3759,6 +3773,7 @@ int main(int argc,char **argv)
bool enforceLocalKeyWord = false;
bool largeTemporaryWarning = false;
bool caseSensitiveRegisterNames = false;
bool debugOutput = false;
bool compileAll = false;
@ -3794,6 +3809,8 @@ int main(int argc,char **argv)
largeTemporaryWarning = true;
else if (argv[i][1] == 's')
caseSensitiveRegisterNames = true;
else if (argv[i][1] == 'y')
debugOutput = true;
#ifdef YYDEBUG
else if (argv[i][1] == 'x')
sleighdebug = 1; // Debug option
@ -3825,7 +3842,8 @@ int main(int argc,char **argv)
sla.replace(slaspec.length() - slaspecExtLen, slaspecExtLen, SLAEXT);
SleighCompile compiler;
compiler.setAllOptions(defines, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning,
deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning, caseSensitiveRegisterNames);
deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning, caseSensitiveRegisterNames,
debugOutput);
retval = compiler.run_compilation(slaspec,sla);
if (retval != 0) {
return retval; // stop on first error
@ -3861,7 +3879,8 @@ int main(int argc,char **argv)
SleighCompile compiler;
compiler.setAllOptions(defines, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning,
deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning,caseSensitiveRegisterNames);
deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning,caseSensitiveRegisterNames,
debugOutput);
if (i < argc - 1) {
string fileoutExamine(argv[i+1]);

View file

@ -300,6 +300,7 @@ private:
bool warnalllocalcollisions; ///< \b true if local export collisions generate individual warnings
bool warnallnops; ///< \b true if pcode NOPs generate individual warnings
bool failinsensitivedups; ///< \b true if case insensitive register duplicates cause error
bool debugoutput; ///< \b true if output .sla is written in XML debug format
vector<string> noplist; ///< List of individual NOP warnings
mutable Location currentLocCache; ///< Location for (last) request of current location
int4 errors; ///< Number of fatal errors encountered
@ -382,6 +383,11 @@ public:
/// \param val is \b true is duplicates cause an error.
void setInsensitiveDuplicateError(bool val) { failinsensitivedups = val; }
/// \brief Set whether the output .sla file should be written in XML debug format
///
/// \param val is \b true if the XML debug format should be used
void setDebugOutput(bool val) { debugoutput = val; }
// Lexer functions
void calcContextLayout(void); ///< Calculate the internal context field layout
string grabCurrentFilePath(void) const; ///< Get the path to the current source file
@ -448,7 +454,7 @@ public:
void setAllOptions(const map<string,string> &defines, bool unnecessaryPcodeWarning,
bool lenientConflict, bool allCollisionWarning,
bool allNopWarning,bool deadTempWarning,bool enforceLocalKeyWord,
bool largeTemporaryWarning, bool caseSensitiveRegisterNames);
bool largeTemporaryWarning, bool caseSensitiveRegisterNames,bool debugOutput);
int4 run_compilation(const string &filein,const string &fileout);
};

View file

@ -462,50 +462,50 @@ void PatternExpression::release(PatternExpression *p)
delete p;
}
PatternExpression *PatternExpression::restoreExpression(const Element *el,Translate *trans)
PatternExpression *PatternExpression::decodeExpression(Decoder &decoder,Translate *trans)
{
PatternExpression *res;
const string &nm(el->getName());
uint4 el = decoder.peekElement();
if (nm == "tokenfield")
if (el == sla::ELEM_TOKENFIELD)
res = new TokenField();
else if (nm == "contextfield")
else if (el == sla::ELEM_CONTEXTFIELD)
res = new ContextField();
else if (nm == "intb")
else if (el == sla::ELEM_INTB)
res = new ConstantValue();
else if (nm == "operand_exp")
else if (el == sla::ELEM_OPERAND_EXP)
res = new OperandValue();
else if (nm == "start_exp")
else if (el == sla::ELEM_START_EXP)
res = new StartInstructionValue();
else if (nm == "end_exp")
else if (el == sla::ELEM_END_EXP)
res = new EndInstructionValue();
else if (nm == "plus_exp")
else if (el == sla::ELEM_PLUS_EXP)
res = new PlusExpression();
else if (nm == "sub_exp")
else if (el == sla::ELEM_SUB_EXP)
res = new SubExpression();
else if (nm == "mult_exp")
else if (el == sla::ELEM_MULT_EXP)
res = new MultExpression();
else if (nm == "lshift_exp")
else if (el == sla::ELEM_LSHIFT_EXP)
res = new LeftShiftExpression();
else if (nm == "rshift_exp")
else if (el == sla::ELEM_RSHIFT_EXP)
res = new RightShiftExpression();
else if (nm == "and_exp")
else if (el == sla::ELEM_AND_EXP)
res = new AndExpression();
else if (nm == "or_exp")
else if (el == sla::ELEM_OR_EXP)
res = new OrExpression();
else if (nm == "xor_exp")
else if (el == sla::ELEM_XOR_EXP)
res = new XorExpression();
else if (nm == "div_exp")
else if (el == sla::ELEM_DIV_EXP)
res = new DivExpression();
else if (nm == "minus_exp")
else if (el == sla::ELEM_MINUS_EXP)
res = new MinusExpression();
else if (nm == "not_exp")
else if (el == sla::ELEM_NOT_EXP)
res = new NotExpression();
else
return (PatternExpression *)0;
res->restoreXml(el,trans);
res->decode(decoder,trans);
return res;
}
@ -597,58 +597,33 @@ TokenPattern TokenField::genPattern(intb val) const
return TokenPattern(tok,val,bitstart,bitend);
}
void TokenField::saveXml(ostream &s) const
void TokenField::encode(Encoder &encoder) const
{
s << "<tokenfield";
s << " bigendian=\"";
if (bigendian)
s << "true\"";
else
s << "false\"";
s << " signbit=\"";
if (signbit)
s << "true\"";
else
s << "false\"";
s << " bitstart=\"" << dec << bitstart << "\"";
s << " bitend=\"" << bitend << "\"";
s << " bytestart=\"" << bytestart << "\"";
s << " byteend=\"" << byteend << "\"";
s << " shift=\"" << shift << "\"/>\n";
encoder.openElement(sla::ELEM_TOKENFIELD);
encoder.writeBool(sla::ATTRIB_BIGENDIAN, bigendian);
encoder.writeBool(sla::ATTRIB_SIGNBIT, signbit);
encoder.writeSignedInteger(sla::ATTRIB_STARTBIT, bitstart);
encoder.writeSignedInteger(sla::ATTRIB_ENDBIT, bitend);
encoder.writeSignedInteger(sla::ATTRIB_STARTBYTE, bytestart);
encoder.writeSignedInteger(sla::ATTRIB_ENDBYTE, byteend);
encoder.writeSignedInteger(sla::ATTRIB_SHIFT, shift);
encoder.closeElement(sla::ELEM_TOKENFIELD);
}
void TokenField::restoreXml(const Element *el,Translate *trans)
void TokenField::decode(Decoder &decoder,Translate *trans)
{
uint4 el = decoder.openElement(sla::ELEM_TOKENFIELD);
tok = (Token *)0;
bigendian = xml_readbool(el->getAttributeValue("bigendian"));
signbit = xml_readbool(el->getAttributeValue("signbit"));
{
istringstream s(el->getAttributeValue("bitstart"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> bitstart;
}
{
istringstream s(el->getAttributeValue("bitend"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> bitend;
}
{
istringstream s(el->getAttributeValue("bytestart"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> bytestart;
}
{
istringstream s(el->getAttributeValue("byteend"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> byteend;
}
{
istringstream s(el->getAttributeValue("shift"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> shift;
}
bigendian = decoder.readBool(sla::ATTRIB_BIGENDIAN);
signbit = decoder.readBool(sla::ATTRIB_SIGNBIT);
bitstart = decoder.readSignedInteger(sla::ATTRIB_STARTBIT);
bitend = decoder.readSignedInteger(sla::ATTRIB_ENDBIT);
bytestart = decoder.readSignedInteger(sla::ATTRIB_STARTBYTE);
byteend = decoder.readSignedInteger(sla::ATTRIB_ENDBYTE);
shift = decoder.readSignedInteger(sla::ATTRIB_SHIFT);
decoder.closeElement(el);
}
ContextField::ContextField(bool s,int4 sbit,int4 ebit)
@ -680,65 +655,88 @@ TokenPattern ContextField::genPattern(intb val) const
return TokenPattern(val,startbit,endbit);
}
void ContextField::saveXml(ostream &s) const
void ContextField::encode(Encoder &encoder) const
{
s << "<contextfield";
s << " signbit=\"";
if (signbit)
s << "true\"";
else
s << "false\"";
s << " startbit=\"" << dec << startbit << "\"";
s << " endbit=\"" << endbit << "\"";
s << " startbyte=\"" << startbyte << "\"";
s << " endbyte=\"" << endbyte << "\"";
s << " shift=\"" << shift << "\"/>\n";
encoder.openElement(sla::ELEM_CONTEXTFIELD);
encoder.writeBool(sla::ATTRIB_SIGNBIT, signbit);
encoder.writeSignedInteger(sla::ATTRIB_STARTBIT, startbit);
encoder.writeSignedInteger(sla::ATTRIB_ENDBIT, endbit);
encoder.writeSignedInteger(sla::ATTRIB_STARTBYTE, startbyte);
encoder.writeSignedInteger(sla::ATTRIB_ENDBYTE, endbyte);
encoder.writeSignedInteger(sla::ATTRIB_SHIFT, shift);
encoder.closeElement(sla::ELEM_CONTEXTFIELD);
}
void ContextField::restoreXml(const Element *el,Translate *trans)
void ContextField::decode(Decoder &decoder,Translate *trans)
{
signbit = xml_readbool(el->getAttributeValue("signbit"));
{
istringstream s(el->getAttributeValue("startbit"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> startbit;
}
{
istringstream s(el->getAttributeValue("endbit"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> endbit;
}
{
istringstream s(el->getAttributeValue("startbyte"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> startbyte;
}
{
istringstream s(el->getAttributeValue("endbyte"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> endbyte;
}
{
istringstream s(el->getAttributeValue("shift"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> shift;
}
uint4 el = decoder.openElement(sla::ELEM_CONTEXTFIELD);
signbit = decoder.readBool(sla::ATTRIB_SIGNBIT);
startbit = decoder.readSignedInteger(sla::ATTRIB_STARTBIT);
endbit = decoder.readSignedInteger(sla::ATTRIB_ENDBIT);
startbyte = decoder.readSignedInteger(sla::ATTRIB_STARTBYTE);
endbyte = decoder.readSignedInteger(sla::ATTRIB_ENDBYTE);
shift = decoder.readSignedInteger(sla::ATTRIB_SHIFT);
decoder.closeElement(el);
}
void ConstantValue::saveXml(ostream &s) const
void ConstantValue::encode(Encoder &encoder) const
{
s << "<intb val=\"" << dec << val << "\"/>\n";
encoder.openElement(sla::ELEM_INTB);
encoder.writeSignedInteger(sla::ATTRIB_VAL, val);
encoder.closeElement(sla::ELEM_INTB);
}
void ConstantValue::restoreXml(const Element *el,Translate *trans)
void ConstantValue::decode(Decoder &decoder,Translate *trans)
{
istringstream s(el->getAttributeValue("val"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> val;
uint4 el = decoder.openElement(sla::ELEM_INTB);
val = decoder.readSignedInteger(sla::ATTRIB_VAL);
decoder.closeElement(el);
}
void StartInstructionValue::encode(Encoder &encoder) const
{
encoder.openElement(sla::ELEM_START_EXP);
encoder.closeElement(sla::ELEM_START_EXP);
}
void StartInstructionValue::decode(Decoder &decoder,Translate *trans)
{
uint4 el = decoder.openElement(sla::ELEM_START_EXP);
decoder.closeElement(el);
}
void EndInstructionValue::encode(Encoder &encoder) const
{
encoder.openElement(sla::ELEM_END_EXP);
encoder.closeElement(sla::ELEM_END_EXP);
}
void EndInstructionValue::decode(Decoder &decoder,Translate *trans)
{
uint4 el = decoder.openElement(sla::ELEM_END_EXP);
decoder.closeElement(el);
}
void Next2InstructionValue::encode(Encoder &encoder) const
{
encoder.openElement(sla::ELEM_NEXT2_EXP);
encoder.closeElement(sla::ELEM_NEXT2_EXP);
}
void Next2InstructionValue::decode(Decoder &decoder,Translate *trans)
{
uint4 el = decoder.openElement(sla::ELEM_NEXT2_EXP);
decoder.closeElement(el);
}
TokenPattern OperandValue::genPattern(intb val) const
@ -809,37 +807,27 @@ const string &OperandValue::getName(void) const
return sym->getName();
}
void OperandValue::saveXml(ostream &s) const
void OperandValue::encode(Encoder &encoder) const
{
s << "<operand_exp";
s << " index=\"" << dec << index << "\"";
s << " table=\"0x" << hex << ct->getParent()->getId() << "\"";
s << " ct=\"0x" << ct->getId() << "\"/>\n"; // Save id of our constructor
encoder.openElement(sla::ELEM_OPERAND_EXP);
encoder.writeSignedInteger(sla::ATTRIB_INDEX, index);
encoder.writeUnsignedInteger(sla::ATTRIB_TABLE, ct->getParent()->getId());
encoder.writeUnsignedInteger(sla::ATTRIB_CT, ct->getId()); // Save id of our constructor
encoder.closeElement(sla::ELEM_OPERAND_EXP);
}
void OperandValue::restoreXml(const Element *el,Translate *trans)
void OperandValue::decode(Decoder &decoder,Translate *trans)
{
uintm ctid,tabid;
{
istringstream s(el->getAttributeValue("index"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> index;
}
{
istringstream s(el->getAttributeValue("table"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> tabid;
}
{
istringstream s(el->getAttributeValue("ct"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> ctid;
}
uint4 el = decoder.openElement(sla::ELEM_OPERAND_EXP);
index = decoder.readSignedInteger(sla::ATTRIB_INDEX);
uintm tabid = decoder.readUnsignedInteger(sla::ATTRIB_TABLE);
uintm ctid = decoder.readUnsignedInteger(sla::ATTRIB_CT);
SleighBase *sleigh = (SleighBase *)trans;
SubtableSymbol *tab = dynamic_cast<SubtableSymbol *>(sleigh->findSymbol(tabid));
ct = tab->getConstructor(ctid);
decoder.closeElement(el);
}
BinaryExpression::BinaryExpression(PatternExpression *l,PatternExpression *r)
@ -858,24 +846,22 @@ BinaryExpression::~BinaryExpression(void)
PatternExpression::release(right);
}
void BinaryExpression::saveXml(ostream &s) const
void BinaryExpression::encode(Encoder &encoder) const
{ // Outer tag is generated by derived classes
left->saveXml(s);
right->saveXml(s);
left->encode(encoder);
right->encode(encoder);
}
void BinaryExpression::restoreXml(const Element *el,Translate *trans)
void BinaryExpression::decode(Decoder &decoder,Translate *trans)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
left = PatternExpression::restoreExpression(*iter,trans);
++iter;
right = PatternExpression::restoreExpression(*iter,trans);
uint4 el = decoder.openElement();
left = PatternExpression::decodeExpression(decoder,trans);
right = PatternExpression::decodeExpression(decoder,trans);
left->layClaim();
right->layClaim();
decoder.closeElement(el);
}
UnaryExpression::UnaryExpression(PatternExpression *u)
@ -891,20 +877,19 @@ UnaryExpression::~UnaryExpression(void)
PatternExpression::release(unary);
}
void UnaryExpression::saveXml(ostream &s) const
void UnaryExpression::encode(Encoder &encoder) const
{ // Outer tag is generated by derived classes
unary->saveXml(s);
unary->encode(encoder);
}
void UnaryExpression::restoreXml(const Element *el,Translate *trans)
void UnaryExpression::decode(Decoder &decoder,Translate *trans)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
unary = PatternExpression::restoreExpression(*iter,trans);
uint4 el = decoder.openElement();
unary = PatternExpression::decodeExpression(decoder,trans);
unary->layClaim();
decoder.closeElement(el);
}
intb PlusExpression::getValue(ParserWalker &walker) const
@ -923,12 +908,12 @@ intb PlusExpression::getSubValue(const vector<intb> &replace,int4 &listpos) cons
return leftval + rightval;
}
void PlusExpression::saveXml(ostream &s) const
void PlusExpression::encode(Encoder &encoder) const
{
s << "<plus_exp>\n";
BinaryExpression::saveXml(s);
s << "</plus_exp>\n";
encoder.openElement(sla::ELEM_PLUS_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_PLUS_EXP);
}
intb SubExpression::getValue(ParserWalker &walker) const
@ -947,12 +932,12 @@ intb SubExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return leftval - rightval;
}
void SubExpression::saveXml(ostream &s) const
void SubExpression::encode(Encoder &encoder) const
{
s << "<sub_exp>\n";
BinaryExpression::saveXml(s);
s << "</sub_exp>\n";
encoder.openElement(sla::ELEM_SUB_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_SUB_EXP);
}
intb MultExpression::getValue(ParserWalker &walker) const
@ -971,12 +956,12 @@ intb MultExpression::getSubValue(const vector<intb> &replace,int4 &listpos) cons
return leftval * rightval;
}
void MultExpression::saveXml(ostream &s) const
void MultExpression::encode(Encoder &encoder) const
{
s << "<mult_exp>\n";
BinaryExpression::saveXml(s);
s << "</mult_exp>\n";
encoder.openElement(sla::ELEM_MULT_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_MULT_EXP);
}
intb LeftShiftExpression::getValue(ParserWalker &walker) const
@ -995,12 +980,12 @@ intb LeftShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos)
return leftval << rightval;
}
void LeftShiftExpression::saveXml(ostream &s) const
void LeftShiftExpression::encode(Encoder &encoder) const
{
s << "<lshift_exp>\n";
BinaryExpression::saveXml(s);
s << "</lshift_exp>\n";
encoder.openElement(sla::ELEM_LSHIFT_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_LSHIFT_EXP);
}
intb RightShiftExpression::getValue(ParserWalker &walker) const
@ -1019,12 +1004,12 @@ intb RightShiftExpression::getSubValue(const vector<intb> &replace,int4 &listpos
return leftval >> rightval;
}
void RightShiftExpression::saveXml(ostream &s) const
void RightShiftExpression::encode(Encoder &encoder) const
{
s << "<rshift_exp>\n";
BinaryExpression::saveXml(s);
s << "</rshift_exp>\n";
encoder.openElement(sla::ELEM_RSHIFT_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_RSHIFT_EXP);
}
intb AndExpression::getValue(ParserWalker &walker) const
@ -1043,12 +1028,12 @@ intb AndExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return leftval & rightval;
}
void AndExpression::saveXml(ostream &s) const
void AndExpression::encode(Encoder &encoder) const
{
s << "<and_exp>\n";
BinaryExpression::saveXml(s);
s << "</and_exp>\n";
encoder.openElement(sla::ELEM_AND_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_AND_EXP);
}
intb OrExpression::getValue(ParserWalker &walker) const
@ -1067,12 +1052,12 @@ intb OrExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return leftval | rightval;
}
void OrExpression::saveXml(ostream &s) const
void OrExpression::encode(Encoder &encoder) const
{
s << "<or_exp>\n";
BinaryExpression::saveXml(s);
s << "</or_exp>\n";
encoder.openElement(sla::ELEM_OR_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_OR_EXP);
}
intb XorExpression::getValue(ParserWalker &walker) const
@ -1091,12 +1076,12 @@ intb XorExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return leftval ^ rightval;
}
void XorExpression::saveXml(ostream &s) const
void XorExpression::encode(Encoder &encoder) const
{
s << "<xor_exp>\n";
BinaryExpression::saveXml(s);
s << "</xor_exp>\n";
encoder.openElement(sla::ELEM_XOR_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_XOR_EXP);
}
intb DivExpression::getValue(ParserWalker &walker) const
@ -1115,12 +1100,12 @@ intb DivExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return leftval / rightval;
}
void DivExpression::saveXml(ostream &s) const
void DivExpression::encode(Encoder &encoder) const
{
s << "<div_exp>\n";
BinaryExpression::saveXml(s);
s << "</div_exp>\n";
encoder.openElement(sla::ELEM_DIV_EXP);
BinaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_DIV_EXP);
}
intb MinusExpression::getValue(ParserWalker &walker) const
@ -1137,12 +1122,12 @@ intb MinusExpression::getSubValue(const vector<intb> &replace,int4 &listpos) con
return -val;
}
void MinusExpression::saveXml(ostream &s) const
void MinusExpression::encode(Encoder &encoder) const
{
s << "<minus_exp>\n";
UnaryExpression::saveXml(s);
s << "</minus_exp>\n";
encoder.openElement(sla::ELEM_MINUS_EXP);
UnaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_MINUS_EXP);
}
intb NotExpression::getValue(ParserWalker &walker) const
@ -1159,12 +1144,12 @@ intb NotExpression::getSubValue(const vector<intb> &replace,int4 &listpos) const
return ~val;
}
void NotExpression::saveXml(ostream &s) const
void NotExpression::encode(Encoder &encoder) const
{
s << "<not_exp>\n";
UnaryExpression::saveXml(s);
s << "</not_exp>\n";
encoder.openElement(sla::ELEM_NOT_EXP);
UnaryExpression::encode(encoder);
encoder.closeElement(sla::ELEM_NOT_EXP);
}
static bool advance_combo(vector<intb> &val,const vector<intb> &min,vector<intb> &max)

View file

@ -67,14 +67,14 @@ public:
virtual void listValues(vector<const PatternValue *> &list) const=0;
virtual void getMinMax(vector<intb> &minlist,vector<intb> &maxlist) const=0;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const=0;
virtual void saveXml(ostream &s) const=0;
virtual void restoreXml(const Element *el,Translate *trans)=0;
virtual void encode(Encoder &encoder) const=0;
virtual void decode(Decoder &decoder,Translate *trans)=0;
intb getSubValue(const vector<intb> &replace) {
int4 listpos = 0;
return getSubValue(replace,listpos); }
void layClaim(void) { refcount += 1; }
static void release(PatternExpression *p);
static PatternExpression *restoreExpression(const Element *el,Translate *trans);
static PatternExpression *decodeExpression(Decoder &decoder,Translate *trans);
};
class PatternValue : public PatternExpression {
@ -96,15 +96,15 @@ class TokenField : public PatternValue {
int4 bytestart,byteend; // Bytes to read to get value
int4 shift; // Amount to shift to align value (bitstart % 8)
public:
TokenField(void) {} // For use with restoreXml
TokenField(void) {} // For use with decode
TokenField(Token *tk,bool s,int4 bstart,int4 bend);
virtual intb getValue(ParserWalker &walker) const;
virtual TokenPattern genMinPattern(const vector<TokenPattern> &ops) const { return TokenPattern(tok); }
virtual TokenPattern genPattern(intb val) const;
virtual intb minValue(void) const { return 0; }
virtual intb maxValue(void) const { intb res=0; return zero_extend(~res,bitend-bitstart); }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class ContextField : public PatternValue {
@ -113,7 +113,7 @@ class ContextField : public PatternValue {
int4 shift;
bool signbit;
public:
ContextField(void) {} // For use with restoreXml
ContextField(void) {} // For use with decode
ContextField(bool s,int4 sbit,int4 ebit);
int4 getStartBit(void) const { return startbit; }
int4 getEndBit(void) const { return endbit; }
@ -123,22 +123,22 @@ public:
virtual TokenPattern genPattern(intb val) const;
virtual intb minValue(void) const { return 0; }
virtual intb maxValue(void) const { intb res=0; return zero_extend(~res,(endbit-startbit)); }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class ConstantValue : public PatternValue {
intb val;
public:
ConstantValue(void) {} // For use with restoreXml
ConstantValue(void) {} // For use with decode
ConstantValue(intb v) { val = v; }
virtual intb getValue(ParserWalker &walker) const { return val; }
virtual TokenPattern genMinPattern(const vector<TokenPattern> &ops) const { return TokenPattern(); }
virtual TokenPattern genPattern(intb v) const { return TokenPattern(val==v); }
virtual intb minValue(void) const { return val; }
virtual intb maxValue(void) const { return val; }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class StartInstructionValue : public PatternValue {
@ -150,8 +150,8 @@ public:
virtual TokenPattern genPattern(intb val) const { return TokenPattern(); }
virtual intb minValue(void) const { return (intb)0; }
virtual intb maxValue(void) const { return (intb)0; }
virtual void saveXml(ostream &s) const { s << "<start_exp/>"; }
virtual void restoreXml(const Element *el,Translate *trans) {}
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class EndInstructionValue : public PatternValue {
@ -163,8 +163,8 @@ public:
virtual TokenPattern genPattern(intb val) const { return TokenPattern(); }
virtual intb minValue(void) const { return (intb)0; }
virtual intb maxValue(void) const { return (intb)0; }
virtual void saveXml(ostream &s) const { s << "<end_exp/>"; }
virtual void restoreXml(const Element *el,Translate *trans) {}
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class Next2InstructionValue : public PatternValue {
@ -176,8 +176,8 @@ public:
virtual TokenPattern genPattern(intb val) const { return TokenPattern(); }
virtual intb minValue(void) const { return (intb)0; }
virtual intb maxValue(void) const { return (intb)0; }
virtual void saveXml(ostream &s) const { s << "<next2_exp/>"; }
virtual void restoreXml(const Element *el,Translate *trans) {}
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class Constructor; // Forward declaration
@ -186,7 +186,7 @@ class OperandValue : public PatternValue {
int4 index; // This is the defining field of expression
Constructor *ct; // cached pointer to constructor
public:
OperandValue(void) { } // For use with restoreXml
OperandValue(void) { } // For use with decode
OperandValue(int4 ind,Constructor *c) { index = ind; ct = c; }
void changeIndex(int4 newind) { index = newind; }
bool isConstructorRelative(void) const;
@ -197,8 +197,8 @@ public:
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual intb minValue(void) const;
virtual intb maxValue(void) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class BinaryExpression : public PatternExpression {
@ -206,7 +206,7 @@ class BinaryExpression : public PatternExpression {
protected:
virtual ~BinaryExpression(void);
public:
BinaryExpression(void) { left = (PatternExpression *)0; right = (PatternExpression *)0; } // For use with restoreXml
BinaryExpression(void) { left = (PatternExpression *)0; right = (PatternExpression *)0; } // For use with decode
BinaryExpression(PatternExpression *l,PatternExpression *r);
PatternExpression *getLeft(void) const { return left; }
PatternExpression *getRight(void) const { return right; }
@ -215,8 +215,8 @@ public:
left->listValues(list); right->listValues(list); }
virtual void getMinMax(vector<intb> &minlist,vector<intb> &maxlist) const {
left->getMinMax(minlist,maxlist); right->getMinMax(minlist,maxlist); }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class UnaryExpression : public PatternExpression {
@ -224,7 +224,7 @@ class UnaryExpression : public PatternExpression {
protected:
virtual ~UnaryExpression(void);
public:
UnaryExpression(void) { unary = (PatternExpression *)0; } // For use with restoreXml
UnaryExpression(void) { unary = (PatternExpression *)0; } // For use with decode
UnaryExpression(PatternExpression *u);
PatternExpression *getUnary(void) const { return unary; }
virtual TokenPattern genMinPattern(const vector<TokenPattern> &ops) const { return TokenPattern(); }
@ -233,35 +233,35 @@ public:
virtual void getMinMax(vector<intb> &minlist,vector<intb> &maxlist) const {
unary->getMinMax(minlist,maxlist);
}
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,Translate *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,Translate *trans);
};
class PlusExpression : public BinaryExpression {
public:
PlusExpression(void) {} // For use by restoreXml
PlusExpression(void) {} // For use by decode
PlusExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class SubExpression : public BinaryExpression {
public:
SubExpression(void) {} // For use with restoreXml
SubExpression(void) {} // For use with decode
SubExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class MultExpression : public BinaryExpression {
public:
MultExpression(void) {} // For use with restoreXml
MultExpression(void) {} // For use with decode
MultExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class LeftShiftExpression : public BinaryExpression {
@ -270,7 +270,7 @@ public:
LeftShiftExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class RightShiftExpression : public BinaryExpression {
@ -279,7 +279,7 @@ public:
RightShiftExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class AndExpression : public BinaryExpression {
@ -288,7 +288,7 @@ public:
AndExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class OrExpression : public BinaryExpression {
@ -297,7 +297,7 @@ public:
OrExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class XorExpression : public BinaryExpression {
@ -306,7 +306,7 @@ public:
XorExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class DivExpression : public BinaryExpression {
@ -315,7 +315,7 @@ public:
DivExpression(PatternExpression *l,PatternExpression *r) : BinaryExpression(l,r) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class MinusExpression : public UnaryExpression {
@ -324,7 +324,7 @@ public:
MinusExpression(PatternExpression *u) : UnaryExpression(u) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
class NotExpression : public UnaryExpression {
@ -333,7 +333,7 @@ public:
NotExpression(PatternExpression *u) : UnaryExpression(u) {}
virtual intb getValue(ParserWalker &walker) const;
virtual intb getSubValue(const vector<intb> &replace,int4 &listpos) const;
virtual void saveXml(ostream &s) const;
virtual void encode(Encoder &encoder) const;
};
struct OperandResolve {

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "slghpattern.hh"
#include "slaformat.hh"
namespace ghidra {
@ -137,17 +138,18 @@ bool DisjointPattern::resolvesIntersect(const DisjointPattern *op1,const Disjoin
return resolveIntersectBlock(op1->getBlock(true),op2->getBlock(true),getBlock(true));
}
DisjointPattern *DisjointPattern::restoreDisjoint(const Element *el)
DisjointPattern *DisjointPattern::decodeDisjoint(Decoder &decoder)
{ // DisjointPattern factory
DisjointPattern *res;
if (el->getName() == "instruct_pat")
uint4 el = decoder.peekElement();
if (el == sla::ELEM_INSTRUCT_PAT)
res = new InstructionPattern();
else if (el->getName() == "context_pat")
else if (el == sla::ELEM_CONTEXT_PAT)
res = new ContextPattern();
else
res = new CombinePattern();
res->restoreXml(el);
res->decode(decoder);
return res;
}
@ -485,54 +487,37 @@ bool PatternBlock::isContextMatch(ParserWalker &walker) const
return true;
}
void PatternBlock::saveXml(ostream &s) const
void PatternBlock::encode(Encoder &encoder) const
{
s << "<pat_block ";
s << "offset=\"" << dec << offset << "\" ";
s << "nonzero=\"" << nonzerosize << "\">\n";
encoder.openElement(sla::ELEM_PAT_BLOCK);
encoder.writeSignedInteger(sla::ATTRIB_OFF, offset);
encoder.writeSignedInteger(sla::ATTRIB_NONZERO, nonzerosize);
for(int4 i=0;i<maskvec.size();++i) {
s << " <mask_word ";
s << "mask=\"0x" << hex << maskvec[i] << "\" ";
s << "val=\"0x" << valvec[i] << "\"/>\n";
encoder.openElement(sla::ELEM_MASK_WORD);
encoder.writeUnsignedInteger(sla::ATTRIB_MASK, maskvec[i]);
encoder.writeUnsignedInteger(sla::ATTRIB_VAL, valvec[i]);
encoder.closeElement(sla::ELEM_MASK_WORD);
}
s << "</pat_block>\n";
encoder.closeElement(sla::ELEM_PAT_BLOCK);
}
void PatternBlock::restoreXml(const Element *el)
void PatternBlock::decode(Decoder &decoder)
{
{
istringstream s(el->getAttributeValue("offset"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> offset;
}
{
istringstream s(el->getAttributeValue("nonzero"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> nonzerosize;
}
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
uintm mask,val;
while(iter != list.end()) {
Element *subel = *iter;
{
istringstream s(subel->getAttributeValue("mask"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> mask;
}
{
istringstream s(subel->getAttributeValue("val"));
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> val;
}
uint4 el = decoder.openElement(sla::ELEM_PAT_BLOCK);
offset = decoder.readSignedInteger(sla::ATTRIB_OFF);
nonzerosize = decoder.readSignedInteger(sla::ATTRIB_NONZERO);
while(decoder.peekElement() != 0) {
uint4 subel = decoder.openElement(sla::ELEM_MASK_WORD);
uintm mask = decoder.readUnsignedInteger(sla::ATTRIB_MASK);
uintm val = decoder.readUnsignedInteger(sla::ATTRIB_VAL);
maskvec.push_back(mask);
valvec.push_back(val);
++iter;
decoder.closeElement(subel);
}
normalize();
decoder.closeElement(el);
}
Pattern *InstructionPattern::doAnd(const Pattern *b,int4 sa) const
@ -623,22 +608,21 @@ Pattern *InstructionPattern::doOr(const Pattern *b,int4 sa) const
return new OrPattern(res1,res2);
}
void InstructionPattern::saveXml(ostream &s) const
void InstructionPattern::encode(Encoder &encoder) const
{
s << "<instruct_pat>\n";
maskvalue->saveXml(s);
s << "</instruct_pat>\n";
encoder.openElement(sla::ELEM_INSTRUCT_PAT);
maskvalue->encode(encoder);
encoder.closeElement(sla::ELEM_INSTRUCT_PAT);
}
void InstructionPattern::restoreXml(const Element *el)
void InstructionPattern::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
uint4 el = decoder.openElement(sla::ELEM_INSTRUCT_PAT);
maskvalue = new PatternBlock(true);
maskvalue->restoreXml(*iter);
maskvalue->decode(decoder);
decoder.closeElement(el);
}
Pattern *ContextPattern::doOr(const Pattern *b,int4 sa) const
@ -673,22 +657,21 @@ Pattern *ContextPattern::commonSubPattern(const Pattern *b,int4 sa) const
return new ContextPattern(resblock);
}
void ContextPattern::saveXml(ostream &s) const
void ContextPattern::encode(Encoder &encoder) const
{
s << "<context_pat>\n";
maskvalue->saveXml(s);
s << "</context_pat>\n";
encoder.openElement(sla::ELEM_CONTEXT_PAT);
maskvalue->encode(encoder);
encoder.closeElement(sla::ELEM_CONTEXT_PAT);
}
void ContextPattern::restoreXml(const Element *el)
void ContextPattern::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
uint4 el = decoder.openElement(sla::ELEM_CONTEXT_PAT);
maskvalue = new PatternBlock(true);
maskvalue->restoreXml(*iter);
maskvalue->decode(decoder);
decoder.closeElement(el);
}
CombinePattern::~CombinePattern(void)
@ -804,26 +787,24 @@ Pattern *CombinePattern::simplifyClone(void) const
(InstructionPattern *)instr->simplifyClone());
}
void CombinePattern::saveXml(ostream &s) const
void CombinePattern::encode(Encoder &encoder) const
{
s << "<combine_pat>\n";
context->saveXml(s);
instr->saveXml(s);
s << "</combine_pat>\n";
encoder.openElement(sla::ELEM_COMBINE_PAT);
context->encode(encoder);
instr->encode(encoder);
encoder.closeElement(sla::ELEM_COMBINE_PAT);
}
void CombinePattern::restoreXml(const Element *el)
void CombinePattern::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
uint4 el = decoder.openElement(sla::ELEM_COMBINE_PAT);
context = new ContextPattern();
context->restoreXml(*iter);
++iter;
context->decode(decoder);
instr = new InstructionPattern();
instr->restoreXml(*iter);
instr->decode(decoder);
decoder.closeElement(el);
}
OrPattern::OrPattern(DisjointPattern *a,DisjointPattern *b)
@ -995,26 +976,24 @@ Pattern *OrPattern::simplifyClone(void) const
return new OrPattern(newlist);
}
void OrPattern::saveXml(ostream &s) const
void OrPattern::encode(Encoder &encoder) const
{
s << "<or_pat>\n";
encoder.openElement(sla::ELEM_OR_PAT);
for(int4 i=0;i<orlist.size();++i)
orlist[i]->saveXml(s);
s << "</or_pat>\n";
orlist[i]->encode(encoder);
encoder.closeElement(sla::ELEM_OR_PAT);
}
void OrPattern::restoreXml(const Element *el)
void OrPattern::decode(Decoder &decoder)
{
const List &list(el->getChildren());
List::const_iterator iter;
iter = list.begin();
while(iter != list.end()) {
DisjointPattern *pat = DisjointPattern::restoreDisjoint(*iter);
uint4 el = decoder.openElement(sla::ELEM_OR_PAT);
while(decoder.peekElement() != 0) {
DisjointPattern *pat = DisjointPattern::decodeDisjoint(decoder);
orlist.push_back(pat);
++iter;
}
decoder.closeElement(el);
}
} // End namespace ghidra

View file

@ -45,8 +45,8 @@ public:
bool alwaysFalse(void) const { return (nonzerosize==-1); }
bool isInstructionMatch(ParserWalker &walker) const;
bool isContextMatch(ParserWalker &walker) const;
void saveXml(ostream &s) const;
void restoreXml(const Element *el);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder);
};
class DisjointPattern;
@ -64,8 +64,8 @@ public:
virtual bool alwaysTrue(void) const=0;
virtual bool alwaysFalse(void) const=0;
virtual bool alwaysInstructionTrue(void) const=0;
virtual void saveXml(ostream &s) const=0;
virtual void restoreXml(const Element *el)=0;
virtual void encode(Encoder &encoder) const=0;
virtual void decode(Decoder &decoder)=0;
};
class DisjointPattern : public Pattern { // A pattern with no ORs in it
@ -79,14 +79,14 @@ public:
bool specializes(const DisjointPattern *op2) const;
bool identical(const DisjointPattern *op2) const;
bool resolvesIntersect(const DisjointPattern *op1,const DisjointPattern *op2) const;
static DisjointPattern *restoreDisjoint(const Element *el);
static DisjointPattern *decodeDisjoint(Decoder &decoder);
};
class InstructionPattern : public DisjointPattern { // Matches the instruction bitstream
PatternBlock *maskvalue;
virtual PatternBlock *getBlock(bool context) const { return context ? (PatternBlock *)0 : maskvalue; }
public:
InstructionPattern(void) { maskvalue = (PatternBlock *)0; } // For use with restoreXml
InstructionPattern(void) { maskvalue = (PatternBlock *)0; } // For use with decode
InstructionPattern(PatternBlock *mv) { maskvalue = mv; }
InstructionPattern(bool tf) { maskvalue = new PatternBlock(tf); }
PatternBlock *getBlock(void) { return maskvalue; }
@ -100,15 +100,15 @@ public:
virtual bool alwaysTrue(void) const { return maskvalue->alwaysTrue(); }
virtual bool alwaysFalse(void) const { return maskvalue->alwaysFalse(); }
virtual bool alwaysInstructionTrue(void) const { return maskvalue->alwaysTrue(); }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder);
};
class ContextPattern : public DisjointPattern { // Matches the context bitstream
PatternBlock *maskvalue;
virtual PatternBlock *getBlock(bool context) const { return context ? maskvalue : (PatternBlock *)0; }
public:
ContextPattern(void) { maskvalue = (PatternBlock *)0; } // For use with restoreXml
ContextPattern(void) { maskvalue = (PatternBlock *)0; } // For use with decode
ContextPattern(PatternBlock *mv) { maskvalue = mv; }
PatternBlock *getBlock(void) { return maskvalue; }
virtual ~ContextPattern(void) { if (maskvalue != (PatternBlock *)0) delete maskvalue; }
@ -121,8 +121,8 @@ public:
virtual bool alwaysTrue(void) const { return maskvalue->alwaysTrue(); }
virtual bool alwaysFalse(void) const { return maskvalue->alwaysFalse(); }
virtual bool alwaysInstructionTrue(void) const { return true; }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder);
};
// A pattern with a context piece and an instruction piece
@ -144,14 +144,14 @@ public:
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder);
};
class OrPattern : public Pattern {
vector<DisjointPattern *> orlist;
public:
OrPattern(void) {} // For use with restoreXml
OrPattern(void) {} // For use with decode
OrPattern(DisjointPattern *a,DisjointPattern *b);
OrPattern(const vector<DisjointPattern *> &list);
virtual ~OrPattern(void);
@ -166,8 +166,8 @@ public:
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder);
};
} // End namespace ghidra

File diff suppressed because it is too large Load diff

View file

@ -35,16 +35,16 @@ private:
uintm id; // Unique id across all symbols
uintm scopeid; // Unique id of scope this symbol is in
public:
SleighSymbol(void) {} // For use with restoreXml
SleighSymbol(void) {} // For use with decode
SleighSymbol(const string &nm) { name = nm; id = 0; }
virtual ~SleighSymbol(void) {}
const string &getName(void) const { return name; }
uintm getId(void) const { return id; }
virtual symbol_type getType(void) const { return dummy_symbol; }
virtual void saveXmlHeader(ostream &s) const;
void restoreXmlHeader(const Element *el);
virtual void saveXml(ostream &s) const {}
virtual void restoreXml(const Element *el,SleighBase *trans) {}
virtual void encodeHeader(Encoder &encoder) const;
void decodeHeader(Decoder &decoder);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
struct SymbolCompare {
@ -92,9 +92,9 @@ public:
SleighSymbol *findGlobalSymbol(const string &nm) const { return findSymbolInternal(table[0],nm); }
SleighSymbol *findSymbol(uintm id) const { return symbollist[id]; }
void replaceSymbol(SleighSymbol *a,SleighSymbol *b);
void saveXml(ostream &s) const;
void restoreXml(const Element *el,SleighBase *trans);
void restoreSymbolHeader(const Element *el);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder,SleighBase *trans);
void decodeSymbolHeader(Decoder &decoder);
void purge(void);
};
@ -127,20 +127,19 @@ public:
int4 getDefineCount(void) const { return define_count; }
int4 getRefCount(void) const { return ref_count; }
virtual symbol_type getType(void) const { return section_symbol; }
// Not saved or restored
};
class UserOpSymbol : public SleighSymbol { // A user-defined pcode-op
uint4 index;
public:
UserOpSymbol(void) {} // For use with restoreXml
UserOpSymbol(void) {} // For use with decode
UserOpSymbol(const string &nm) : SleighSymbol(nm) { index = 0; }
void setIndex(uint4 ind) { index = ind; }
uint4 getIndex(void) const { return index; }
virtual symbol_type getType(void) const { return userop_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class Constructor; // Forward declaration
@ -174,33 +173,31 @@ public:
class PatternlessSymbol : public SpecificSymbol { // Behaves like constant 0 pattern
ConstantValue *patexp;
public:
PatternlessSymbol(void); // For use with restoreXml
PatternlessSymbol(void); // For use with decode
PatternlessSymbol(const string &nm);
virtual ~PatternlessSymbol(void);
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
virtual void saveXml(ostream &s) const {}
virtual void restoreXml(const Element *el,SleighBase *trans) {}
};
class EpsilonSymbol : public PatternlessSymbol { // Another name for zero pattern/value
AddrSpace *const_space;
public:
EpsilonSymbol(void) {} // For use with restoreXml
EpsilonSymbol(void) {} // For use with decode
EpsilonSymbol(const string &nm,AddrSpace *spc) : PatternlessSymbol(nm) { const_space=spc; }
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return epsilon_symbol; }
virtual VarnodeTpl *getVarnode(void) const;
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class ValueSymbol : public FamilySymbol {
protected:
PatternValue *patval;
public:
ValueSymbol(void) { patval = (PatternValue *)0; } // For use with restoreXml
ValueSymbol(void) { patval = (PatternValue *)0; } // For use with decode
ValueSymbol(const string &nm,PatternValue *pv);
virtual ~ValueSymbol(void);
virtual PatternValue *getPatternValue(void) const { return patval; }
@ -208,9 +205,9 @@ public:
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return value_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class ValueMapSymbol : public ValueSymbol {
@ -218,15 +215,15 @@ class ValueMapSymbol : public ValueSymbol {
bool tableisfilled;
void checkTableFill(void);
public:
ValueMapSymbol(void) {} // For use with restoreXml
ValueMapSymbol(void) {} // For use with decode
ValueMapSymbol(const string &nm,PatternValue *pv,const vector<intb> &vt) : ValueSymbol(nm,pv) { valuetable=vt; checkTableFill(); }
virtual Constructor *resolve(ParserWalker &walker);
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return valuemap_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class NameSymbol : public ValueSymbol {
@ -234,21 +231,21 @@ class NameSymbol : public ValueSymbol {
bool tableisfilled;
void checkTableFill(void);
public:
NameSymbol(void) {} // For use with restoreXml
NameSymbol(void) {} // For use with decode
NameSymbol(const string &nm,PatternValue *pv,const vector<string> &nt) : ValueSymbol(nm,pv) { nametable=nt; checkTableFill(); }
virtual Constructor *resolve(ParserWalker &walker);
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return name_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class VarnodeSymbol : public PatternlessSymbol { // A global varnode
VarnodeData fix;
bool context_bits;
public:
VarnodeSymbol(void) {} // For use with restoreXml
VarnodeSymbol(void) {} // For use with decode
VarnodeSymbol(const string &nm,AddrSpace *base,uintb offset,int4 size);
void markAsContext(void) { context_bits = true; }
const VarnodeData &getFixedVarnode(void) const { return fix; }
@ -259,9 +256,9 @@ public:
s << getName(); }
virtual void collectLocalValues(vector<uintb> &results) const;
virtual symbol_type getType(void) const { return varnode_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class BitrangeSymbol : public SleighSymbol { // A smaller bitrange within a varnode
@ -269,7 +266,7 @@ class BitrangeSymbol : public SleighSymbol { // A smaller bitrange within a varn
uint4 bitoffset; // least significant bit of range
uint4 numbits; // number of bits in the range
public:
BitrangeSymbol(void) {} // For use with restoreXml
BitrangeSymbol(void) {} // For use with decode
BitrangeSymbol(const string &nm,VarnodeSymbol *sym,uint4 bitoff,uint4 num)
: SleighSymbol(nm) { varsym=sym; bitoffset=bitoff; numbits=num; }
VarnodeSymbol *getParentSymbol(void) const { return varsym; }
@ -283,16 +280,16 @@ class ContextSymbol : public ValueSymbol {
uint4 low,high; // into a varnode
bool flow;
public:
ContextSymbol(void) {} // For use with restoreXml
ContextSymbol(void) {} // For use with decode
ContextSymbol(const string &nm,ContextField *pate,VarnodeSymbol *v,uint4 l,uint4 h,bool flow);
VarnodeSymbol *getVarnode(void) const { return vn; }
uint4 getLow(void) const { return low; }
uint4 getHigh(void) const { return high; }
bool getFlow(void) const { return flow; }
virtual symbol_type getType(void) const { return context_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class VarnodeListSymbol : public ValueSymbol {
@ -300,16 +297,16 @@ class VarnodeListSymbol : public ValueSymbol {
bool tableisfilled;
void checkTableFill(void);
public:
VarnodeListSymbol(void) {} // For use with restoreXml
VarnodeListSymbol(void) {} // For use with decode
VarnodeListSymbol(const string &nm,PatternValue *pv,const vector<SleighSymbol *> &vt);
virtual Constructor *resolve(ParserWalker &walker);
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual int4 getSize(void) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return varnodelist_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class OperandSymbol : public SpecificSymbol {
@ -329,7 +326,7 @@ private:
void setVariableLength(void) { flags |= variable_len; }
bool isVariableLength(void) const { return ((flags&variable_len)!=0); }
public:
OperandSymbol(void) {} // For use with restoreXml
OperandSymbol(void) {} // For use with decode
OperandSymbol(const string &nm,int4 index,Constructor *ct);
uint4 getRelativeOffset(void) const { return reloffset; }
int4 getOffsetBase(void) const { return offsetbase; }
@ -354,16 +351,16 @@ public:
virtual void print(ostream &s,ParserWalker &walker) const;
virtual void collectLocalValues(vector<uintb> &results) const;
virtual symbol_type getType(void) const { return operand_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class StartSymbol : public SpecificSymbol {
AddrSpace *const_space;
PatternExpression *patexp;
public:
StartSymbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
StartSymbol(void) { patexp = (PatternExpression *)0; } // For use with decode
StartSymbol(const string &nm,AddrSpace *cspc);
virtual ~StartSymbol(void);
virtual VarnodeTpl *getVarnode(void) const;
@ -371,16 +368,16 @@ public:
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return start_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class EndSymbol : public SpecificSymbol {
AddrSpace *const_space;
PatternExpression *patexp;
public:
EndSymbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
EndSymbol(void) { patexp = (PatternExpression *)0; } // For use with decode
EndSymbol(const string &nm,AddrSpace *cspc);
virtual ~EndSymbol(void);
virtual VarnodeTpl *getVarnode(void) const;
@ -388,16 +385,16 @@ public:
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return end_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class Next2Symbol : public SpecificSymbol {
AddrSpace *const_space;
PatternExpression *patexp;
public:
Next2Symbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
Next2Symbol(void) { patexp = (PatternExpression *)0; } // For use with decode
Next2Symbol(const string &nm,AddrSpace *cspc);
virtual ~Next2Symbol(void);
virtual VarnodeTpl *getVarnode(void) const;
@ -405,47 +402,41 @@ public:
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return next2_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class FlowDestSymbol : public SpecificSymbol {
AddrSpace *const_space;
public:
FlowDestSymbol(void) {} // For use with restoreXml
FlowDestSymbol(void) {} // For use with decode
FlowDestSymbol(const string &nm,AddrSpace *cspc);
virtual VarnodeTpl *getVarnode(void) const;
virtual PatternExpression *getPatternExpression(void) const { throw SleighError("Cannot use symbol in pattern"); }
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return start_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
};
class FlowRefSymbol : public SpecificSymbol {
AddrSpace *const_space;
public:
FlowRefSymbol(void) {} // For use with restoreXml
FlowRefSymbol(void) {} // For use with decode
FlowRefSymbol(const string &nm,AddrSpace *cspc);
virtual VarnodeTpl *getVarnode(void) const;
virtual PatternExpression *getPatternExpression(void) const { throw SleighError("Cannot use symbol in pattern"); }
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual symbol_type getType(void) const { return start_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
};
class ContextChange { // Change to context command
public:
virtual ~ContextChange(void) {}
virtual void validate(void) const=0;
virtual void saveXml(ostream &s) const=0;
virtual void restoreXml(const Element *el,SleighBase *trans)=0;
virtual void encode(Encoder &encoder) const=0;
virtual void decode(Decoder &decoder,SleighBase *trans)=0;
virtual void apply(ParserWalkerChange &walker) const=0;
virtual ContextChange *clone(void) const=0;
};
@ -457,11 +448,11 @@ class ContextOp : public ContextChange {
int4 shift; // Number of bits to shift value into place
public:
ContextOp(int4 startbit,int4 endbit,PatternExpression *pe);
ContextOp(void) {} // For use with restoreXml
ContextOp(void) {} // For use with decode
virtual ~ContextOp(void) { PatternExpression::release(patexp); }
virtual void validate(void) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
virtual void apply(ParserWalkerChange &walker) const;
virtual ContextChange *clone(void) const;
};
@ -472,11 +463,11 @@ class ContextCommit : public ContextChange {
uintm mask; // mask of bits in word being committed
bool flow; // Whether the context "flows" from the point of change
public:
ContextCommit(void) {} // For use with restoreXml
ContextCommit(void) {} // For use with decode
ContextCommit(TripleSymbol *s,int4 sbit,int4 ebit,bool fl);
virtual void validate(void) const {}
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
virtual void apply(ParserWalkerChange &walker) const;
virtual ContextChange *clone(void) const;
};
@ -500,7 +491,7 @@ class Constructor { // This is NOT a symbol
mutable bool inerror; // An error is associated with this Constructor
void orderOperands(void);
public:
Constructor(void); // For use with restoreXml
Constructor(void); // For use with decode
Constructor(SubtableSymbol *p);
~Constructor(void);
TokenPattern *buildPattern(ostream &s);
@ -542,8 +533,8 @@ public:
void setError(bool val) const { inerror = val; }
bool isError(void) const { return inerror; }
bool isRecursive(void) const;
void saveXml(ostream &s) const;
void restoreXml(const Element *el,SleighBase *trans);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder,SleighBase *trans);
};
class DecisionProperties {
@ -569,15 +560,15 @@ class DecisionNode {
int4 getMaximumLength(bool context);
void consistentValues(vector<uint4> &bins,DisjointPattern *pat);
public:
DecisionNode(void) {} // For use with restoreXml
DecisionNode(void) {} // For use with decode
DecisionNode(DecisionNode *p);
~DecisionNode(void);
Constructor *resolve(ParserWalker &walker) const;
void addConstructorPair(const DisjointPattern *pat,Constructor *ct);
void split(DecisionProperties &props);
void orderPatterns(DecisionProperties &props);
void saveXml(ostream &s) const;
void restoreXml(const Element *el,DecisionNode *par,SubtableSymbol *sub);
void encode(Encoder &encoder) const;
void decode(Decoder &decoder,DecisionNode *par,SubtableSymbol *sub);
};
class SubtableSymbol : public TripleSymbol {
@ -586,7 +577,7 @@ class SubtableSymbol : public TripleSymbol {
vector<Constructor *> construct; // All the Constructors in this table
DecisionNode *decisiontree;
public:
SubtableSymbol(void) { pattern = (TokenPattern *)0; decisiontree = (DecisionNode *)0; } // For use with restoreXml
SubtableSymbol(void) { pattern = (TokenPattern *)0; decisiontree = (DecisionNode *)0; } // For use with decode
SubtableSymbol(const string &nm);
virtual ~SubtableSymbol(void);
bool isBeingBuilt(void) const { return beingbuilt; }
@ -606,9 +597,9 @@ public:
throw SleighError("Cannot use subtable in expression"); }
virtual void collectLocalValues(vector<uintb> &results) const;
virtual symbol_type getType(void) const { return subtable_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
virtual void restoreXml(const Element *el,SleighBase *trans);
virtual void encode(Encoder &encoder) const;
virtual void encodeHeader(Encoder &encoder) const;
virtual void decode(Decoder &decoder,SleighBase *trans);
};
class MacroSymbol : public SleighSymbol { // A user-defined pcode-macro

View file

@ -45,13 +45,15 @@ void AddrSpace::calcScaleMask(void)
/// \param t is the processor translator associated with the new space
/// \param tp is the type of the new space (PROCESSOR, CONSTANT, INTERNAL,...)
/// \param nm is the name of the new space
/// \param bigEnd is \b true for big endian encoding
/// \param size is the (offset encoding) size of the new space
/// \param ws is the number of bytes in an addressable unit
/// \param ind is the integer identifier for the new space
/// \param fl can be 0 or AddrSpace::hasphysical
/// \param dl is the number of rounds to delay heritage for the new space
AddrSpace::AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const string &nm,
uint4 size,uint4 ws, int4 ind,uint4 fl,int4 dl)
/// \param dead is the number of rounds to delay before dead code removal
AddrSpace::AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const string &nm,bool bigEnd,
uint4 size,uint4 ws, int4 ind,uint4 fl,int4 dl,int4 dead)
{
refcount = 0; // No references to this space yet
manage = m;
@ -62,13 +64,13 @@ AddrSpace::AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const s
wordsize = ws;
index = ind;
delay = dl;
deadcodedelay = dl; // Deadcode delay initially starts the same as heritage delay
deadcodedelay = dead;
minimumPointerSize = 0; // (initially) assume pointers must match the space size exactly
shortcut = ' '; // Placeholder meaning shortcut is unassigned
// These are the flags we allow to be set from constructor
flags = (fl & hasphysical);
if (t->isBigEndian())
if (bigEnd)
flags |= big_endian;
flags |= (heritaged | does_deadcode); // Always on unless explicitly turned off in derived constructor
@ -94,24 +96,6 @@ AddrSpace::AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp)
// We let big_endian get set by attribute
}
/// Save the \e name, \e index, \e bigendian, \e delay,
/// \e size, \e wordsize, and \e physical attributes which
/// are common with all address spaces derived from AddrSpace
/// \param s the stream where the attributes are written
void AddrSpace::saveBasicAttributes(ostream &s) const
{
a_v(s,"name",name);
a_v_i(s,"index",index);
a_v_b(s,"bigendian",isBigEndian());
a_v_i(s,"delay",delay);
if (delay != deadcodedelay)
a_v_i(s,"deadcodedelay",deadcodedelay);
a_v_i(s,"size",addressSize);
if (wordsize > 1) a_v_i(s,"wordsize",wordsize);
a_v_b(s,"physical",hasPhysical());
}
/// The logical form of the space is truncated from its actual size
/// Pointers may refer to this original size put the most significant bytes are ignored
/// \param newsize is the size (in bytes) of the truncated (logical) space
@ -310,17 +294,6 @@ uintb AddrSpace::read(const string &s,int4 &size) const
return offset;
}
/// Write a tag fully describing the details of this space
/// suitable for later recovery via decode.
/// \param s is the stream being written
void AddrSpace::saveXml(ostream &s) const
{
s << "<space"; // This implies type=processor
saveBasicAttributes(s);
s << "/>\n";
}
/// Walk attributes of the current element and recover all the properties defining
/// this space. The processor translator, \e trans, and the
/// \e type must already be filled in.
@ -378,7 +351,7 @@ const int4 ConstantSpace::INDEX = 0;
/// \param m is the associated address space manager
/// \param t is the associated processor translator
ConstantSpace::ConstantSpace(AddrSpaceManager *m,const Translate *t)
: AddrSpace(m,t,IPTR_CONSTANT,NAME,sizeof(uintb),1,INDEX,0,0)
: AddrSpace(m,t,IPTR_CONSTANT,NAME,false,sizeof(uintb),1,INDEX,0,0,0)
{
clearFlags(heritaged|does_deadcode|big_endian);
if (HOST_ENDIAN==1) // Endianness always matches host
@ -399,14 +372,6 @@ void ConstantSpace::printRaw(ostream &s,uintb offset) const
s << "0x" << hex << offset;
}
/// The ConstantSpace should never be explicitly saved as it is
/// always built automatically
void ConstantSpace::saveXml(ostream &s) const
{
throw LowlevelError("Should never save the constant space as XML");
}
/// As the ConstantSpace is never saved, it should never get
/// decoded either.
void ConstantSpace::decode(Decoder &decoder)
@ -426,7 +391,7 @@ const int4 OtherSpace::INDEX = 1;
/// \param t is the associated processor translator
/// \param ind is the integer identifier
OtherSpace::OtherSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
: AddrSpace(m,t,IPTR_PROCESSOR,NAME,sizeof(uintb),1,INDEX,0,0)
: AddrSpace(m,t,IPTR_PROCESSOR,NAME,false,sizeof(uintb),1,INDEX,0,0,0)
{
clearFlags(heritaged|does_deadcode);
setFlags(is_otherspace);
@ -445,14 +410,6 @@ void OtherSpace::printRaw(ostream &s,uintb offset) const
s << "0x" << hex << offset;
}
void OtherSpace::saveXml(ostream &s) const
{
s << "<space_other";
saveBasicAttributes(s);
s << "/>\n";
}
const string UniqueSpace::NAME = "unique";
const uint4 UniqueSpace::SIZE = 4;
@ -465,7 +422,7 @@ const uint4 UniqueSpace::SIZE = 4;
/// \param ind is the integer identifier
/// \param fl are attribute flags (currently unused)
UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl)
: AddrSpace(m,t,IPTR_INTERNAL,NAME,SIZE,1,ind,fl,0)
: AddrSpace(m,t,IPTR_INTERNAL,NAME,t->isBigEndian(),SIZE,1,ind,fl,0,0)
{
setFlags(hasphysical);
}
@ -476,14 +433,6 @@ UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t)
setFlags(hasphysical);
}
void UniqueSpace::saveXml(ostream &s) const
{
s << "<space_unique";
saveBasicAttributes(s);
s << "/>\n";
}
const string JoinSpace::NAME = "join";
/// This is the constructor for the \b join space, which is automatically constructed by the
@ -492,7 +441,7 @@ const string JoinSpace::NAME = "join";
/// \param t is the associated processor translator
/// \param ind is the integer identifier
JoinSpace::JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind)
: AddrSpace(m,t,IPTR_JOIN,NAME,sizeof(uintm),1,ind,0,0)
: AddrSpace(m,t,IPTR_JOIN,NAME,t->isBigEndian(),sizeof(uintm),1,ind,0,0,0)
{
// This is a virtual space
// setFlags(hasphysical);
@ -691,12 +640,6 @@ uintb JoinSpace::read(const string &s,int4 &size) const
return rec->getUnified().offset;
}
void JoinSpace::saveXml(ostream &s) const
{
throw LowlevelError("Should never save join space to XML");
}
void JoinSpace::decode(Decoder &decoder)
{
@ -712,16 +655,6 @@ OverlaySpace::OverlaySpace(AddrSpaceManager *m,const Translate *t)
setFlags(overlay);
}
void OverlaySpace::saveXml(ostream &s) const
{
s << "<space_overlay";
a_v(s,"name",name);
a_v_i(s,"index",index);
a_v(s,"base",baseSpace->getName());
s << "/>\n";
}
void OverlaySpace::decode(Decoder &decoder)
{

View file

@ -117,11 +117,11 @@ protected:
void calcScaleMask(void); ///< Calculate scale and mask
void setFlags(uint4 fl); ///< Set a cached attribute
void clearFlags(uint4 fl); ///< Clear a cached attribute
void saveBasicAttributes(ostream &s) const; ///< Write the XML attributes of this space
void decodeBasicAttributes(Decoder &decoder); ///< Read attributes for \b this space from an open XML element
void truncateSpace(uint4 newsize);
public:
AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const string &nm,uint4 size,uint4 ws,int4 ind,uint4 fl,int4 dl);
AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp,const string &nm,bool bigEnd,
uint4 size,uint4 ws,int4 ind,uint4 fl,int4 dl,int4 dead);
AddrSpace(AddrSpaceManager *m,const Translate *t,spacetype tp); ///< For use with decode
virtual ~AddrSpace(void) {} ///< The address space destructor
const string &getName(void) const; ///< Get the name
@ -163,8 +163,7 @@ public:
virtual uintb decodeAttributes(Decoder &decoder,uint4 &size) const; ///< Recover an offset and size
virtual void printRaw(ostream &s,uintb offset) const; ///< Write an address in this space to a stream
virtual uintb read(const string &s,int4 &size) const; ///< Read in an address (and possible size) from a string
virtual void saveXml(ostream &s) const; ///< Write the details of this space as XML
virtual void decode(Decoder &decoder); ///< Recover the details of this space from XML
virtual void decode(Decoder &decoder); ///< Recover the details of this space from a stream
static uintb addressToByte(uintb val,uint4 ws); ///< Scale from addressable units to byte units
static uintb byteToAddress(uintb val,uint4 ws); ///< Scale from byte units to addressable units
@ -190,7 +189,6 @@ public:
ConstantSpace(AddrSpaceManager *m,const Translate *t); ///< Only constructor
virtual int4 overlapJoin(uintb offset,int4 size,AddrSpace *pointSpace,uintb pointOff,int4 pointSkip) const;
virtual void printRaw(ostream &s,uintb offset) const;
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
static const string NAME; ///< Reserved name for the address space
static const int4 INDEX; ///< Reserved index for constant space
@ -202,7 +200,6 @@ public:
OtherSpace(AddrSpaceManager *m, const Translate *t, int4 ind); ///< Constructor
OtherSpace(AddrSpaceManager *m, const Translate *t); ///< For use with decode
virtual void printRaw(ostream &s, uintb offset) const;
virtual void saveXml(ostream &s) const;
static const string NAME; ///< Reserved name for the address space
static const int4 INDEX; ///< Reserved index for the other space
};
@ -220,7 +217,6 @@ class UniqueSpace : public AddrSpace {
public:
UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl); ///< Constructor
UniqueSpace(AddrSpaceManager *m,const Translate *t); ///< For use with decode
virtual void saveXml(ostream &s) const;
static const string NAME; ///< Reserved name for the unique space
static const uint4 SIZE; ///< Fixed size (in bytes) for unique space offsets
};
@ -243,7 +239,6 @@ public:
virtual uintb decodeAttributes(Decoder &decoder,uint4 &size) const;
virtual void printRaw(ostream &s,uintb offset) const;
virtual uintb read(const string &s,int4 &size) const;
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
static const string NAME; ///< Reserved name for the join space
};
@ -261,7 +256,6 @@ class OverlaySpace : public AddrSpace {
public:
OverlaySpace(AddrSpaceManager *m,const Translate *t); ///< Constructor
virtual AddrSpace *getContain(void) const { return baseSpace; }
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
};

View file

@ -56,7 +56,7 @@ void TruncationTag::decode(Decoder &decoder)
/// \param isFormal is the formal stack space indicator
SpacebaseSpace::SpacebaseSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind,int4 sz,
AddrSpace *base,int4 dl,bool isFormal)
: AddrSpace(m,t,IPTR_SPACEBASE,nm,sz,base->getWordSize(),ind,0,dl)
: AddrSpace(m,t,IPTR_SPACEBASE,nm,t->isBigEndian(),sz,base->getWordSize(),ind,0,dl,dl)
{
contain = base;
hasbaseregister = false; // No base register assigned yet
@ -123,15 +123,6 @@ const VarnodeData &SpacebaseSpace::getSpacebaseFull(int4 i) const
return baseOrig;
}
void SpacebaseSpace::saveXml(ostream &s) const
{
s << "<space_base";
saveBasicAttributes(s);
a_v(s,"contain",contain->getName());
s << "/>\n";
}
void SpacebaseSpace::decode(Decoder &decoder)
{

View file

@ -185,7 +185,6 @@ public:
virtual const VarnodeData &getSpacebaseFull(int4 i) const;
virtual bool stackGrowsNegative(void) const { return isNegativeStack; }
virtual AddrSpace *getContain(void) const { return contain; } ///< Return containing space
virtual void saveXml(ostream &s) const;
virtual void decode(Decoder &decoder);
};
@ -235,7 +234,7 @@ class AddrSpaceManager {
vector<JoinRecord *> splitlist; ///< JoinRecords indexed by join address
protected:
AddrSpace *decodeSpace(Decoder &decoder,const Translate *trans); ///< Add a space to the model based an on XML tag
void decodeSpaces(Decoder &decoder,const Translate *trans); ///< Restore address spaces in the model from an XML tag
void decodeSpaces(Decoder &decoder,const Translate *trans); ///< Restore address spaces in the model from a stream
void setDefaultCodeSpace(int4 index); ///< Set the default address space (for code)
void setDefaultDataSpace(int4 index); ///< Set the default address space for data
void setReverseJustified(AddrSpace *spc); ///< Set reverse justified property on this space

View file

@ -598,8 +598,8 @@ const TypeField *Datatype::resolveTruncation(int8 offset,PcodeOp *op,int4 slot,i
return (const TypeField *)0;
}
/// Restore the basic properties (name,size,id) of a data-type from an XML element
/// Properties are read from the attributes of the element
/// Restore the basic properties (name,size,id) of a data-type from a stream.
/// Properties are read from the attributes of the element.
/// \param decoder is the stream decoder
void Datatype::decodeBasic(Decoder &decoder)