mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/GP-4285_CompressedSleigh'
This commit is contained in:
commit
d1dc48547e
207 changed files with 15233 additions and 6055 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
165
Ghidra/Features/Decompiler/src/decompile/cpp/compression.cc
Normal file
165
Ghidra/Features/Decompiler/src/decompile/cpp/compression.cc
Normal 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;
|
||||
}
|
||||
|
||||
}
|
100
Ghidra/Features/Decompiler/src/decompile/cpp/compression.hh
Normal file
100
Ghidra/Features/Decompiler/src/decompile/cpp/compression.hh
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,39 +290,6 @@ void ConstTpl::transfer(const vector<HandleTpl *> ¶ms)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
258
Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.cc
Normal file
258
Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.cc
Normal 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
|
205
Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.hh
Normal file
205
Ghidra/Features/Decompiler/src/decompile/cpp/slaformat.hh
Normal 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
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue