mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 02:10:47 +08:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
@@ -624,8 +624,9 @@ void Architecture::postSpecFile(void)
|
||||
void Architecture::restoreFromSpec(DocumentStorage &store)
|
||||
|
||||
{
|
||||
Translate *newtrans = buildTranslator(store); // Once language is described we can build translator
|
||||
newtrans->initialize(store);
|
||||
unique_ptr<Translate> utrans(buildTranslator(store)); // Once language is described we can build translator
|
||||
utrans->initialize(store);
|
||||
Translate *newtrans = utrans.release();
|
||||
translate = newtrans;
|
||||
modifySpaces(newtrans); // Give architecture chance to modify spaces, before copying
|
||||
copySpaces(newtrans);
|
||||
@@ -741,23 +742,21 @@ void Architecture::decodeDynamicRule(Decoder &decoder)
|
||||
ProtoModel *Architecture::decodeProto(Decoder &decoder)
|
||||
|
||||
{
|
||||
ProtoModel *res;
|
||||
unique_ptr<ProtoModel> model;
|
||||
uint4 elemId = decoder.peekElement();
|
||||
if (elemId == ELEM_PROTOTYPE)
|
||||
res = new ProtoModel(this);
|
||||
model.reset(new ProtoModel(this));
|
||||
else if (elemId == ELEM_RESOLVEPROTOTYPE)
|
||||
res = new ProtoModelMerged(this);
|
||||
model.reset(new ProtoModelMerged(this));
|
||||
else
|
||||
throw LowlevelError("Expecting <prototype> or <resolveprototype> tag");
|
||||
|
||||
res->decode(decoder);
|
||||
model->decode(decoder);
|
||||
|
||||
ProtoModel *other = getModel(res->getName());
|
||||
if (other != (ProtoModel *)0) {
|
||||
string errMsg = "Duplicate ProtoModel name: " + res->getName();
|
||||
delete res;
|
||||
throw LowlevelError(errMsg);
|
||||
}
|
||||
ProtoModel *other = getModel(model->getName());
|
||||
if (other != (ProtoModel *)0)
|
||||
throw LowlevelError("Duplicate ProtoModel name: " + model->getName());
|
||||
ProtoModel *res = model.release();
|
||||
protoModels[res->getName()] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,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.
|
||||
@@ -67,19 +67,19 @@ bool BfdArchitectureCapability::isXmlMatch(Document *doc) const
|
||||
void BfdArchitecture::buildLoader(DocumentStorage &store)
|
||||
|
||||
{
|
||||
LoadImageBfd *ldr;
|
||||
unique_ptr<LoadImageBfd> ldr;
|
||||
|
||||
collectSpecFiles(*errorstream);
|
||||
if (getTarget().find("binary")==0)
|
||||
ldr = new LoadImageBfd(getFilename(),"binary");
|
||||
ldr.reset(new LoadImageBfd(getFilename(),"binary"));
|
||||
else if (getTarget().find("default")==0)
|
||||
ldr = new LoadImageBfd(getFilename(),"default");
|
||||
ldr.reset(new LoadImageBfd(getFilename(),"default"));
|
||||
else
|
||||
ldr = new LoadImageBfd(getFilename(),getTarget());
|
||||
ldr.reset(new LoadImageBfd(getFilename(),getTarget()));
|
||||
ldr->open();
|
||||
if (adjustvma!=0)
|
||||
ldr->adjustVma(adjustvma);
|
||||
loader = ldr;
|
||||
loader = ldr.release();
|
||||
}
|
||||
|
||||
void BfdArchitecture::resolveArchitecture(void)
|
||||
|
||||
@@ -1402,7 +1402,7 @@ void BlockGraph::decodeBody(Decoder &decoder)
|
||||
|
||||
{
|
||||
BlockMap newresolver;
|
||||
vector<FlowBlock *> tmplist;
|
||||
vector<unique_ptr<FlowBlock> > tmplist;
|
||||
|
||||
for(;;) {
|
||||
uint4 subId = decoder.peekElement();
|
||||
@@ -1411,15 +1411,14 @@ void BlockGraph::decodeBody(Decoder &decoder)
|
||||
int4 newindex = decoder.readSignedInteger(ATTRIB_INDEX);
|
||||
FlowBlock *bl = newresolver.createBlock(decoder.readString(ATTRIB_TYPE));
|
||||
bl->index = newindex; // Need to set index here for sort
|
||||
tmplist.push_back(bl);
|
||||
tmplist.push_back(unique_ptr<FlowBlock>(bl));
|
||||
decoder.closeElement(subId);
|
||||
}
|
||||
newresolver.sortList();
|
||||
|
||||
for(int4 i=0;i<tmplist.size();++i) {
|
||||
FlowBlock *bl = tmplist[i];
|
||||
bl->decode(decoder,newresolver);
|
||||
addBlock(bl);
|
||||
tmplist[i]->decode(decoder,newresolver);
|
||||
addBlock(tmplist[i].release());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1905,12 +1904,13 @@ BlockSwitch *BlockGraph::newBlockSwitch(const vector<FlowBlock *> &cs,bool hasEx
|
||||
|
||||
{
|
||||
FlowBlock *rootbl = cs[0];
|
||||
BlockSwitch *ret = new BlockSwitch(rootbl);
|
||||
unique_ptr<BlockSwitch> uret( new BlockSwitch(rootbl) );
|
||||
const FlowBlock *leafbl = rootbl->getExitLeaf();
|
||||
if ((leafbl == (const FlowBlock *)0)||(leafbl->getType() != FlowBlock::t_copy))
|
||||
throw LowlevelError("Could not get switch leaf");
|
||||
ret->grabCaseBasic(leafbl->subBlock(0),cs); // Must be called before the identifyInternal
|
||||
identifyInternal(ret,cs);
|
||||
uret->grabCaseBasic(leafbl->subBlock(0),cs); // Must be called before the identifyInternal
|
||||
identifyInternal(uret.get(),cs);
|
||||
BlockSwitch *ret = uret.release();
|
||||
addBlock(ret);
|
||||
if (hasExit)
|
||||
ret->forceOutputNum(1); // If there is an exit, there should be exactly 1 out edge
|
||||
|
||||
@@ -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.
|
||||
@@ -206,43 +206,38 @@ int main(int argc,char **argv)
|
||||
startDecompilerLibrary(ghidraroot.c_str(), extrapaths);
|
||||
}
|
||||
|
||||
IfaceStatus *status;
|
||||
int4 retval = 2;
|
||||
try {
|
||||
status = new IfaceTerm("[decomp]> ",cin,cout); // Set up interface
|
||||
} catch(IfaceError &err) {
|
||||
cerr << "Interface error during setup: " << err.explain << endl;
|
||||
exit(1);
|
||||
}
|
||||
IfaceCapability::registerAllCommands(status); // Register commands for decompiler and all modules
|
||||
unique_ptr<IfaceStatus> status(new IfaceTerm("[decomp]> ",cin,cout)); // Set up interface
|
||||
IfaceCapability::registerAllCommands(status.get()); // Register commands for decompiler and all modules
|
||||
|
||||
// Extra commands specific to the console application
|
||||
status->registerCom(new IfcLoadFile(),"load","file");
|
||||
status->registerCom(new IfcAddpath(),"addpath");
|
||||
status->registerCom(new IfcSave(),"save");
|
||||
status->registerCom(new IfcRestore(),"restore");
|
||||
// Extra commands specific to the console application
|
||||
status->registerCom(new IfcLoadFile(),"load","file");
|
||||
status->registerCom(new IfcAddpath(),"addpath");
|
||||
status->registerCom(new IfcSave(),"save");
|
||||
status->registerCom(new IfcRestore(),"restore");
|
||||
|
||||
if (initscript != (const char *)0) {
|
||||
try {
|
||||
status->pushScript(initscript,"init> ");
|
||||
} catch(IfaceParseError &err) {
|
||||
*status->optr << err.explain << endl;
|
||||
status->done = true;
|
||||
if (initscript != (const char *)0) {
|
||||
try {
|
||||
status->pushScript(initscript,"init> ");
|
||||
} catch(IfaceParseError &err) {
|
||||
*status->optr << err.explain << endl;
|
||||
status->done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!status->done)
|
||||
mainloop(status);
|
||||
int4 retval = status->isInError() ? 1 : 0;
|
||||
if (!status->done)
|
||||
mainloop(status.get());
|
||||
retval = status->isInError() ? 1 : 0;
|
||||
|
||||
#ifdef CPUI_STATISTICS
|
||||
IfaceDecompData *decompdata = (IfaceDecompData *)status->getData("decompile");
|
||||
decompdata->conf->stats->printResults(cout);
|
||||
IfaceDecompData *decompdata = (IfaceDecompData *)status->getData("decompile");
|
||||
decompdata->conf->stats->printResults(cout);
|
||||
#endif
|
||||
|
||||
try {
|
||||
delete status;
|
||||
} catch(IfaceError &err) {
|
||||
cerr << err.explain << endl;
|
||||
cerr << "Interface error: " << err.explain << endl;
|
||||
retval = 2;
|
||||
}
|
||||
|
||||
shutdownDecompilerLibrary();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1589,7 +1589,7 @@ Symbol *Scope::addMapSym(Decoder &decoder)
|
||||
throw LowlevelError("Unknown symbol type");
|
||||
try { // Protect against duplicate scope errors
|
||||
sym->decode(decoder);
|
||||
} catch(RecovError &err) {
|
||||
} catch(...) {
|
||||
delete sym;
|
||||
throw;
|
||||
}
|
||||
@@ -2950,12 +2950,13 @@ Database::~Database(void)
|
||||
void Database::attachScope(Scope *newscope,Scope *parent)
|
||||
|
||||
{
|
||||
unique_ptr<Scope> owner(newscope);
|
||||
if (parent == (Scope *)0) {
|
||||
if (globalscope != (Scope *)0)
|
||||
throw LowlevelError("Multiple global scopes");
|
||||
if (newscope->name.size() != 0)
|
||||
throw LowlevelError("Global scope does not have empty name");
|
||||
globalscope = newscope;
|
||||
globalscope = owner.release();
|
||||
idmap[globalscope->uniqueId] = globalscope;
|
||||
return;
|
||||
}
|
||||
@@ -2964,14 +2965,9 @@ void Database::attachScope(Scope *newscope,Scope *parent)
|
||||
pair<uint8,Scope *> value(newscope->uniqueId,newscope);
|
||||
pair<ScopeMap::iterator,bool> res;
|
||||
res = idmap.insert(value);
|
||||
if (res.second==false) {
|
||||
ostringstream s;
|
||||
s << "Duplicate scope id: ";
|
||||
s << newscope->getFullName();
|
||||
delete newscope;
|
||||
throw RecovError(s.str());
|
||||
}
|
||||
parent->attachScope(newscope);
|
||||
if (res.second==false)
|
||||
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
|
||||
@@ -3379,17 +3375,18 @@ void Database::decode(Decoder &decoder)
|
||||
void Database::decodeScope(Decoder &decoder,Scope *newScope)
|
||||
|
||||
{
|
||||
unique_ptr<Scope> owner(newScope);
|
||||
uint4 elemId = decoder.openElement();
|
||||
if (elemId == ELEM_SCOPE) {
|
||||
Scope *parentScope = parseParentTag(decoder);
|
||||
attachScope(newScope,parentScope);
|
||||
attachScope(owner.release(),parentScope);
|
||||
newScope->decode(decoder);
|
||||
}
|
||||
else {
|
||||
newScope->decodeWrappingAttributes(decoder);
|
||||
uint4 subId = decoder.openElement(ELEM_SCOPE);
|
||||
Scope *parentScope = parseParentTag(decoder);
|
||||
attachScope(newScope,parentScope);
|
||||
attachScope(owner.release(),parentScope);
|
||||
newScope->decode(decoder);
|
||||
decoder.closeElement(subId);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
|
||||
namespace ghidra {
|
||||
|
||||
@@ -65,6 +66,7 @@ using std::max;
|
||||
using std::to_string;
|
||||
using std::piecewise_construct;
|
||||
using std::forward_as_tuple;
|
||||
using std::unique_ptr;
|
||||
|
||||
|
||||
/// \brief The lowest level error generated by the decompiler
|
||||
|
||||
@@ -682,8 +682,8 @@ bool FlowInfo::setupCallSpecs(PcodeOp *op,FuncCallSpecs *fc)
|
||||
{
|
||||
FuncCallSpecs *res;
|
||||
res = new FuncCallSpecs(op);
|
||||
data.opSetInput(op,data.newVarnodeCallSpecs(res),0);
|
||||
qlst.push_back(res);
|
||||
data.opSetInput(op,data.newVarnodeCallSpecs(res),0);
|
||||
|
||||
data.getOverride().applyPrototype(data,*res);
|
||||
queryCall(*res);
|
||||
|
||||
@@ -615,9 +615,9 @@ void Funcdata::decodeJumpTable(Decoder &decoder)
|
||||
{
|
||||
uint4 elemId = decoder.openElement(ELEM_JUMPTABLELIST);
|
||||
while(decoder.peekElement() != 0) {
|
||||
JumpTable *jt = new JumpTable();
|
||||
unique_ptr<JumpTable> jt(new JumpTable());
|
||||
jt->decode(decoder);
|
||||
jumpvec.push_back(jt);
|
||||
jumpvec.push_back(jt.release());
|
||||
}
|
||||
decoder.closeElement(elemId);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1856,12 +1856,12 @@ void IfcProtooverride::execute(istream &s)
|
||||
PrototypePieces pieces;
|
||||
parse_protopieces(pieces,s,dcp->conf); // Parse the prototype from stream
|
||||
|
||||
FuncProto *newproto = new FuncProto();
|
||||
unique_ptr<FuncProto> newproto(new FuncProto());
|
||||
|
||||
// Make proto whose storage is internal, not backed by a real scope
|
||||
newproto->setInternal(pieces.model,dcp->conf->types->getTypeVoid());
|
||||
newproto->setPieces(pieces);
|
||||
dcp->fd->getOverride().insertProtoOverride(callpoint,newproto);
|
||||
dcp->fd->getOverride().insertProtoOverride(callpoint,newproto.release());
|
||||
dcp->fd->clear(); // Clear any analysis (this leaves overrides intact)
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -249,7 +249,7 @@ void IfaceTerm::pushScript(istream *iptr,const string &newprompt)
|
||||
{
|
||||
inputstack.push_back(sptr);
|
||||
sptr = iptr;
|
||||
IfaceStatus::pushScript(iptr,newprompt);
|
||||
IfaceStatus::pushScript((istream *)0,newprompt);
|
||||
}
|
||||
|
||||
void IfaceTerm::popScript(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.
|
||||
@@ -145,8 +145,10 @@ void IfaceStatus::pushScript(const string &filename,const string &newprompt)
|
||||
|
||||
{
|
||||
ifstream *s = new ifstream(filename.c_str());
|
||||
if (!*s)
|
||||
if (!*s) {
|
||||
delete s;
|
||||
throw IfaceParseError("Unable to open script file: "+filename);
|
||||
}
|
||||
pushScript(s,newprompt);
|
||||
}
|
||||
|
||||
@@ -159,6 +161,10 @@ void IfaceStatus::pushScript(const string &filename,const string &newprompt)
|
||||
void IfaceStatus::pushScript(istream *iptr,const string &newprompt)
|
||||
|
||||
{
|
||||
if (iptr != (istream *)0) {
|
||||
delete iptr;
|
||||
throw IfaceExecutionError("Unable to read script from stream on this interface");
|
||||
}
|
||||
promptstack.push_back(prompt);
|
||||
uint4 flags = 0;
|
||||
if (errorisdone)
|
||||
|
||||
@@ -2482,11 +2482,11 @@ void JumpTable::setOverride(const vector<Address> &addrtable,const Address &nadd
|
||||
if (jmodel != (JumpModel *)0)
|
||||
delete jmodel;
|
||||
|
||||
JumpBasicOverride *override;
|
||||
jmodel = override = new JumpBasicOverride(this);
|
||||
override->setAddresses(addrtable);
|
||||
override->setNorm(naddr,h);
|
||||
override->setStartingValue(sv);
|
||||
JumpBasicOverride *jumpOverride;
|
||||
jmodel = jumpOverride = new JumpBasicOverride(this);
|
||||
jumpOverride->setAddresses(addrtable);
|
||||
jumpOverride->setNorm(naddr,h);
|
||||
jumpOverride->setStartingValue(sv);
|
||||
}
|
||||
|
||||
/// \brief Get the index of the i-th address table entry that corresponds to the given basic-block
|
||||
|
||||
@@ -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.
|
||||
@@ -30,8 +30,6 @@ uint1 *LoadImage::load(int4 size,const Address &addr)
|
||||
|
||||
{
|
||||
uint1 *buf = new uint1[ size ];
|
||||
if (buf == (uint1 *)0)
|
||||
throw LowlevelError("Out of memory");
|
||||
loadFill(buf,size,addr);
|
||||
return buf;
|
||||
}
|
||||
@@ -62,6 +60,7 @@ void RawLoadImage::open(void)
|
||||
thefile = new ifstream(filename.c_str());
|
||||
if (!(*thefile)) {
|
||||
string errmsg = "Unable to open raw image file: "+filename;
|
||||
delete thefile;
|
||||
throw LowlevelError(errmsg);
|
||||
}
|
||||
thefile->seekg(0,ios::end);
|
||||
|
||||
@@ -689,7 +689,10 @@ void PackedDecode::endIngest(int4 bufPos)
|
||||
}
|
||||
uint1 *buf = inStream.back().start;
|
||||
buf[bufPos] = ELEMENT_END;
|
||||
} else {
|
||||
throw DecoderError("Ended ingestion without any input");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PackedDecode::~PackedDecode(void)
|
||||
@@ -961,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);
|
||||
@@ -1002,10 +1004,12 @@ 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");
|
||||
|
||||
spc = spcManager->getSpace(res);
|
||||
if (spc == (AddrSpace *)0)
|
||||
throw DecoderError("Unknown address space index");
|
||||
|
||||
@@ -536,7 +536,7 @@ private:
|
||||
uint1 getByte(Position &pos) { return *pos.current; } ///< Get the byte at the current position, do not advance
|
||||
uint1 getBytePlus1(Position &pos); ///< Get the byte following the current byte, do not advance position
|
||||
uint1 getNextByte(Position &pos); ///< Get the byte at the current position and advance to the next byte
|
||||
void advancePosition(Position &pos,int4 skip); ///< Advance the position by the given number of bytes
|
||||
void advancePosition(Position &pos,uint4 skip); ///< Advance the position by the given number of bytes
|
||||
uint8 readInteger(int4 len); ///< Read an integer from the \e current position given its length in bytes
|
||||
uint4 readLengthCode(uint1 typeByte) { return ((uint4)typeByte & PackedFormat::LENGTHCODE_MASK); } ///< Extract length code from type byte
|
||||
void findMatchingAttribute(const AttributeId &attribId); ///< Find attribute matching the given id in open element
|
||||
@@ -631,7 +631,7 @@ inline uint1 PackedDecode::getNextByte(Position &pos)
|
||||
/// An exception is thrown of position is advanced past the end of the stream
|
||||
/// \param pos is the position being advanced
|
||||
/// \param skip is the number of bytes to advance
|
||||
inline void PackedDecode::advancePosition(Position &pos,int4 skip)
|
||||
inline void PackedDecode::advancePosition(Position &pos,uint4 skip)
|
||||
|
||||
{
|
||||
while(pos.end - pos.current <= skip) {
|
||||
|
||||
@@ -252,23 +252,23 @@ PrimitiveExtractor::PrimitiveExtractor(Datatype *dt,bool unionIllegal,int offset
|
||||
DatatypeFilter *DatatypeFilter::decodeFilter(Decoder &decoder)
|
||||
|
||||
{
|
||||
DatatypeFilter *filter;
|
||||
unique_ptr<DatatypeFilter> filter;
|
||||
uint4 elemId = decoder.openElement(ELEM_DATATYPE);
|
||||
string nm = decoder.readString(ATTRIB_NAME);
|
||||
if (nm == "any") {
|
||||
filter = new SizeRestrictedFilter();
|
||||
filter.reset(new SizeRestrictedFilter());
|
||||
}
|
||||
else if (nm == "homogeneous-float-aggregate") {
|
||||
filter = new HomogeneousAggregate(TYPE_FLOAT,4,0,0);
|
||||
filter.reset(new HomogeneousAggregate(TYPE_FLOAT,4,0,0));
|
||||
}
|
||||
else {
|
||||
// If no other name matches, assume this is a metatype
|
||||
type_metatype meta = string2metatype(nm);
|
||||
filter = new MetaTypeFilter(meta);
|
||||
filter.reset(new MetaTypeFilter(meta));
|
||||
}
|
||||
filter->decode(decoder);
|
||||
decoder.closeElement(elemId);
|
||||
return filter;
|
||||
return filter.release();
|
||||
}
|
||||
|
||||
/// Parse the given string as a comma or space separated list of decimal integers,
|
||||
@@ -451,18 +451,18 @@ void HomogeneousAggregate::decode(Decoder &decoder)
|
||||
QualifierFilter *QualifierFilter::decodeFilter(Decoder &decoder)
|
||||
|
||||
{
|
||||
QualifierFilter *filter;
|
||||
unique_ptr<QualifierFilter> filter;
|
||||
uint4 elemId = decoder.peekElement();
|
||||
if (elemId == ELEM_VARARGS)
|
||||
filter = new VarargsFilter();
|
||||
filter.reset(new VarargsFilter());
|
||||
else if (elemId == ELEM_POSITION)
|
||||
filter = new PositionMatchFilter(-1);
|
||||
filter.reset(new PositionMatchFilter(-1));
|
||||
else if (elemId == ELEM_DATATYPE_AT)
|
||||
filter = new DatatypeMatchFilter();
|
||||
filter.reset(new DatatypeMatchFilter());
|
||||
else
|
||||
return (QualifierFilter *)0;
|
||||
filter->decode(decoder);
|
||||
return filter;
|
||||
return filter.release();
|
||||
}
|
||||
|
||||
/// The AndFilter assumes ownership of all the filters in the array and the original vector is cleared
|
||||
@@ -592,32 +592,32 @@ bool AssignAction::fillinOutputMap(ParamActive *active) const
|
||||
AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandard *res)
|
||||
|
||||
{
|
||||
AssignAction *action;
|
||||
unique_ptr<AssignAction> action;
|
||||
uint4 elemId = decoder.peekElement();
|
||||
if (elemId == ELEM_GOTO_STACK)
|
||||
action = new GotoStack(res,0);
|
||||
action.reset(new GotoStack(res,0));
|
||||
else if (elemId == ELEM_JOIN) {
|
||||
action = new MultiSlotAssign(res);
|
||||
action.reset(new MultiSlotAssign(res));
|
||||
}
|
||||
else if (elemId == ELEM_CONSUME) {
|
||||
action = new ConsumeAs(TYPECLASS_GENERAL,res);
|
||||
action.reset(new ConsumeAs(TYPECLASS_GENERAL,res));
|
||||
}
|
||||
else if (elemId == ELEM_CONVERT_TO_PTR) {
|
||||
action = new ConvertToPointer(res);
|
||||
action.reset(new ConvertToPointer(res));
|
||||
}
|
||||
else if (elemId == ELEM_HIDDEN_RETURN) {
|
||||
action = new HiddenReturnAssign(res,hiddenret_specialreg);
|
||||
action.reset(new HiddenReturnAssign(res,hiddenret_specialreg));
|
||||
}
|
||||
else if (elemId == ELEM_JOIN_PER_PRIMITIVE) {
|
||||
action = new MultiMemberAssign(TYPECLASS_GENERAL,false,res->isBigEndian(),res);
|
||||
action.reset(new MultiMemberAssign(TYPECLASS_GENERAL,false,res->isBigEndian(),res));
|
||||
}
|
||||
else if (elemId == ELEM_JOIN_DUAL_CLASS) {
|
||||
action = new MultiSlotDualAssign(res);
|
||||
action.reset(new MultiSlotDualAssign(res));
|
||||
}
|
||||
else
|
||||
throw DecoderError("Expecting model rule action");
|
||||
action->decode(decoder);
|
||||
return action;
|
||||
return action.release();
|
||||
}
|
||||
|
||||
/// \brief Read the next model rule precondition element from the stream
|
||||
@@ -629,18 +629,18 @@ AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandar
|
||||
/// \return the new precondition, or null if no more preconditions are in the stream
|
||||
AssignAction *AssignAction::decodePrecondition(Decoder &decoder,const ParamListStandard *res)
|
||||
{
|
||||
AssignAction *action;
|
||||
unique_ptr<AssignAction> action;
|
||||
uint4 elemId = decoder.peekElement();
|
||||
|
||||
if (elemId == ELEM_CONSUME_EXTRA) {
|
||||
action = new ConsumeExtra(res);
|
||||
action.reset(new ConsumeExtra(res));
|
||||
}
|
||||
else {
|
||||
return (AssignAction *)0;
|
||||
}
|
||||
|
||||
action->decode(decoder);
|
||||
return action;
|
||||
return action.release();
|
||||
}
|
||||
|
||||
/// \brief Read the next model rule sideeffect element from the stream
|
||||
@@ -653,22 +653,22 @@ AssignAction *AssignAction::decodePrecondition(Decoder &decoder,const ParamListS
|
||||
AssignAction *AssignAction::decodeSideeffect(Decoder &decoder,const ParamListStandard *res)
|
||||
|
||||
{
|
||||
AssignAction *action;
|
||||
unique_ptr<AssignAction> action;
|
||||
uint4 elemId = decoder.peekElement();
|
||||
|
||||
if (elemId == ELEM_CONSUME_EXTRA) {
|
||||
action = new ConsumeExtra(res);
|
||||
action.reset(new ConsumeExtra(res));
|
||||
}
|
||||
else if (elemId == ELEM_EXTRA_STACK) {
|
||||
action = new ExtraStack(res);
|
||||
action.reset(new ExtraStack(res));
|
||||
}
|
||||
else if (elemId == ELEM_CONSUME_REMAINING) {
|
||||
action = new ConsumeRemaining(res);
|
||||
action.reset(new ConsumeRemaining(res));
|
||||
}
|
||||
else
|
||||
throw DecoderError("Expecting model rule sideeffect");
|
||||
action->decode(decoder);
|
||||
return action;
|
||||
return action.release();
|
||||
}
|
||||
|
||||
/// \brief Truncate a tiling by a given number of bytes
|
||||
@@ -1695,9 +1695,9 @@ void ModelRule::decode(Decoder &decoder,const ParamListStandard *res)
|
||||
qualifier = new AndFilter(qualifiers);
|
||||
}
|
||||
for (;;) {
|
||||
AssignAction *precond = AssignAction::decodePrecondition(decoder, res);
|
||||
if (precond == (AssignAction *)0)
|
||||
break;
|
||||
AssignAction *precond = AssignAction::decodePrecondition(decoder, res);
|
||||
if (precond == (AssignAction *)0)
|
||||
break;
|
||||
preconditions.push_back(precond);
|
||||
}
|
||||
assign = AssignAction::decodeAction(decoder, res);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -367,10 +367,10 @@ void Override::decode(Decoder &decoder,Architecture *glb)
|
||||
}
|
||||
else if (subId == ELEM_PROTOOVERRIDE) {
|
||||
Address callpoint = Address::decode(decoder);
|
||||
FuncProto *fp = new FuncProto();
|
||||
unique_ptr<FuncProto> fp(new FuncProto());
|
||||
fp->setInternal(glb->defaultfp,glb->types->getTypeVoid());
|
||||
fp->decode(decoder,glb);
|
||||
insertProtoOverride(callpoint,fp);
|
||||
insertProtoOverride(callpoint,fp.release());
|
||||
}
|
||||
else if (subId == ELEM_FORCEGOTO) {
|
||||
Address targetpc = Address::decode(decoder);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
@@ -55,14 +55,12 @@ bool RawBinaryArchitectureCapability::isXmlMatch(Document *doc) const
|
||||
void RawBinaryArchitecture::buildLoader(DocumentStorage &store)
|
||||
|
||||
{
|
||||
RawLoadImage *ldr;
|
||||
|
||||
collectSpecFiles(*errorstream);
|
||||
ldr = new RawLoadImage(getFilename());
|
||||
unique_ptr<RawLoadImage> ldr(new RawLoadImage(getFilename()));
|
||||
ldr->open();
|
||||
if (adjustvma != 0)
|
||||
ldr->adjustVma(adjustvma);
|
||||
loader = ldr;
|
||||
loader = ldr.release();
|
||||
}
|
||||
|
||||
void RawBinaryArchitecture::resolveArchitecture(void)
|
||||
|
||||
@@ -721,8 +721,8 @@ void OpTpl::decode(Decoder &decoder)
|
||||
}
|
||||
while(decoder.peekElement() != 0) {
|
||||
VarnodeTpl *vn = new VarnodeTpl();
|
||||
vn->decode(decoder);
|
||||
input.push_back(vn);
|
||||
vn->decode(decoder);
|
||||
}
|
||||
decoder.closeElement(el);
|
||||
}
|
||||
@@ -915,8 +915,8 @@ int4 ConstructTpl::decode(Decoder &decoder)
|
||||
}
|
||||
while(decoder.peekElement() != 0) {
|
||||
OpTpl *op = new OpTpl();
|
||||
op->decode(decoder);
|
||||
vec.push_back(op);
|
||||
op->decode(decoder);
|
||||
}
|
||||
decoder.closeElement(el);
|
||||
return sectionid;
|
||||
|
||||
@@ -142,7 +142,7 @@ class OpTpl {
|
||||
OpCode opc;
|
||||
vector<VarnodeTpl *> input;
|
||||
public:
|
||||
OpTpl(void) {}
|
||||
OpTpl(void) : output(nullptr) {}
|
||||
OpTpl(OpCode oc) { opc = oc; output = (VarnodeTpl *)0; }
|
||||
~OpTpl(void);
|
||||
VarnodeTpl *getOut(void) const { return output; }
|
||||
|
||||
@@ -452,9 +452,9 @@ void DisassemblyCache::initialize(int4 min,int4 hashsize)
|
||||
nextfree = 0;
|
||||
hashtable = new ParserContext *[hashsize];
|
||||
for(int4 i=0;i<minimumreuse;++i) {
|
||||
ParserContext *pos = new ParserContext(contextcache,translate);
|
||||
pos->initialize(constspace);
|
||||
list[i] = pos;
|
||||
ParserContext *pos = new ParserContext(contextcache,translate);
|
||||
list[i] = pos;
|
||||
pos->initialize(constspace);
|
||||
}
|
||||
ParserContext *pos = list[0];
|
||||
for(int4 i=0;i<hashsize;++i)
|
||||
|
||||
@@ -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
|
||||
@@ -3671,10 +3702,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);
|
||||
}
|
||||
@@ -3691,6 +3722,9 @@ void SleighCompile::buildConstructor(Constructor *big,PatternEquation *pateq,vec
|
||||
delete contvec;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PatternEquation::release(pateq);
|
||||
}
|
||||
symtab.popScope(); // In all cases pop scope
|
||||
}
|
||||
|
||||
@@ -3751,6 +3785,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
|
||||
@@ -3777,7 +3812,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 *>; }
|
||||
|
||||
@@ -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.
|
||||
@@ -503,9 +503,13 @@ PatternExpression *PatternExpression::decodeExpression(Decoder &decoder,Translat
|
||||
else if (el == sla::ELEM_NOT_EXP)
|
||||
res = new NotExpression();
|
||||
else
|
||||
return (PatternExpression *)0;
|
||||
|
||||
res->decode(decoder,trans);
|
||||
throw DecoderError("Invalid pattern expression element");
|
||||
try {
|
||||
res->decode(decoder,trans);
|
||||
} catch(...) {
|
||||
delete res;
|
||||
throw;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -826,6 +830,9 @@ void OperandValue::decode(Decoder &decoder,Translate *trans)
|
||||
uintm ctid = decoder.readUnsignedInteger(sla::ATTRIB_CT);
|
||||
SleighBase *sleigh = (SleighBase *)trans;
|
||||
SubtableSymbol *tab = dynamic_cast<SubtableSymbol *>(sleigh->findSymbol(tabid));
|
||||
if (ctid >= tab->getNumConstructors()) {
|
||||
throw DecoderError("Invalid constructor id");
|
||||
}
|
||||
ct = tab->getConstructor(ctid);
|
||||
decoder.closeElement(el);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -141,16 +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();
|
||||
res.reset(new CombinePattern());
|
||||
res->decode(decoder);
|
||||
return res;
|
||||
return res.release();
|
||||
}
|
||||
|
||||
void PatternBlock::normalize(void)
|
||||
|
||||
@@ -1128,9 +1128,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.
|
||||
|
||||
@@ -49,10 +49,12 @@ SymbolTable::~SymbolTable(void)
|
||||
{
|
||||
vector<SymbolScope *>::iterator iter;
|
||||
for(iter=table.begin();iter!=table.end();++iter)
|
||||
delete *iter;
|
||||
if (*iter)
|
||||
delete *iter;
|
||||
vector<SleighSymbol *>::iterator siter;
|
||||
for(siter=symbollist.begin();siter!=symbollist.end();++siter)
|
||||
delete *siter;
|
||||
if (*siter)
|
||||
delete *siter;
|
||||
}
|
||||
|
||||
void SymbolTable::addScope(void)
|
||||
@@ -170,13 +172,33 @@ 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);
|
||||
if (id >= table.size()) {
|
||||
throw SleighError("Bad symbol scope id: exceeds symbol scope table size");
|
||||
}
|
||||
|
||||
uintm parent = decoder.readUnsignedInteger(sla::ATTRIB_PARENT);
|
||||
if (parent >= table.size()) {
|
||||
throw SleighError("Bad symbol scope parent id: exceeds symbol scope table size");
|
||||
}
|
||||
|
||||
SymbolScope *parscope = (parent==id) ? (SymbolScope *)0 : table[parent];
|
||||
if (table[id]) {
|
||||
throw SleighError("Bad symbol scope parent id: not unique");
|
||||
}
|
||||
|
||||
table[id] = new SymbolScope( parscope, id );
|
||||
decoder.closeElement(subel);
|
||||
}
|
||||
@@ -202,39 +224,58 @@ void SymbolTable::decodeSymbolHeader(Decoder &decoder)
|
||||
|
||||
{ // Put the shell of a symbol in the symbol table
|
||||
// in order to allow recursion
|
||||
SleighSymbol *sym;
|
||||
unique_ptr<SleighSymbol> sym;
|
||||
uint4 el = decoder.peekElement();
|
||||
if (el == sla::ELEM_USEROP_HEAD)
|
||||
sym = new UserOpSymbol();
|
||||
sym.reset(new UserOpSymbol());
|
||||
else if (el == sla::ELEM_EPSILON_SYM_HEAD)
|
||||
sym = new EpsilonSymbol();
|
||||
sym.reset(new EpsilonSymbol());
|
||||
else if (el == sla::ELEM_VALUE_SYM_HEAD)
|
||||
sym = new ValueSymbol();
|
||||
sym.reset(new ValueSymbol());
|
||||
else if (el == sla::ELEM_VALUEMAP_SYM_HEAD)
|
||||
sym = new ValueMapSymbol();
|
||||
sym.reset(new ValueMapSymbol());
|
||||
else if (el == sla::ELEM_NAME_SYM_HEAD)
|
||||
sym = new NameSymbol();
|
||||
sym.reset(new NameSymbol());
|
||||
else if (el == sla::ELEM_VARNODE_SYM_HEAD)
|
||||
sym = new VarnodeSymbol();
|
||||
sym.reset(new VarnodeSymbol());
|
||||
else if (el == sla::ELEM_CONTEXT_SYM_HEAD)
|
||||
sym = new ContextSymbol();
|
||||
sym.reset(new ContextSymbol());
|
||||
else if (el == sla::ELEM_VARLIST_SYM_HEAD)
|
||||
sym = new VarnodeListSymbol();
|
||||
sym.reset(new VarnodeListSymbol());
|
||||
else if (el == sla::ELEM_OPERAND_SYM_HEAD)
|
||||
sym = new OperandSymbol();
|
||||
sym.reset(new OperandSymbol());
|
||||
else if (el == sla::ELEM_START_SYM_HEAD)
|
||||
sym = new StartSymbol();
|
||||
sym.reset(new StartSymbol());
|
||||
else if (el == sla::ELEM_END_SYM_HEAD)
|
||||
sym = new EndSymbol();
|
||||
sym.reset(new EndSymbol());
|
||||
else if (el == sla::ELEM_NEXT2_SYM_HEAD)
|
||||
sym = new Next2Symbol();
|
||||
sym.reset(new Next2Symbol());
|
||||
else if (el == sla::ELEM_SUBTABLE_SYM_HEAD)
|
||||
sym = new SubtableSymbol();
|
||||
sym.reset(new SubtableSymbol());
|
||||
else
|
||||
throw SleighError("Bad symbol xml");
|
||||
|
||||
sym->decodeHeader(decoder); // Restore basic elements of symbol
|
||||
symbollist[sym->id] = sym; // Put the basic symbol in the table
|
||||
table[sym->scopeid]->addSymbol(sym); // to allow recursion
|
||||
|
||||
if (sym->id >= symbollist.size()) {
|
||||
throw SleighError("Bad symbol id: exceeds symbollist size");
|
||||
}
|
||||
|
||||
if (symbollist[sym->id] != (SleighSymbol *)0) {
|
||||
throw SleighError("Bad symbol id: not unique");
|
||||
}
|
||||
|
||||
if (sym->scopeid >= table.size()) {
|
||||
throw SleighError("Bad symbol scope id: too large");
|
||||
}
|
||||
|
||||
if (table[sym->scopeid] == (SymbolScope *)0) {
|
||||
throw SleighError("Bad symbol scope id: undefined");
|
||||
}
|
||||
|
||||
SleighSymbol *res = sym.release();
|
||||
symbollist[res->id] = res; // Put the basic symbol in the table
|
||||
table[res->scopeid]->addSymbol(res); // to allow recursion
|
||||
}
|
||||
|
||||
void SymbolTable::purge(void)
|
||||
@@ -500,6 +541,9 @@ void ValueSymbol::encodeHeader(Encoder &encoder) const
|
||||
void ValueSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
|
||||
{
|
||||
if (patval)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans);
|
||||
patval->layClaim();
|
||||
decoder.closeElement(sla::ELEM_VALUE_SYM.getId());
|
||||
@@ -581,6 +625,9 @@ void ValueMapSymbol::encodeHeader(Encoder &encoder) const
|
||||
void ValueMapSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
|
||||
{
|
||||
if (patval)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans);
|
||||
patval->layClaim();
|
||||
while(decoder.peekElement() != 0) {
|
||||
@@ -660,6 +707,9 @@ void NameSymbol::encodeHeader(Encoder &encoder) const
|
||||
void NameSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
|
||||
{
|
||||
if (patval)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans);
|
||||
patval->layClaim();
|
||||
while(decoder.peekElement() != 0) {
|
||||
@@ -794,6 +844,10 @@ void ContextSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
if (lowMissing || highMissing) {
|
||||
throw DecoderError("Missing high/low attributes");
|
||||
}
|
||||
|
||||
if (patval)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans);
|
||||
patval->layClaim();
|
||||
decoder.closeElement(sla::ELEM_CONTEXT_SYM.getId());
|
||||
@@ -898,6 +952,9 @@ void VarnodeListSymbol::encodeHeader(Encoder &encoder) const
|
||||
void VarnodeListSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
|
||||
{
|
||||
if (patval)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans);
|
||||
patval->layClaim();
|
||||
while(decoder.peekElement() != 0) {
|
||||
@@ -945,7 +1002,9 @@ void OperandSymbol::defineOperand(TripleSymbol *tri)
|
||||
OperandSymbol::~OperandSymbol(void)
|
||||
|
||||
{
|
||||
PatternExpression::release(localexp);
|
||||
if (localexp != (PatternExpression *)0)
|
||||
PatternExpression::release(localexp);
|
||||
|
||||
if (defexp != (PatternExpression *)0)
|
||||
PatternExpression::release(defexp);
|
||||
}
|
||||
@@ -1040,6 +1099,9 @@ void OperandSymbol::encodeHeader(Encoder &encoder) const
|
||||
void OperandSymbol::decode(Decoder &decoder,SleighBase *trans)
|
||||
|
||||
{
|
||||
if (defexp || localexp)
|
||||
throw DecoderError("Already decoded symbol");
|
||||
|
||||
defexp = (PatternExpression *)0;
|
||||
triple = (TripleSymbol *)0;
|
||||
flags = 0;
|
||||
@@ -1631,28 +1693,28 @@ void Constructor::decode(Decoder &decoder,SleighBase *trans)
|
||||
}
|
||||
else if (subel == sla::ELEM_CONTEXT_OP) {
|
||||
ContextOp *c_op = new ContextOp();
|
||||
c_op->decode(decoder,trans);
|
||||
context.push_back(c_op);
|
||||
c_op->decode(decoder,trans);
|
||||
}
|
||||
else if (subel == sla::ELEM_COMMIT) {
|
||||
ContextCommit *c_op = new ContextCommit();
|
||||
c_op->decode(decoder,trans);
|
||||
context.push_back(c_op);
|
||||
c_op->decode(decoder,trans);
|
||||
}
|
||||
else {
|
||||
ConstructTpl *cur = new ConstructTpl();
|
||||
unique_ptr<ConstructTpl> cur(new ConstructTpl());
|
||||
int4 sectionid = cur->decode(decoder);
|
||||
if (sectionid < 0) {
|
||||
if (templ != (ConstructTpl *)0)
|
||||
throw LowlevelError("Duplicate main section");
|
||||
templ = cur;
|
||||
templ = cur.release();
|
||||
}
|
||||
else {
|
||||
while(namedtempl.size() <= sectionid)
|
||||
namedtempl.push_back((ConstructTpl *)0);
|
||||
if (namedtempl[sectionid] != (ConstructTpl *)0)
|
||||
throw LowlevelError("Duplicate named section");
|
||||
namedtempl[sectionid] = cur;
|
||||
namedtempl[sectionid] = cur.release();
|
||||
}
|
||||
}
|
||||
subel = decoder.peekElement();
|
||||
@@ -2334,6 +2396,9 @@ void DecisionNode::decode(Decoder &decoder,DecisionNode *par,SubtableSymbol *sub
|
||||
if (subel == sla::ELEM_PAIR) {
|
||||
decoder.openElement();
|
||||
uintm id = decoder.readSignedInteger(sla::ATTRIB_ID);
|
||||
if (id >= sub->getNumConstructors()) {
|
||||
throw DecoderError("Invalid constructor id");
|
||||
}
|
||||
Constructor *ct = sub->getConstructor(id);
|
||||
DisjointPattern *pat = DisjointPattern::decodeDisjoint(decoder);
|
||||
list.push_back(pair<DisjointPattern *,Constructor *>(pat,ct));
|
||||
@@ -2341,8 +2406,8 @@ void DecisionNode::decode(Decoder &decoder,DecisionNode *par,SubtableSymbol *sub
|
||||
}
|
||||
else if (subel == sla::ELEM_DECISION) {
|
||||
DecisionNode *subnode = new DecisionNode();
|
||||
subnode->decode(decoder,this,sub);
|
||||
children.push_back(subnode);
|
||||
subnode->decode(decoder,this,sub);
|
||||
}
|
||||
subel = decoder.peekElement();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -326,7 +328,7 @@ private:
|
||||
void setVariableLength(void) { flags |= variable_len; }
|
||||
bool isVariableLength(void) const { return ((flags&variable_len)!=0); }
|
||||
public:
|
||||
OperandSymbol(void) {} // For use with decode
|
||||
OperandSymbol(void) : localexp(nullptr), defexp(nullptr) {} // For use with decode
|
||||
OperandSymbol(const string &nm,int4 index,Constructor *ct);
|
||||
uint4 getRelativeOffset(void) const { return reloffset; }
|
||||
int4 getOffsetBase(void) const { return offsetbase; }
|
||||
@@ -448,8 +450,8 @@ class ContextOp : public ContextChange {
|
||||
int4 shift; // Number of bits to shift value into place
|
||||
public:
|
||||
ContextOp(int4 startbit,int4 endbit,PatternExpression *pe);
|
||||
ContextOp(void) {} // For use with decode
|
||||
virtual ~ContextOp(void) { PatternExpression::release(patexp); }
|
||||
ContextOp(void) : patexp(nullptr) {} // For use with decode
|
||||
virtual ~ContextOp(void) { if (patexp) PatternExpression::release(patexp); }
|
||||
virtual void validate(void) const;
|
||||
virtual void encode(Encoder &encoder) const;
|
||||
virtual void decode(Decoder &decoder,SleighBase *trans);
|
||||
|
||||
@@ -258,20 +258,20 @@ AddrSpace *AddrSpaceManager::decodeSpace(Decoder &decoder,const Translate *trans
|
||||
|
||||
{
|
||||
uint4 elemId = decoder.peekElement();
|
||||
AddrSpace *res;
|
||||
unique_ptr<AddrSpace> res;
|
||||
if (elemId == ELEM_SPACE_BASE)
|
||||
res = new SpacebaseSpace(this,trans);
|
||||
res.reset(new SpacebaseSpace(this,trans));
|
||||
else if (elemId == ELEM_SPACE_UNIQUE)
|
||||
res = new UniqueSpace(this,trans);
|
||||
res.reset(new UniqueSpace(this,trans));
|
||||
else if (elemId == ELEM_SPACE_OTHER)
|
||||
res = new OtherSpace(this,trans);
|
||||
res.reset(new OtherSpace(this,trans));
|
||||
else if (elemId == ELEM_SPACE_OVERLAY)
|
||||
res = new OverlaySpace(this,trans);
|
||||
res.reset(new OverlaySpace(this,trans));
|
||||
else
|
||||
res = new AddrSpace(this,trans,IPTR_PROCESSOR);
|
||||
res.reset(new AddrSpace(this,trans,IPTR_PROCESSOR));
|
||||
|
||||
res->decode(decoder);
|
||||
return res;
|
||||
return res.release();
|
||||
}
|
||||
|
||||
/// This routine initializes (almost) all the address spaces used
|
||||
@@ -352,49 +352,49 @@ void AddrSpaceManager::setReverseJustified(AddrSpace *spc)
|
||||
void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
||||
|
||||
{
|
||||
bool nameTypeMismatch = false;
|
||||
bool duplicateName = false;
|
||||
bool duplicateId = false;
|
||||
unique_ptr<AddrSpace> owner;
|
||||
if (spc->refcount == 0)
|
||||
owner.reset(spc); // Take ownership if this is the first reference
|
||||
switch(spc->getType()) {
|
||||
case IPTR_CONSTANT:
|
||||
if (spc->getName() != ConstantSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized with wrong type");
|
||||
if (spc->index != ConstantSpace::INDEX)
|
||||
throw LowlevelError("const space must be assigned index 0");
|
||||
constantspace = spc;
|
||||
break;
|
||||
case IPTR_INTERNAL:
|
||||
if (spc->getName() != UniqueSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized with wrong type");
|
||||
if (uniqspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
uniqspace = spc;
|
||||
break;
|
||||
case IPTR_FSPEC:
|
||||
if (spc->getName() != "fspec")
|
||||
nameTypeMismatch = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized with wrong type");
|
||||
if (fspecspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
fspecspace = spc;
|
||||
break;
|
||||
case IPTR_JOIN:
|
||||
if (spc->getName() != JoinSpace::NAME)
|
||||
nameTypeMismatch = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized with wrong type");
|
||||
if (joinspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
joinspace = spc;
|
||||
break;
|
||||
case IPTR_IOP:
|
||||
if (spc->getName() != "iop")
|
||||
nameTypeMismatch = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized with wrong type");
|
||||
if (iopspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
iopspace = spc;
|
||||
break;
|
||||
case IPTR_SPACEBASE:
|
||||
if (spc->getName() == "stack") {
|
||||
if (stackspace != (AddrSpace *)0)
|
||||
duplicateName = true;
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
stackspace = spc;
|
||||
}
|
||||
// fallthru
|
||||
@@ -412,26 +412,14 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
||||
if (baselist.size() <= spc->index)
|
||||
baselist.resize(spc->index+1, (AddrSpace *)0);
|
||||
|
||||
duplicateId = baselist[spc->index] != (AddrSpace *)0;
|
||||
if (baselist[spc->index] != (AddrSpace *)0)
|
||||
throw LowlevelError("Space " + spc->getName() + " was assigned id duplicating: "+baselist[spc->index]->getName());
|
||||
|
||||
if (!nameTypeMismatch && !duplicateName && !duplicateId) {
|
||||
duplicateName = !name2Space.insert(pair<string,AddrSpace *>(spc->getName(),spc)).second;
|
||||
}
|
||||
if (!name2Space.insert(pair<string,AddrSpace *>(spc->getName(),spc)).second)
|
||||
throw LowlevelError("Space " + spc->getName() + " was initialized more than once");
|
||||
|
||||
if (nameTypeMismatch || duplicateName || duplicateId) {
|
||||
string errMsg = "Space " + spc->getName();
|
||||
if (nameTypeMismatch)
|
||||
errMsg = errMsg + " was initialized with wrong type";
|
||||
if (duplicateName)
|
||||
errMsg = errMsg + " was initialized more than once";
|
||||
if (duplicateId)
|
||||
errMsg = errMsg + " was assigned as id duplicating: "+baselist[spc->index]->getName();
|
||||
if (spc->refcount == 0)
|
||||
delete spc;
|
||||
spc = (AddrSpace *)0;
|
||||
throw LowlevelError(errMsg);
|
||||
}
|
||||
baselist[spc->index] = spc;
|
||||
owner.release();
|
||||
spc->refcount += 1;
|
||||
assignShortcut(spc);
|
||||
}
|
||||
@@ -1024,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];
|
||||
@@ -1033,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
|
||||
|
||||
@@ -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.
|
||||
@@ -490,6 +490,7 @@ UserPcodeOp *UserOpManage::registerBuiltin(uint4 i)
|
||||
void UserOpManage::registerOp(UserPcodeOp *op)
|
||||
|
||||
{
|
||||
unique_ptr<UserPcodeOp> owner(op); // Take ownership
|
||||
int4 ind = op->getIndex();
|
||||
if (ind < 0) throw LowlevelError("UserOp not assigned an index");
|
||||
|
||||
@@ -509,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] = op; // Index crossref
|
||||
useroplist[ind] = owner.release(); // Index crossref
|
||||
useropmap[op->getName()] = op; // Name crossref
|
||||
|
||||
SegmentOp *s_op = dynamic_cast<SegmentOp *>(op);
|
||||
@@ -533,15 +534,9 @@ void UserOpManage::registerOp(UserPcodeOp *op)
|
||||
void UserOpManage::decodeSegmentOp(Decoder &decoder,Architecture *glb)
|
||||
|
||||
{
|
||||
SegmentOp *s_op;
|
||||
s_op = new SegmentOp("",glb,useroplist.size());
|
||||
try {
|
||||
s_op->decode(decoder);
|
||||
registerOp(s_op);
|
||||
} catch(LowlevelError &err) {
|
||||
delete s_op;
|
||||
throw err;
|
||||
}
|
||||
unique_ptr<UserPcodeOp> s_op(new SegmentOp("",glb,useroplist.size()));
|
||||
s_op->decode(decoder);
|
||||
registerOp(s_op.release());
|
||||
}
|
||||
|
||||
/// Create either a VolatileReadOp or VolatileWriteOp description object based on
|
||||
@@ -589,14 +584,9 @@ void UserOpManage::decodeVolatile(Decoder &decoder,Architecture *glb)
|
||||
void UserOpManage::decodeCallOtherFixup(Decoder &decoder,Architecture *glb)
|
||||
|
||||
{
|
||||
InjectedUserOp *op = new InjectedUserOp("",glb,0,0);
|
||||
try {
|
||||
op->decode(decoder);
|
||||
registerOp(op);
|
||||
} catch(LowlevelError &err) {
|
||||
delete op;
|
||||
throw err;
|
||||
}
|
||||
unique_ptr<UserPcodeOp> op(new InjectedUserOp("",glb,0,0));
|
||||
op->decode(decoder);
|
||||
registerOp(op.release());
|
||||
}
|
||||
|
||||
/// Create a JumpAssistOp description object based on the element
|
||||
@@ -606,14 +596,9 @@ void UserOpManage::decodeCallOtherFixup(Decoder &decoder,Architecture *glb)
|
||||
void UserOpManage::decodeJumpAssist(Decoder &decoder,Architecture *glb)
|
||||
|
||||
{
|
||||
JumpAssistOp *op = new JumpAssistOp(glb);
|
||||
try {
|
||||
op->decode(decoder);
|
||||
registerOp(op);
|
||||
} catch(LowlevelError &err) {
|
||||
delete op;
|
||||
throw err;
|
||||
}
|
||||
unique_ptr<UserPcodeOp> op(new JumpAssistOp(glb));
|
||||
op->decode(decoder);
|
||||
registerOp(op.release());
|
||||
}
|
||||
|
||||
/// \brief Manually install an InjectedUserOp given just names of the user defined op and the p-code snippet
|
||||
@@ -637,12 +622,7 @@ void UserOpManage::manualCallOtherFixup(const string &useropname,const string &o
|
||||
|
||||
int4 injectid = glb->pcodeinjectlib->manualCallOtherFixup(useropname,outname,inname,snippet);
|
||||
InjectedUserOp *op = new InjectedUserOp(useropname,glb,userop->getIndex(),injectid);
|
||||
try {
|
||||
registerOp(op);
|
||||
} catch(LowlevelError &err) {
|
||||
delete op;
|
||||
throw err;
|
||||
}
|
||||
registerOp(op);
|
||||
}
|
||||
|
||||
} // End namespace ghidra
|
||||
|
||||
@@ -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