GP-6757 Additional memory fixes

This commit is contained in:
caheckman
2026-04-24 20:54:00 +00:00
parent cfaee5f04f
commit 4e6ba952ea
22 changed files with 1268 additions and 1178 deletions
@@ -742,21 +742,21 @@ void Architecture::decodeDynamicRule(Decoder &decoder)
ProtoModel *Architecture::decodeProto(Decoder &decoder)
{
unique_ptr<ProtoModel> umodel;
unique_ptr<ProtoModel> model;
uint4 elemId = decoder.peekElement();
if (elemId == ELEM_PROTOTYPE)
umodel.reset(new ProtoModel(this));
model.reset(new ProtoModel(this));
else if (elemId == ELEM_RESOLVEPROTOTYPE)
umodel.reset(new ProtoModelMerged(this));
model.reset(new ProtoModelMerged(this));
else
throw LowlevelError("Expecting <prototype> or <resolveprototype> tag");
umodel->decode(decoder);
model->decode(decoder);
ProtoModel *other = getModel(umodel->getName());
ProtoModel *other = getModel(model->getName());
if (other != (ProtoModel *)0)
throw LowlevelError("Duplicate ProtoModel name: " + umodel->getName());
ProtoModel *res = umodel.release();
throw LowlevelError("Duplicate ProtoModel name: " + model->getName());
ProtoModel *res = model.release();
protoModels[res->getName()] = res;
return res;
}
@@ -132,7 +132,10 @@ void CPoolRecord::decode(Decoder &decoder,TypeFactory &typegrp)
if (subId == ELEM_TOKEN)
token = decoder.readString(ATTRIB_CONTENT);
else {
byteDataLen = decoder.readSignedInteger(ATTRIB_LENGTH);
int8 val = decoder.readSignedInteger(ATTRIB_LENGTH);
if (val < 0 || val >= MAX_STRING_SIZE)
throw LowlevelError("Bad constant pool record: bad <data> size");
byteDataLen = val;
istringstream s3(decoder.readString(ATTRIB_CONTENT));
byteData = new uint1[byteDataLen];
for(int4 i=0;i<byteDataLen;++i) {
@@ -4,9 +4,9 @@
* 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.
@@ -79,6 +79,7 @@ private:
Datatype *type; ///< Data-type associated with the object
uint1 *byteData; ///< For string literals, the raw byte data of the string
int4 byteDataLen; ///< The number of bytes in the data for a string literal
static constexpr int8 MAX_STRING_SIZE = 0x100000; ///< Maximum allowed bytes of string in pool
public:
CPoolRecord(void) { type = (Datatype *)0; byteData = (uint1 *)0; } ///< Construct an empty record
~CPoolRecord(void) { if (byteData != (uint1 *)0) delete [] byteData; } ///< Destructor
@@ -2946,24 +2946,24 @@ Database::~Database(void)
void Database::attachScope(Scope *newscope,Scope *parent)
{
unique_ptr<Scope> uscope(newscope);
unique_ptr<Scope> owner(newscope);
if (parent == (Scope *)0) {
if (globalscope != (Scope *)0)
throw LowlevelError("Multiple global scopes");
if (uscope->name.size() != 0)
if (newscope->name.size() != 0)
throw LowlevelError("Global scope does not have empty name");
globalscope = uscope.release();
globalscope = owner.release();
idmap[globalscope->uniqueId] = globalscope;
return;
}
if (uscope->name.size()==0)
if (newscope->name.size()==0)
throw LowlevelError("Non-global scope has empty name");
pair<uint8,Scope *> value(uscope->uniqueId,uscope.get());
pair<uint8,Scope *> value(newscope->uniqueId,newscope);
pair<ScopeMap::iterator,bool> res;
res = idmap.insert(value);
if (res.second==false)
throw RecovError("Duplicate scope id: " + uscope->getFullName());
parent->attachScope(uscope.release());
throw RecovError("Duplicate scope id: " + newscope->getFullName());
parent->attachScope(owner.release());
}
/// Give \b this database the chance to inform existing scopes of any change to the
@@ -3371,18 +3371,18 @@ void Database::decode(Decoder &decoder)
void Database::decodeScope(Decoder &decoder,Scope *newScope)
{
unique_ptr<Scope> uscope(newScope);
unique_ptr<Scope> owner(newScope);
uint4 elemId = decoder.openElement();
if (elemId == ELEM_SCOPE) {
Scope *parentScope = parseParentTag(decoder);
attachScope(uscope.release(),parentScope);
attachScope(owner.release(),parentScope);
newScope->decode(decoder);
}
else {
uscope->decodeWrappingAttributes(decoder);
newScope->decodeWrappingAttributes(decoder);
uint4 subId = decoder.openElement(ELEM_SCOPE);
Scope *parentScope = parseParentTag(decoder);
attachScope(uscope.release(),parentScope);
attachScope(owner.release(),parentScope);
newScope->decode(decoder);
decoder.closeElement(subId);
}
@@ -47,14 +47,6 @@ ElementId ELEM_COMMAND_GETSTRINGDATA = ElementId("command_getstringdata",255);
ElementId ELEM_COMMAND_GETTRACKEDREGISTERS = ElementId("command_gettrackedregisters",256);
ElementId ELEM_COMMAND_GETUSEROPNAME = ElementId("command_getuseropname",257);
/// Catch the signal so the OS doesn't pop up a dialog
/// \param sig is the OS signal (should always be SIGSEGV)
void ArchitectureGhidra::segvHandler(int4 sig)
{
exit(1); // Just die - prevents OS from popping-up a dialog
}
/// All communications between the Ghidra client and the decompiler are surrounded
/// by alignment bursts. A burst is 1 or more zero bytes followed by
/// an 0x01 byte, then followed by a code byte.
@@ -746,6 +738,8 @@ void ArchitectureGhidra::getBytes(uint1 *buf,int4 size,const Address &inaddr)
if (type == 12) {
uint1 *dblbuf = new uint1[size * 2];
sin.read((char *)dblbuf,size*2);
if (sin.gcount() != size*2)
throw JavaError("alignment","Could not read expected number of bytes");
for (int4 i=0; i < size; i++) {
buf[i] = ((dblbuf[i*2]-'A') << 4) | (dblbuf[i*2 + 1]-'A');
}
@@ -4,9 +4,9 @@
* 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.
@@ -155,7 +155,6 @@ public:
void getStringData(vector<uint1> &buffer,const Address &addr,Datatype *ct,int4 maxBytes,bool &isTrunc);
virtual void printMessage(const string &message) const;
static void segvHandler(int4 sig); ///< Handler for a segment violation (SIGSEGV) signal
static int4 readToAnyBurst(istream &s); ///< Read the next message protocol marker
static bool readBoolStream(istream &s); ///< Read a boolean value from the client
static void readStringStream(istream &s,string &res); ///< Receive a string from the client
@@ -4,9 +4,9 @@
* 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.
@@ -505,6 +505,14 @@ void GhidraDecompCapability::initialize(void)
commandmap["setOptions"] = new SetOptions();
}
/// Catch the signal so the OS doesn't pop up a dialog
/// \param sig is the OS signal (should always be SIGSEGV)
static void segvHandler(int4 sig)
{
_exit(1); // Don't do any cleanup, just die - prevents OS from popping-up a dialog
}
} // End namespace ghidra
int main(int argc,char **argv)
@@ -512,7 +520,7 @@ int main(int argc,char **argv)
{
using namespace ghidra;
signal(SIGSEGV, &ArchitectureGhidra::segvHandler); // Exit on SEGV errors
signal(SIGSEGV, &segvHandler); // Exit on SEGV errors
#ifdef _WINDOWS
// Force i/o streams to be in binary mode
_setmode(_fileno(stdin), _O_BINARY);
@@ -964,11 +964,10 @@ string PackedDecode::readString(void)
attributeRead = true;
throw DecoderError("Expecting string attribute");
}
int4 length = readLengthCode(typeByte);
length = readInteger(length);
uint8 length = readInteger(readLengthCode(typeByte));
attributeRead = true;
int4 curLen = curPos.end - curPos.current;
uint8 curLen = curPos.end - curPos.current;
if (curLen >= length) {
string res((const char *)curPos.current,length);
advancePosition(curPos, length);
@@ -1005,10 +1004,9 @@ AddrSpace *PackedDecode::readSpace(void)
getNextByte(curPos);
uint1 typeByte = getNextByte(curPos);
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
int4 res;
AddrSpace *spc;
if (typeCode == TYPECODE_ADDRESSSPACE) {
res = readInteger(readLengthCode(typeByte));
uint8 res = readInteger(readLengthCode(typeByte));
if (res >= spcManager->numSpaces())
throw DecoderError("Invalid address space index");
@@ -4,9 +4,9 @@
* 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.
@@ -231,7 +231,7 @@ static void shift_right(uint4 *arr,int4 size,int4 sa)
///
/// The numerator and denominator, expressed in 32-bit \e digits, are provided.
/// The algorithm calculates the quotient and the remainder is left in the array originally
/// containing the numerator.
/// containing the numerator. We assume m > n > 0 and u[n-1] >= v[n-1] > 0.
/// \param m is the number of 32-bit digits in the numerator
/// \param n is the number of 32-bit digits in the denominator
/// \param u is the numerator and will hold the remainder
@@ -311,8 +311,6 @@ void udiv128(uint8 *numer,uint8 *denom,uint8 *quotient_res,uint8 *remainder_res)
remainder_res[1] = numer[1];
return;
}
u[m] = 0;
m += 1; // Extend u array by 1 to account for normalization
if (n == 1) {
uint4 d = v[0];
uint4 rem = 0;
@@ -325,10 +323,13 @@ void udiv128(uint8 *numer,uint8 *denom,uint8 *quotient_res,uint8 *remainder_res)
u[0] = rem; // Last carry is final remainder
}
else {
u[m] = 0;
m += 1; // Temporarily extend u array by 1 to allow for normalization
knuth_algorithm_d(m,n,u,v,q);
m -= 1; // Remove the extension
}
pack32_64(2,m-n,quotient_res,q);
pack32_64(2,m-1,remainder_res,u);
pack32_64(2,m-n+1,quotient_res,q);
pack32_64(2,m,remainder_res,u);
}
} // End namespace ghidra
@@ -96,7 +96,7 @@ bool VarnodeData::isContiguous(const VarnodeData &lo) const
OpCode PcodeOpRaw::decode(Decoder &decoder,int4 isize,VarnodeData *invar,VarnodeData **outvar)
{
OpCode opcode = (OpCode)decoder.readSignedInteger(ATTRIB_CODE);
OpCode opcode = decoder.readOpcode(ATTRIB_CODE);
uint4 subId = decoder.peekElement();
if (subId == ELEM_VOID) {
decoder.openElement();
@@ -39,6 +39,37 @@ SectionVector::SectionVector(ConstructTpl *rtl,SymbolScope *scope)
main.scope = scope;
}
SectionVector::~SectionVector(void)
{
if (main.section != (ConstructTpl *)0)
delete main.section;
for(int4 i=0;i<named.size();++i) {
ConstructTpl *section = named[i].section;
if (section != (ConstructTpl *)0)
delete section;
}
}
/// \return the p-code template for the main section
ConstructTpl *SectionVector::releaseMainSection(void)
{
ConstructTpl *res = main.section;
main.section = (ConstructTpl *)0;
return res;
}
/// \param index is the index of the requested section
/// \return the p-code template for the section
ConstructTpl *SectionVector::releaseNamedSection(int4 index)
{
ConstructTpl *res = named[index].section;
named[index].section = (ConstructTpl *)0;
return res;
}
/// Associate the new section with \b nextindex, established prior to parsing
/// \param rtl is the \e named section of p-code
/// \param scope is the associated symbol scope
@@ -3688,10 +3719,10 @@ void SleighCompile::buildConstructor(Constructor *big,PatternEquation *pateq,vec
if (vec != (SectionVector *)0) { // If the sections were implemented
noerrors = finalizeSections(big,vec);
if (noerrors) { // Attach the sections to the Constructor
big->setMainSection(vec->getMainSection());
big->setMainSection(vec->releaseMainSection());
int4 max = vec->getMaxId();
for(int4 i=0;i<max;++i) {
ConstructTpl *section = vec->getNamedSection(i);
ConstructTpl *section = vec->releaseNamedSection(i);
if (section != (ConstructTpl *)0)
big->setNamedSection(section,i);
}
@@ -3708,6 +3739,9 @@ void SleighCompile::buildConstructor(Constructor *big,PatternEquation *pateq,vec
delete contvec;
}
}
else {
PatternEquation::release(pateq);
}
symtab.popScope(); // In all cases pop scope
}
@@ -3768,6 +3802,7 @@ int4 SleighCompile::run_compilation(const string &filein,const string &fileout)
try {
int4 parseres = sleighparse(); // Try to parse
fclose(sleighin);
sleighlex_destroy(); // Make sure lexer is reset so we can parse multiple files
if (parseres==0)
process(); // Do all the post-processing
if ((parseres==0)&&(numErrors()==0)) { // If no errors
@@ -3794,7 +3829,6 @@ int4 SleighCompile::run_compilation(const string &filein,const string &fileout)
cerr << "No output produced" <<endl;
return 2;
}
sleighlex_destroy(); // Make sure lexer is reset so we can parse multiple files
} catch(LowlevelError &err) {
cerr << "Unrecoverable error: " << err.explain << endl;
return 2;
@@ -60,14 +60,15 @@ class SectionVector {
RtlPair main; ///< The main section
vector<RtlPair> named; ///< Named sections accessed by index
public:
SectionVector(ConstructTpl *rtl,SymbolScope *scope); ///< Constructor
ConstructTpl *getMainSection(void) const { return main.section; } ///< Get the \e main section
ConstructTpl *getNamedSection(int4 index) const { return named[index].section; } ///< Get a \e named section by index
RtlPair getMainPair(void) const { return main; } ///< Get the \e main section/namespace pair
RtlPair getNamedPair(int4 i) const { return named[i]; } ///< Get a \e named section/namespace pair by index
void setNextIndex(int4 i) { nextindex = i; } ///< Set the index of the currently parsing \e named section
int4 getMaxId(void) const { return named.size(); } ///< Get the maximum (exclusive) named section index
void append(ConstructTpl *rtl,SymbolScope *scope); ///< Add a new \e named section
SectionVector(ConstructTpl *rtl,SymbolScope *scope); ///< Constructor
~SectionVector(void); ///< Destructor
ConstructTpl *releaseMainSection(void); ///< Get the \e main section, giving up ownership
ConstructTpl *releaseNamedSection(int4 index); ///< Get a \e named section by index, giving up ownership
RtlPair getMainPair(void) const { return main; } ///< Get the \e main section/namespace pair
RtlPair getNamedPair(int4 i) const { return named[i]; } ///< Get a \e named section/namespace pair by index
void setNextIndex(int4 i) { nextindex = i; } ///< Set the index of the currently parsing \e named section
int4 getMaxId(void) const { return named.size(); } ///< Get the maximum (exclusive) named section index
void append(ConstructTpl *rtl,SymbolScope *scope); ///< Add a new \e named section
};
/// \brief Qualities associated (via parsing) with an address space
File diff suppressed because it is too large Load Diff
@@ -4,16 +4,16 @@
* 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.
*/
/* A Bison parser, made by GNU Bison 3.5.1. */
/* A Bison parser, made by GNU Bison 3.7.4. */
/* Bison interface for Yacc-like parsers in C
@@ -46,8 +46,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_SLEIGH_SLGHPARSE_HH_INCLUDED
# define YY_SLEIGH_SLGHPARSE_HH_INCLUDED
@@ -67,123 +68,128 @@
extern int sleighdebug;
#endif
/* Token type. */
/* Token kinds. */
#ifndef SLEIGHTOKENTYPE
# define SLEIGHTOKENTYPE
enum sleightokentype
{
OP_BOOL_OR = 258,
OP_BOOL_AND = 259,
OP_BOOL_XOR = 260,
OP_OR = 261,
OP_XOR = 262,
OP_AND = 263,
OP_EQUAL = 264,
OP_NOTEQUAL = 265,
OP_FEQUAL = 266,
OP_FNOTEQUAL = 267,
OP_GREATEQUAL = 268,
OP_LESSEQUAL = 269,
OP_SLESS = 270,
OP_SGREATEQUAL = 271,
OP_SLESSEQUAL = 272,
OP_SGREAT = 273,
OP_FLESS = 274,
OP_FGREAT = 275,
OP_FLESSEQUAL = 276,
OP_FGREATEQUAL = 277,
OP_LEFT = 278,
OP_RIGHT = 279,
OP_SRIGHT = 280,
OP_FADD = 281,
OP_FSUB = 282,
OP_SDIV = 283,
OP_SREM = 284,
OP_FMULT = 285,
OP_FDIV = 286,
OP_ZEXT = 287,
OP_CARRY = 288,
OP_BORROW = 289,
OP_SEXT = 290,
OP_SCARRY = 291,
OP_SBORROW = 292,
OP_NAN = 293,
OP_ABS = 294,
OP_SQRT = 295,
OP_CEIL = 296,
OP_FLOOR = 297,
OP_ROUND = 298,
OP_INT2FLOAT = 299,
OP_FLOAT2FLOAT = 300,
OP_TRUNC = 301,
OP_CPOOLREF = 302,
OP_NEW = 303,
OP_POPCOUNT = 304,
OP_LZCOUNT = 305,
BADINTEGER = 306,
GOTO_KEY = 307,
CALL_KEY = 308,
RETURN_KEY = 309,
IF_KEY = 310,
DEFINE_KEY = 311,
ATTACH_KEY = 312,
MACRO_KEY = 313,
SPACE_KEY = 314,
TYPE_KEY = 315,
RAM_KEY = 316,
DEFAULT_KEY = 317,
REGISTER_KEY = 318,
ENDIAN_KEY = 319,
WITH_KEY = 320,
ALIGN_KEY = 321,
OP_UNIMPL = 322,
TOKEN_KEY = 323,
SIGNED_KEY = 324,
NOFLOW_KEY = 325,
HEX_KEY = 326,
DEC_KEY = 327,
BIG_KEY = 328,
LITTLE_KEY = 329,
SIZE_KEY = 330,
WORDSIZE_KEY = 331,
OFFSET_KEY = 332,
NAMES_KEY = 333,
VALUES_KEY = 334,
VARIABLES_KEY = 335,
PCODEOP_KEY = 336,
IS_KEY = 337,
LOCAL_KEY = 338,
DELAYSLOT_KEY = 339,
CROSSBUILD_KEY = 340,
EXPORT_KEY = 341,
BUILD_KEY = 342,
CONTEXT_KEY = 343,
ELLIPSIS_KEY = 344,
GLOBALSET_KEY = 345,
BITRANGE_KEY = 346,
CHAR = 347,
INTEGER = 348,
INTB = 349,
STRING = 350,
SYMBOLSTRING = 351,
SPACESYM = 352,
SECTIONSYM = 353,
TOKENSYM = 354,
USEROPSYM = 355,
VALUESYM = 356,
VALUEMAPSYM = 357,
CONTEXTSYM = 358,
NAMESYM = 359,
VARSYM = 360,
BITSYM = 361,
SPECSYM = 362,
VARLISTSYM = 363,
OPERANDSYM = 364,
JUMPSYM = 365,
MACROSYM = 366,
LABELSYM = 367,
SUBTABLESYM = 368
SLEIGHEMPTY = -2,
SLEIGHEOF = 0, /* "end of file" */
SLEIGHerror = 256, /* error */
SLEIGHUNDEF = 257, /* "invalid token" */
OP_BOOL_OR = 258, /* OP_BOOL_OR */
OP_BOOL_AND = 259, /* OP_BOOL_AND */
OP_BOOL_XOR = 260, /* OP_BOOL_XOR */
OP_OR = 261, /* OP_OR */
OP_XOR = 262, /* OP_XOR */
OP_AND = 263, /* OP_AND */
OP_EQUAL = 264, /* OP_EQUAL */
OP_NOTEQUAL = 265, /* OP_NOTEQUAL */
OP_FEQUAL = 266, /* OP_FEQUAL */
OP_FNOTEQUAL = 267, /* OP_FNOTEQUAL */
OP_GREATEQUAL = 268, /* OP_GREATEQUAL */
OP_LESSEQUAL = 269, /* OP_LESSEQUAL */
OP_SLESS = 270, /* OP_SLESS */
OP_SGREATEQUAL = 271, /* OP_SGREATEQUAL */
OP_SLESSEQUAL = 272, /* OP_SLESSEQUAL */
OP_SGREAT = 273, /* OP_SGREAT */
OP_FLESS = 274, /* OP_FLESS */
OP_FGREAT = 275, /* OP_FGREAT */
OP_FLESSEQUAL = 276, /* OP_FLESSEQUAL */
OP_FGREATEQUAL = 277, /* OP_FGREATEQUAL */
OP_LEFT = 278, /* OP_LEFT */
OP_RIGHT = 279, /* OP_RIGHT */
OP_SRIGHT = 280, /* OP_SRIGHT */
OP_FADD = 281, /* OP_FADD */
OP_FSUB = 282, /* OP_FSUB */
OP_SDIV = 283, /* OP_SDIV */
OP_SREM = 284, /* OP_SREM */
OP_FMULT = 285, /* OP_FMULT */
OP_FDIV = 286, /* OP_FDIV */
OP_ZEXT = 287, /* OP_ZEXT */
OP_CARRY = 288, /* OP_CARRY */
OP_BORROW = 289, /* OP_BORROW */
OP_SEXT = 290, /* OP_SEXT */
OP_SCARRY = 291, /* OP_SCARRY */
OP_SBORROW = 292, /* OP_SBORROW */
OP_NAN = 293, /* OP_NAN */
OP_ABS = 294, /* OP_ABS */
OP_SQRT = 295, /* OP_SQRT */
OP_CEIL = 296, /* OP_CEIL */
OP_FLOOR = 297, /* OP_FLOOR */
OP_ROUND = 298, /* OP_ROUND */
OP_INT2FLOAT = 299, /* OP_INT2FLOAT */
OP_FLOAT2FLOAT = 300, /* OP_FLOAT2FLOAT */
OP_TRUNC = 301, /* OP_TRUNC */
OP_CPOOLREF = 302, /* OP_CPOOLREF */
OP_NEW = 303, /* OP_NEW */
OP_POPCOUNT = 304, /* OP_POPCOUNT */
OP_LZCOUNT = 305, /* OP_LZCOUNT */
BADINTEGER = 306, /* BADINTEGER */
GOTO_KEY = 307, /* GOTO_KEY */
CALL_KEY = 308, /* CALL_KEY */
RETURN_KEY = 309, /* RETURN_KEY */
IF_KEY = 310, /* IF_KEY */
DEFINE_KEY = 311, /* DEFINE_KEY */
ATTACH_KEY = 312, /* ATTACH_KEY */
MACRO_KEY = 313, /* MACRO_KEY */
SPACE_KEY = 314, /* SPACE_KEY */
TYPE_KEY = 315, /* TYPE_KEY */
RAM_KEY = 316, /* RAM_KEY */
DEFAULT_KEY = 317, /* DEFAULT_KEY */
REGISTER_KEY = 318, /* REGISTER_KEY */
ENDIAN_KEY = 319, /* ENDIAN_KEY */
WITH_KEY = 320, /* WITH_KEY */
ALIGN_KEY = 321, /* ALIGN_KEY */
OP_UNIMPL = 322, /* OP_UNIMPL */
TOKEN_KEY = 323, /* TOKEN_KEY */
SIGNED_KEY = 324, /* SIGNED_KEY */
NOFLOW_KEY = 325, /* NOFLOW_KEY */
HEX_KEY = 326, /* HEX_KEY */
DEC_KEY = 327, /* DEC_KEY */
BIG_KEY = 328, /* BIG_KEY */
LITTLE_KEY = 329, /* LITTLE_KEY */
SIZE_KEY = 330, /* SIZE_KEY */
WORDSIZE_KEY = 331, /* WORDSIZE_KEY */
OFFSET_KEY = 332, /* OFFSET_KEY */
NAMES_KEY = 333, /* NAMES_KEY */
VALUES_KEY = 334, /* VALUES_KEY */
VARIABLES_KEY = 335, /* VARIABLES_KEY */
PCODEOP_KEY = 336, /* PCODEOP_KEY */
IS_KEY = 337, /* IS_KEY */
LOCAL_KEY = 338, /* LOCAL_KEY */
DELAYSLOT_KEY = 339, /* DELAYSLOT_KEY */
CROSSBUILD_KEY = 340, /* CROSSBUILD_KEY */
EXPORT_KEY = 341, /* EXPORT_KEY */
BUILD_KEY = 342, /* BUILD_KEY */
CONTEXT_KEY = 343, /* CONTEXT_KEY */
ELLIPSIS_KEY = 344, /* ELLIPSIS_KEY */
GLOBALSET_KEY = 345, /* GLOBALSET_KEY */
BITRANGE_KEY = 346, /* BITRANGE_KEY */
CHAR = 347, /* CHAR */
INTEGER = 348, /* INTEGER */
INTB = 349, /* INTB */
STRING = 350, /* STRING */
SYMBOLSTRING = 351, /* SYMBOLSTRING */
SPACESYM = 352, /* SPACESYM */
SECTIONSYM = 353, /* SECTIONSYM */
TOKENSYM = 354, /* TOKENSYM */
USEROPSYM = 355, /* USEROPSYM */
VALUESYM = 356, /* VALUESYM */
VALUEMAPSYM = 357, /* VALUEMAPSYM */
CONTEXTSYM = 358, /* CONTEXTSYM */
NAMESYM = 359, /* NAMESYM */
VARSYM = 360, /* VARSYM */
BITSYM = 361, /* BITSYM */
SPECSYM = 362, /* SPECSYM */
VARLISTSYM = 363, /* VARLISTSYM */
OPERANDSYM = 364, /* OPERANDSYM */
JUMPSYM = 365, /* JUMPSYM */
MACROSYM = 366, /* MACROSYM */
LABELSYM = 367, /* LABELSYM */
SUBTABLESYM = 368 /* SUBTABLESYM */
};
typedef enum sleightokentype sleightoken_kind_t;
#endif
/* Value type. */
@@ -151,6 +151,14 @@ extern int sleigherror(const char *str );
%type <specsym> specificsymbol
%type <subtablesym> id_or_nil
%destructor { delete $$; } INTEGER INTB STRING SYMBOLSTRING
%destructor { delete $$; } paramlist rtl rtlmid rtlbody rtlfirstsection rtlcontinue statement expr
%destructor { delete $$; } varnode integervarnode exportvarnode lhsvarnode jumpdest charstring
%destructor { if ($$) PatternEquation::release($$); } pequation elleq ellrt atomic constraint bitpat_or_nil
%destructor { PatternExpression::release($$); } pexpression
%destructor { delete $$; } spaceprop fielddef contextfielddef sizedstar stringlist stringpart anystringlist anystringpart
%destructor { delete $$; } oplist intblist intbpart valuelist valuepart varlist varpart contextlist contextblock
%%
spec: endiandef
| spec aligndef
@@ -193,13 +201,13 @@ contextprop: DEFINE_KEY CONTEXT_KEY VARSYM { $$ = $3; }
{ slgh->reportError("All context definitions must come before constructors"); YYERROR; } }
;
fielddef: STRING '=' '(' INTEGER ',' INTEGER ')' { $$ = new FieldQuality($1,$4,$6); }
| anysymbol '=' '(' INTEGER ',' INTEGER ')' { delete $4; delete $6; string errmsg = $1->getName()+": redefined as field"; slgh->reportError(errmsg); YYERROR; }
| anysymbol '=' '(' INTEGER ',' INTEGER ')' { $$ = (FieldQuality *)0; delete $4; delete $6; string errmsg = $1->getName()+": redefined as field"; slgh->reportError(errmsg); YYERROR; }
| fielddef SIGNED_KEY { $$ = $1; $$->signext = true; }
| fielddef HEX_KEY { $$ = $1; $$->hex = true; }
| fielddef DEC_KEY { $$ = $1; $$->hex = false; }
;
contextfielddef: STRING '=' '(' INTEGER ',' INTEGER ')' { $$ = new FieldQuality($1,$4,$6); }
| anysymbol '=' '(' INTEGER ',' INTEGER ')' { delete $4; delete $6; string errmsg = $1->getName()+": redefined as field"; slgh->reportError(errmsg); YYERROR; }
| anysymbol '=' '(' INTEGER ',' INTEGER ')' { $$ = (FieldQuality *)0; delete $4; delete $6; string errmsg = $1->getName()+": redefined as field"; slgh->reportError(errmsg); YYERROR; }
| contextfielddef SIGNED_KEY { $$ = $1; $$->signext = true; }
| contextfielddef NOFLOW_KEY { $$ = $1; $$->flow = false; }
| contextfielddef HEX_KEY { $$ = $1; $$->hex = true; }
@@ -208,7 +216,7 @@ contextfielddef: STRING '=' '(' INTEGER ',' INTEGER ')' { $$ = new FieldQuality(
spacedef: spaceprop ';' { slgh->newSpace($1); }
;
spaceprop: DEFINE_KEY SPACE_KEY STRING { $$ = new SpaceQuality(*$3); delete $3; }
| DEFINE_KEY SPACE_KEY anysymbol { string errmsg = $3->getName()+": redefined as space"; slgh->reportError(errmsg); YYERROR; }
| DEFINE_KEY SPACE_KEY anysymbol { $$ = (SpaceQuality *)0; string errmsg = $3->getName()+": redefined as space"; slgh->reportError(errmsg); YYERROR; }
| spaceprop TYPE_KEY '=' RAM_KEY { $$ = $1; $$->type = SpaceQuality::ramtype; }
| spaceprop TYPE_KEY '=' REGISTER_KEY { $$ = $1; $$->type = SpaceQuality::registertype; }
| spaceprop SIZE_KEY '=' INTEGER { $$ = $1; $$->size = *$4; delete $4; }
@@ -330,11 +338,11 @@ contextblock: { $$ = (vector<ContextChange *> *)0; }
| '[' contextlist ']' { $$ = $2; }
;
contextlist: { $$ = new vector<ContextChange *>; }
| contextlist CONTEXTSYM '=' pexpression ';' { $$ = $1; if (!slgh->contextMod($1,$2,$4)) { string errmsg="Cannot use 'inst_next' or 'inst_next2' to set context variable: "+$2->getName(); slgh->reportError(errmsg); YYERROR; } }
| contextlist CONTEXTSYM '=' pexpression ';' { $$ = $1; if (!slgh->contextMod($1,$2,$4)) { string errmsg="Cannot use 'inst_next' or 'inst_next2' to set context variable: "+$2->getName(); slgh->reportError(errmsg); delete $1; $4->layClaim(); PatternExpression::release($4); YYERROR; } }
| contextlist GLOBALSET_KEY '(' familysymbol ',' CONTEXTSYM ')' ';' { $$ = $1; slgh->contextSet($1,$4,$6); }
| contextlist GLOBALSET_KEY '(' specificsymbol ',' CONTEXTSYM ')' ';' { $$ = $1; slgh->contextSet($1,$4,$6); }
| contextlist OPERANDSYM '=' pexpression ';' { $$ = $1; slgh->defineOperand($2,$4); }
| contextlist STRING { string errmsg="Expecting context symbol, not "+*$2; delete $2; slgh->reportError(errmsg); YYERROR; }
| contextlist STRING { $$ = (vector<ContextChange *> *)0; delete $1; string errmsg="Expecting context symbol, not "+*$2; delete $2; slgh->reportError(errmsg); YYERROR; }
;
section_def: OP_LEFT STRING OP_RIGHT { $$ = slgh->newSectionSymbol( *$2 ); delete $2; }
| OP_LEFT SECTIONSYM OP_RIGHT { $$ = $2; }
@@ -347,11 +355,11 @@ rtlcontinue: rtlfirstsection { $$ = $1; }
rtl: rtlmid { $$ = $1; if ($$->getOpvec().empty() && ($$->getResult() == (HandleTpl *)0)) slgh->recordNop(); }
| rtlmid EXPORT_KEY exportvarnode ';' { $$ = slgh->setResultVarnode($1,$3); }
| rtlmid EXPORT_KEY sizedstar lhsvarnode ';' { $$ = slgh->setResultStarVarnode($1,$3,$4); }
| rtlmid EXPORT_KEY STRING { string errmsg="Unknown export varnode: "+*$3; delete $3; slgh->reportError(errmsg); YYERROR; }
| rtlmid EXPORT_KEY sizedstar STRING { string errmsg="Unknown pointer varnode: "+*$4; delete $3; delete $4; slgh->reportError(errmsg); YYERROR; }
| rtlmid EXPORT_KEY STRING { $$ = (ConstructTpl *)0; delete $1; string errmsg="Unknown export varnode: "+*$3; delete $3; slgh->reportError(errmsg); YYERROR; }
| rtlmid EXPORT_KEY sizedstar STRING { $$ = (ConstructTpl *)0; delete $1; string errmsg="Unknown pointer varnode: "+*$4; delete $3; delete $4; slgh->reportError(errmsg); YYERROR; }
;
rtlmid: /* EMPTY */ { $$ = slgh->enterSection(); }
| rtlmid statement { $$ = $1; if (!$$->addOpList(*$2)) { delete $2; slgh->reportError("Multiple delayslot declarations"); YYERROR; } delete $2; }
| rtlmid statement { $$ = $1; if (!$$->addOpList(*$2)) { delete $1; delete $2; slgh->reportError("Multiple delayslot declarations"); YYERROR; } delete $2; }
| rtlmid LOCAL_KEY STRING ';' { $$ = $1; slgh->pcode.newLocalDefinition($3); }
| rtlmid LOCAL_KEY STRING ':' INTEGER ';' { $$ = $1; slgh->pcode.newLocalDefinition($3,*$5); delete $5; }
;
@@ -365,8 +373,8 @@ statement: lhsvarnode '=' expr ';' { $3->setOutput($1); $$ = ExprTree::toVector(
| USEROPSYM '(' paramlist ')' ';' { $$ = slgh->pcode.createUserOpNoOut($1,$3); }
| lhsvarnode '[' INTEGER ',' INTEGER ']' '=' expr ';' { $$ = slgh->pcode.assignBitRange($1,(uint4)*$3,(uint4)*$5,$8); delete $3, delete $5; }
| BITSYM '=' expr ';' { $$=slgh->pcode.assignBitRange($1->getParentSymbol()->getVarnode(),$1->getBitOffset(),$1->numBits(),$3); }
| varnode ':' INTEGER '=' { delete $1; delete $3; slgh->reportError("Illegal truncation on left-hand side of assignment"); YYERROR; }
| varnode '(' INTEGER ')' { delete $1; delete $3; slgh->reportError("Illegal subpiece on left-hand side of assignment"); YYERROR; }
| varnode ':' INTEGER '=' { $$ = (vector<OpTpl *> *)0; delete $1; delete $3; slgh->reportError("Illegal truncation on left-hand side of assignment"); YYERROR; }
| varnode '(' INTEGER ')' { $$ = (vector<OpTpl *> *)0; delete $1; delete $3; slgh->reportError("Illegal subpiece on left-hand side of assignment"); YYERROR; }
| BUILD_KEY OPERANDSYM ';' { $$ = slgh->pcode.createOpConst(BUILD,$2->getIndex()); }
| CROSSBUILD_KEY varnode ',' SECTIONSYM ';' { $$ = slgh->createCrossBuild($2,$4); }
| CROSSBUILD_KEY varnode ',' STRING ';' { $$ = slgh->createCrossBuild($2,slgh->newSectionSymbol(*$4)); delete $4; }
@@ -376,7 +384,7 @@ statement: lhsvarnode '=' expr ';' { $3->setOutput($1); $$ = ExprTree::toVector(
| GOTO_KEY '[' expr ']' ';' { $$ = slgh->pcode.createOpNoOut(CPUI_BRANCHIND,$3); }
| CALL_KEY jumpdest ';' { $$ = slgh->pcode.createOpNoOut(CPUI_CALL,new ExprTree($2)); }
| CALL_KEY '[' expr ']' ';' { $$ = slgh->pcode.createOpNoOut(CPUI_CALLIND,$3); }
| RETURN_KEY ';' { slgh->reportError("Must specify an indirect parameter for return"); YYERROR; }
| RETURN_KEY ';' { $$ = (vector<OpTpl *> *)0; slgh->reportError("Must specify an indirect parameter for return"); YYERROR; }
| RETURN_KEY '[' expr ']' ';' { $$ = slgh->pcode.createOpNoOut(CPUI_RETURN,$3); }
| MACROSYM '(' paramlist ')' ';' { $$ = slgh->createMacroUse($1,$3); }
| label { $$ = slgh->pcode.placeLabel( $1 ); }
@@ -447,7 +455,7 @@ expr: varnode { $$ = new ExprTree($1); }
| specificsymbol '[' INTEGER ',' INTEGER ']' { $$ = slgh->pcode.createBitRange($1,(uint4)*$3,(uint4)*$5); delete $3, delete $5; }
| BITSYM { $$=slgh->pcode.createBitRange($1->getParentSymbol(),$1->getBitOffset(),$1->numBits()); }
| USEROPSYM '(' paramlist ')' { $$ = slgh->pcode.createUserOp($1,$3); }
| OP_CPOOLREF '(' paramlist ')' { if ((*$3).size() < 2) { string errmsg = "Must at least two inputs to cpool"; slgh->reportError(errmsg); YYERROR; } $$ = slgh->pcode.createVariadic(CPUI_CPOOLREF,$3); }
| OP_CPOOLREF '(' paramlist ')' { if ((*$3).size() < 2) { string errmsg = "Must be at least two inputs to cpool"; slgh->reportError(errmsg); delete $3; YYERROR; } $$ = slgh->pcode.createVariadic(CPUI_CPOOLREF,$3); }
;
sizedstar: '*' '[' SPACESYM ']' ':' INTEGER { $$ = new StarQuality; $$->size = *$6; delete $6; $$->id=ConstTpl($3->getSpace()); }
| '*' '[' SPACESYM ']' { $$ = new StarQuality; $$->size = 0; $$->id=ConstTpl($3->getSpace()); }
@@ -460,12 +468,12 @@ jumpdest: JUMPSYM { VarnodeTpl *sym = $1->getVarnode(); $$ = new VarnodeTpl(Con
| OPERANDSYM { $$ = $1->getVarnode(); $1->setCodeAddress(); }
| INTEGER '[' SPACESYM ']' { AddrSpace *spc = $3->getSpace(); $$ = new VarnodeTpl(ConstTpl(spc),ConstTpl(ConstTpl::real,*$1),ConstTpl(ConstTpl::real,spc->getAddrSize())); delete $1; }
| label { $$ = new VarnodeTpl(ConstTpl(slgh->getConstantSpace()),ConstTpl(ConstTpl::j_relative,$1->getIndex()),ConstTpl(ConstTpl::real,sizeof(uintm))); $1->incrementRefCount(); }
| STRING { string errmsg = "Unknown jump destination: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| STRING { $$ = (VarnodeTpl *)0; string errmsg = "Unknown jump destination: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
;
varnode: specificsymbol { $$ = $1->getVarnode(); }
| integervarnode { $$ = $1; }
| STRING { string errmsg = "Unknown varnode parameter: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
| STRING { $$ = (VarnodeTpl *)0; string errmsg = "Unknown varnode parameter: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { $$ = (VarnodeTpl *)0; string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
;
integervarnode: INTEGER { $$ = new VarnodeTpl(ConstTpl(slgh->getConstantSpace()),ConstTpl(ConstTpl::real,*$1),ConstTpl(ConstTpl::real,0)); delete $1; }
| BADINTEGER { $$ = new VarnodeTpl(ConstTpl(slgh->getConstantSpace()),ConstTpl(ConstTpl::real,0),ConstTpl(ConstTpl::real,0)); slgh->reportError("Parsed integer is too big (overflow)"); }
@@ -474,8 +482,8 @@ integervarnode: INTEGER { $$ = new VarnodeTpl(ConstTpl(slgh->getConstantSpace()
| '&' ':' INTEGER varnode { $$ = slgh->pcode.addressOf($4,*$3); delete $3; }
;
lhsvarnode: specificsymbol { $$ = $1->getVarnode(); }
| STRING { string errmsg = "Unknown assignment varnode: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
| STRING { $$ = (VarnodeTpl *)0; string errmsg = "Unknown assignment varnode: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { $$ = (VarnodeTpl *)0; string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
;
label: '<' LABELSYM '>' { $$ = $2; }
| '<' STRING '>' { $$ = slgh->pcode.defineLabel( $2 ); }
@@ -484,8 +492,8 @@ exportvarnode: specificsymbol { $$ = $1->getVarnode(); }
| '&' varnode { $$ = slgh->pcode.addressOf($2,0); }
| '&' ':' INTEGER varnode { $$ = slgh->pcode.addressOf($4,*$3); delete $3; }
| INTEGER ':' INTEGER { $$ = new VarnodeTpl(ConstTpl(slgh->getConstantSpace()),ConstTpl(ConstTpl::real,*$1),ConstTpl(ConstTpl::real,*$3)); delete $1; delete $3; }
| STRING { string errmsg="Unknown export varnode: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
| STRING { $$ = (VarnodeTpl *)0; string errmsg="Unknown export varnode: "+*$1; delete $1; slgh->reportError(errmsg); YYERROR; }
| SUBTABLESYM { $$ = (VarnodeTpl *)0; string errmsg = "Subtable not attached to operand: "+$1->getName(); slgh->reportError(errmsg); YYERROR; }
;
familysymbol: VALUESYM { $$ = $1; }
| VALUEMAPSYM { $$ = $1; }
@@ -511,7 +519,7 @@ intbpart: INTEGER { $$ = new vector<intb>; $$->push_back(intb(*$1)); delete $1;
$$ = new vector<intb>; $$->push_back((intb)0xBADBEEF); delete $1; }
| intbpart INTEGER { $$ = $1; $$->push_back(intb(*$2)); delete $2; }
| intbpart '-' INTEGER { $$ = $1; $$->push_back(-intb(*$3)); delete $3; }
| intbpart STRING { if (*$2!="_") { string errmsg = "Expecting integer but saw: "+*$2; delete $2; slgh->reportError(errmsg); YYERROR; }
| intbpart STRING { if (*$2!="_") { string errmsg = "Expecting integer but saw: "+*$2; delete $1; delete $2; slgh->reportError(errmsg); YYERROR; }
$$ = $1; $$->push_back((intb)0xBADBEEF); delete $2; }
;
stringlist: '[' stringpart ']' { $$ = $2; }
@@ -519,7 +527,7 @@ stringlist: '[' stringpart ']' { $$ = $2; }
;
stringpart: STRING { $$ = new vector<string>; $$->push_back( *$1 ); delete $1; }
| stringpart STRING { $$ = $1; $$->push_back(*$2); delete $2; }
| stringpart anysymbol { string errmsg = $2->getName()+": redefined"; slgh->reportError(errmsg); YYERROR; }
| stringpart anysymbol { $$ = (vector<string> *)0; delete $1; string errmsg = $2->getName()+": redefined"; slgh->reportError(errmsg); YYERROR; }
;
anystringlist: '[' anystringpart ']' { $$ = $2; }
;
@@ -536,7 +544,7 @@ valuepart: VALUESYM { $$ = new vector<SleighSymbol *>; $$->push_back( $1 ); }
| CONTEXTSYM { $$ = new vector<SleighSymbol *>; $$->push_back($1); }
| valuepart VALUESYM { $$ = $1; $$->push_back($2); }
| valuepart CONTEXTSYM { $$ = $1; $$->push_back($2); }
| valuepart STRING { string errmsg = *$2+": is not a value pattern"; delete $2; slgh->reportError(errmsg); YYERROR; }
| valuepart STRING { $$ = (vector<SleighSymbol *> *)0; delete $1; string errmsg = *$2+": is not a value pattern"; delete $2; slgh->reportError(errmsg); YYERROR; }
;
varlist: '[' varpart ']' { $$ = $2; }
| VARSYM { $$ = new vector<SleighSymbol *>; $$->push_back($1); }
@@ -545,7 +553,7 @@ varpart: VARSYM { $$ = new vector<SleighSymbol *>; $$->push_back($1); }
| STRING { if (*$1!="_") { string errmsg = *$1+": is not a varnode symbol"; delete $1; slgh->reportError(errmsg); YYERROR; }
$$ = new vector<SleighSymbol *>; $$->push_back((SleighSymbol *)0); delete $1; }
| varpart VARSYM { $$ = $1; $$->push_back($2); }
| varpart STRING { if (*$2!="_") { string errmsg = *$2+": is not a varnode symbol"; delete $2; slgh->reportError(errmsg); YYERROR; }
| varpart STRING { if (*$2!="_") { string errmsg = *$2+": is not a varnode symbol"; delete $1; delete $2; slgh->reportError(errmsg); YYERROR; }
$$ = $1; $$->push_back((SleighSymbol *)0); delete $2; }
;
paramlist: /* EMPTY */ { $$ = new vector<ExprTree *>; }
@@ -141,17 +141,16 @@ bool DisjointPattern::resolvesIntersect(const DisjointPattern *op1,const Disjoin
DisjointPattern *DisjointPattern::decodeDisjoint(Decoder &decoder)
{ // DisjointPattern factory
DisjointPattern *res;
unique_ptr<DisjointPattern> res;
uint4 el = decoder.peekElement();
if (el == sla::ELEM_INSTRUCT_PAT)
res = new InstructionPattern();
res.reset(new InstructionPattern());
else if (el == sla::ELEM_CONTEXT_PAT)
res = new ContextPattern();
res.reset(new ContextPattern());
else
res = new CombinePattern();
unique_ptr<DisjointPattern> upattern(res);
upattern->decode(decoder);
return upattern.release();
res.reset(new CombinePattern());
res->decode(decoder);
return res.release();
}
void PatternBlock::normalize(void)
@@ -4,9 +4,9 @@
* 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.
@@ -1126,9 +1126,9 @@ char *yytext;
* 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.
@@ -172,8 +172,16 @@ void SymbolTable::decode(Decoder &decoder,SleighBase *trans)
{
int4 el = decoder.openElement(sla::ELEM_SYMBOL_TABLE);
table.resize(decoder.readSignedInteger(sla::ATTRIB_SCOPESIZE), (SymbolScope *)0);
symbollist.resize(decoder.readSignedInteger(sla::ATTRIB_SYMBOLSIZE), (SleighSymbol *)0);
int8 tableSize = decoder.readSignedInteger(sla::ATTRIB_SCOPESIZE);
int8 symbolSize = decoder.readSignedInteger(sla::ATTRIB_SYMBOLSIZE);
if (tableSize < 0 || symbolSize < 0)
throw SleighError("Bad symbol table size");
if (tableSize > MAX_TABLES)
throw SleighError("Maximum scopes exceeded");
if (symbolSize > MAX_SYMBOLS)
throw SleighError("Maximum symbols exceeded");
table.resize(tableSize, (SymbolScope *)0);
symbollist.resize(symbolSize, (SleighSymbol *)0);
for(int4 i=0;i<table.size();++i) { // Decode the scopes
int4 subel = decoder.openElement(sla::ELEM_SCOPE);
uintm id = decoder.readUnsignedInteger(sla::ATTRIB_ID);
@@ -4,9 +4,9 @@
* 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.
@@ -76,6 +76,8 @@ class SymbolTable {
SymbolScope *skipScope(int4 i) const;
SleighSymbol *findSymbolInternal(SymbolScope *scope,const string &nm) const;
void renumber(void);
static constexpr int8 MAX_TABLES = 0x100000;
static constexpr int8 MAX_SYMBOLS = 0x1000000;
public:
SymbolTable(void) { curscope = (SymbolScope *)0; }
~SymbolTable(void);
@@ -352,9 +352,9 @@ void AddrSpaceManager::setReverseJustified(AddrSpace *spc)
void AddrSpaceManager::insertSpace(AddrSpace *spc)
{
unique_ptr<AddrSpace> uspc;
unique_ptr<AddrSpace> owner;
if (spc->refcount == 0)
uspc.reset(spc); // Take ownership if this is the first reference
owner.reset(spc); // Take ownership if this is the first reference
switch(spc->getType()) {
case IPTR_CONSTANT:
if (spc->getName() != ConstantSpace::NAME)
@@ -419,7 +419,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
baselist[spc->index] = spc;
uspc.release();
owner.release();
spc->refcount += 1;
assignShortcut(spc);
}
@@ -1012,7 +1012,7 @@ const FloatFormat *Translate::getFloatFormat(int4 size) const
void PcodeEmit::decodeOp(const Address &addr,Decoder &decoder)
{
int4 opcode;
OpCode opcode;
int4 isize;
VarnodeData outvar;
VarnodeData invar[16];
@@ -1021,14 +1021,19 @@ void PcodeEmit::decodeOp(const Address &addr,Decoder &decoder)
uint4 elemId = decoder.openElement(ELEM_OP);
isize = decoder.readSignedInteger(ATTRIB_SIZE);
outptr = &outvar;
if (isize <= 16)
if (isize <= 16) {
if (isize < 0)
throw DecoderError("Bad <op> size attribute");
opcode = PcodeOpRaw::decode(decoder, isize, invar, &outptr);
decoder.closeElement(elemId);
dump(addr,opcode,outptr,invar,isize);
}
else {
vector<VarnodeData> varStorage(isize,VarnodeData());
opcode = PcodeOpRaw::decode(decoder, isize, varStorage.data(), &outptr);
decoder.closeElement(elemId);
dump(addr,opcode,outptr,varStorage.data(),isize);
}
decoder.closeElement(elemId);
dump(addr,(OpCode)opcode,outptr,invar,isize);
}
} // End namespace ghidra
@@ -490,7 +490,7 @@ UserPcodeOp *UserOpManage::registerBuiltin(uint4 i)
void UserOpManage::registerOp(UserPcodeOp *op)
{
unique_ptr<UserPcodeOp> uop(op); // Take ownership
unique_ptr<UserPcodeOp> owner(op); // Take ownership
int4 ind = op->getIndex();
if (ind < 0) throw LowlevelError("UserOp not assigned an index");
@@ -510,7 +510,7 @@ void UserOpManage::registerOp(UserPcodeOp *op)
// We assume this registration customizes an existing userop
delete useroplist[ind]; // Delete the old spec
}
useroplist[ind] = uop.release(); // Index crossref
useroplist[ind] = owner.release(); // Index crossref
useropmap[op->getName()] = op; // Name crossref
SegmentOp *s_op = dynamic_cast<SegmentOp *>(op);
@@ -0,0 +1,89 @@
/* ###
* 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 "test.hh"
#include "multiprecision.hh"
namespace ghidra {
static uint8 num1[2] = { 0xffffffffffffffff, 0xffffffffffffffff };
static uint8 denom1[2] = { 1, 0 };
static uint8 num2[2] = { 0x89a732a9fb157c4d, 0x4eada2039e48443e };
static uint8 denom2[2] = { 0xbabf3b71, 0 };
static uint8 num3[2] = { 0xf7df0315d584ad8d, 0xb9d55c0d1d5cfbbd };
static uint8 denom3[2] = { 0x8aa797dbccee6e96, 0x646be9 };
static uint8 a[2] = { 0x1a309a9df2ce836a, 0xd66f2248906d1bdf };
static uint8 b[2] = { 0xf6c190704eb1763e, 0xa05c42212dfba7c6 };
TEST(multiprec_udiv) {
uint8 q[2];
uint8 r[2];
udiv128(num1, denom1, q, r);
ASSERT_EQUALS(q[0],0xffffffffffffffff);
ASSERT_EQUALS(q[1],0xffffffffffffffff);
ASSERT_EQUALS(r[0],0);
ASSERT_EQUALS(r[1],0);
udiv128(num2, denom2, q, r);
ASSERT_EQUALS(q[0], 0x2a21eef2058d7e9a);
ASSERT_EQUALS(q[1], 0x6bdaed99);
ASSERT_EQUALS(r[0], 0x928d1c53);
ASSERT_EQUALS(r[1], 0);
udiv128(num2,num1,q,r);
ASSERT_EQUALS(q[0], 0);
ASSERT_EQUALS(q[1], 0);
ASSERT_EQUALS(r[0],num2[0]);
ASSERT_EQUALS(r[1],num2[1]);
udiv128(num3,denom3,q,r);
ASSERT_EQUALS(q[0], 0x1d9bc949e24);
ASSERT_EQUALS(q[1], 0);
ASSERT_EQUALS(r[0], 0x2e78197dc5048c75);
ASSERT_EQUALS(r[1], 0x24d9cc);
}
TEST(multiprec_add) {
uint8 res[2];
add128(a,b,res);
ASSERT_EQUALS(res[0], 0x10f22b0e417ff9a8);
ASSERT_EQUALS(res[1], 0x76cb6469be68c3a6);
}
TEST(multiprec_sub) {
uint8 res[2];
subtract128(a,b,res);
ASSERT_EQUALS(res[0], 0x236F0A2DA41D0D2C);
ASSERT_EQUALS(res[1], 0x3612E02762717418);
}
TEST(multiprec_left) {
uint8 res[2];
leftshift128(num2, res, 51);
ASSERT_EQUALS(res[0], 0xe268000000000000);
ASSERT_EQUALS(res[1], 0x21f44d39954fd8ab);
}
TEST(multiprec_less) {
ASSERT(!uless128(a,a));
ASSERT(uless128(num2,num3));
ASSERT(uless128(denom1,denom2));
ASSERT(ulessequal128(a,a));
ASSERT(ulessequal128(num2,num3));
ASSERT(ulessequal128(denom2,denom2));
}
} // End namespace ghidra