mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-22 10:02:49 +08:00
GP-6757 Additional memory fixes
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user