mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Local collision warnings in SLEIGH
This commit is contained in:
commit
bac68e5949
14 changed files with 340 additions and 42 deletions
|
@ -797,6 +797,19 @@ int4 ConstructTpl::fillinBuild(vector<int4> &check,AddrSpace *const_space)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConstructTpl::buildOnly(void) const
|
||||||
|
|
||||||
|
{
|
||||||
|
vector<OpTpl *>::const_iterator iter;
|
||||||
|
OpTpl *op;
|
||||||
|
for(iter=vec.begin();iter!=vec.end();++iter) {
|
||||||
|
op = *iter;
|
||||||
|
if (op->getOpcode() != BUILD)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ConstructTpl::changeHandleIndex(const vector<int4> &handmap)
|
void ConstructTpl::changeHandleIndex(const vector<int4> &handmap)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -178,6 +178,7 @@ public:
|
||||||
bool addOpList(const vector<OpTpl *> &oplist);
|
bool addOpList(const vector<OpTpl *> &oplist);
|
||||||
void setResult(HandleTpl *t) { result = t; }
|
void setResult(HandleTpl *t) { result = t; }
|
||||||
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
|
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
|
||||||
|
bool buildOnly(void) const;
|
||||||
void changeHandleIndex(const vector<int4> &handmap);
|
void changeHandleIndex(const vector<int4> &handmap);
|
||||||
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
|
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
|
||||||
void setOutput(VarnodeTpl *vn,int4 index);
|
void setOutput(VarnodeTpl *vn,int4 index);
|
||||||
|
|
|
@ -1463,6 +1463,7 @@ SleighCompile::SleighCompile(void)
|
||||||
warnunnecessarypcode = false;
|
warnunnecessarypcode = false;
|
||||||
warndeadtemps = false;
|
warndeadtemps = false;
|
||||||
lenientconflicterrors = true;
|
lenientconflicterrors = true;
|
||||||
|
warnalllocalcollisions = false;
|
||||||
warnallnops = false;
|
warnallnops = false;
|
||||||
root = (SubtableSymbol *)0;
|
root = (SubtableSymbol *)0;
|
||||||
}
|
}
|
||||||
|
@ -1620,6 +1621,74 @@ void SleighCompile::checkConsistency(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int4 SleighCompile::findCollision(map<uintb,int4> &local2Operand,const vector<uintb> &locals,int operand)
|
||||||
|
|
||||||
|
{
|
||||||
|
for(int4 i=0;i<locals.size();++i) {
|
||||||
|
pair<map<uintb,int4>::iterator,bool> res;
|
||||||
|
res = local2Operand.insert(pair<uintb,int4>(locals[i],operand));
|
||||||
|
if (!res.second) {
|
||||||
|
int4 oldIndex = (*res.first).second;
|
||||||
|
if (oldIndex != operand)
|
||||||
|
return oldIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SleighCompile::checkLocalExports(Constructor *ct)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (ct->getTempl() == (ConstructTpl *)0)
|
||||||
|
return true; // No template, collisions impossible
|
||||||
|
if (ct->getTempl()->buildOnly())
|
||||||
|
return true; // Operand exports aren't manipulated, so no collision is possible
|
||||||
|
if (ct->getNumOperands() < 2)
|
||||||
|
return true; // Collision can only happen with multiple operands
|
||||||
|
bool noCollisions = true;
|
||||||
|
map<uintb,int4> collect;
|
||||||
|
for(int4 i=0;i<ct->getNumOperands();++i) {
|
||||||
|
vector<uintb> newCollect;
|
||||||
|
ct->getOperand(i)->collectLocalValues(newCollect);
|
||||||
|
if (newCollect.empty()) continue;
|
||||||
|
int4 collideOperand = findCollision(collect, newCollect, i);
|
||||||
|
if (collideOperand >= 0) {
|
||||||
|
noCollisions = false;
|
||||||
|
if (warnalllocalcollisions) {
|
||||||
|
cerr << "Possible collision with symbols ";
|
||||||
|
cerr << ct->getOperand(collideOperand)->getName();
|
||||||
|
cerr << " and " << ct->getOperand(i)->getName();
|
||||||
|
cerr << " in constructor starting at line " << dec << ct->getLineno() << endl;
|
||||||
|
}
|
||||||
|
break; // Don't continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noCollisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighCompile::checkLocalCollisions(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
int4 collisionCount = 0;
|
||||||
|
SubtableSymbol *sym = root; // Start with the instruction table
|
||||||
|
int4 i = -1;
|
||||||
|
for(;;) {
|
||||||
|
int4 numconst = sym->getNumConstructors();
|
||||||
|
for(int4 j=0;j<numconst;++j) {
|
||||||
|
if (!checkLocalExports(sym->getConstructor(j)))
|
||||||
|
collisionCount += 1;
|
||||||
|
}
|
||||||
|
i+=1;
|
||||||
|
if (i>=tables.size()) break;
|
||||||
|
sym = tables[i];
|
||||||
|
}
|
||||||
|
if (collisionCount > 0) {
|
||||||
|
cerr << "WARNING: " << dec << collisionCount << " constructors with local collisions between operands" << endl;
|
||||||
|
if (!warnalllocalcollisions)
|
||||||
|
cerr << "Use -c switch to list each individually" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SleighCompile::checkNops(void)
|
void SleighCompile::checkNops(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1701,6 +1770,8 @@ void SleighCompile::process(void)
|
||||||
if (errors>0) return;
|
if (errors>0) return;
|
||||||
checkConsistency();
|
checkConsistency();
|
||||||
if (errors>0) return;
|
if (errors>0) return;
|
||||||
|
checkLocalCollisions();
|
||||||
|
if (errors>0) return;
|
||||||
buildPatterns();
|
buildPatterns();
|
||||||
if (errors>0) return;
|
if (errors>0) return;
|
||||||
buildDecisionTrees();
|
buildDecisionTrees();
|
||||||
|
@ -2690,7 +2761,8 @@ static void findSlaSpecs(vector<string> &res, const string &dir, const string &s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initCompiler(SleighCompile &compiler, map<string,string> &defines, bool enableUnnecessaryPcodeWarning, bool disableLenientConflict,
|
static void initCompiler(SleighCompile &compiler, map<string,string> &defines, bool enableUnnecessaryPcodeWarning,
|
||||||
|
bool disableLenientConflict, bool enableAllCollisionWarning,
|
||||||
bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord)
|
bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2698,21 +2770,18 @@ static void initCompiler(SleighCompile &compiler, map<string,string> &defines, b
|
||||||
for (iter = defines.begin(); iter != defines.end(); iter++) {
|
for (iter = defines.begin(); iter != defines.end(); iter++) {
|
||||||
compiler.setPreprocValue((*iter).first, (*iter).second);
|
compiler.setPreprocValue((*iter).first, (*iter).second);
|
||||||
}
|
}
|
||||||
if (enableUnnecessaryPcodeWarning) {
|
if (enableUnnecessaryPcodeWarning)
|
||||||
compiler.setUnnecessaryPcodeWarning(true);
|
compiler.setUnnecessaryPcodeWarning(true);
|
||||||
}
|
if (disableLenientConflict)
|
||||||
if (disableLenientConflict) {
|
|
||||||
compiler.setLenientConflict(false);
|
compiler.setLenientConflict(false);
|
||||||
}
|
if (enableAllCollisionWarning)
|
||||||
if (enableAllNopWarning) {
|
compiler.setLocalCollisionWarning( true );
|
||||||
|
if (enableAllNopWarning)
|
||||||
compiler.setAllNopWarning( true );
|
compiler.setAllNopWarning( true );
|
||||||
}
|
if (enableDeadTempWarning)
|
||||||
if (enableDeadTempWarning) {
|
|
||||||
compiler.setDeadTempWarning(true);
|
compiler.setDeadTempWarning(true);
|
||||||
}
|
if (enforceLocalKeyWord)
|
||||||
if (enforceLocalKeyWord) {
|
compiler.setEnforceLocalKeyWord(true);
|
||||||
compiler.setEnforceLocalKeyWord(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void segvHandler(int sig) {
|
static void segvHandler(int sig) {
|
||||||
|
@ -2739,6 +2808,7 @@ int main(int argc,char **argv)
|
||||||
cerr << " -n print warnings for all NOP constructors" << endl;
|
cerr << " -n print warnings for all NOP constructors" << endl;
|
||||||
cerr << " -t print warnings for dead temporaries" << endl;
|
cerr << " -t print warnings for dead temporaries" << endl;
|
||||||
cerr << " -e enforce use of 'local' keyword for temporaries" << endl;
|
cerr << " -e enforce use of 'local' keyword for temporaries" << endl;
|
||||||
|
cerr << " -c print warnings for all constructors with colliding operands" << endl;
|
||||||
cerr << " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE" << endl;
|
cerr << " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE" << endl;
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
@ -2748,6 +2818,7 @@ int main(int argc,char **argv)
|
||||||
map<string,string> defines;
|
map<string,string> defines;
|
||||||
bool enableUnnecessaryPcodeWarning = false;
|
bool enableUnnecessaryPcodeWarning = false;
|
||||||
bool disableLenientConflict = false;
|
bool disableLenientConflict = false;
|
||||||
|
bool enableAllCollisionWarning = false;
|
||||||
bool enableAllNopWarning = false;
|
bool enableAllNopWarning = false;
|
||||||
bool enableDeadTempWarning = false;
|
bool enableDeadTempWarning = false;
|
||||||
bool enforceLocalKeyWord = false;
|
bool enforceLocalKeyWord = false;
|
||||||
|
@ -2774,6 +2845,8 @@ int main(int argc,char **argv)
|
||||||
enableUnnecessaryPcodeWarning = true;
|
enableUnnecessaryPcodeWarning = true;
|
||||||
else if (argv[i][1] == 'l')
|
else if (argv[i][1] == 'l')
|
||||||
disableLenientConflict = true;
|
disableLenientConflict = true;
|
||||||
|
else if (argv[i][1] == 'c')
|
||||||
|
enableAllCollisionWarning = true;
|
||||||
else if (argv[i][1] == 'n')
|
else if (argv[i][1] == 'n')
|
||||||
enableAllNopWarning = true;
|
enableAllNopWarning = true;
|
||||||
else if (argv[1][1] == 't')
|
else if (argv[1][1] == 't')
|
||||||
|
@ -2811,7 +2884,8 @@ int main(int argc,char **argv)
|
||||||
sla.replace(slaspec.length() - slaspecExtLen, slaspecExtLen, SLAEXT);
|
sla.replace(slaspec.length() - slaspecExtLen, slaspecExtLen, SLAEXT);
|
||||||
SleighCompile compiler;
|
SleighCompile compiler;
|
||||||
initCompiler(compiler, defines, enableUnnecessaryPcodeWarning,
|
initCompiler(compiler, defines, enableUnnecessaryPcodeWarning,
|
||||||
disableLenientConflict, enableAllNopWarning, enableDeadTempWarning, enforceLocalKeyWord);
|
disableLenientConflict, enableAllCollisionWarning, enableAllNopWarning,
|
||||||
|
enableDeadTempWarning, enforceLocalKeyWord);
|
||||||
retval = run_compilation(slaspec.c_str(),sla.c_str(),compiler);
|
retval = run_compilation(slaspec.c_str(),sla.c_str(),compiler);
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
return retval; // stop on first error
|
return retval; // stop on first error
|
||||||
|
@ -2844,7 +2918,8 @@ int main(int argc,char **argv)
|
||||||
|
|
||||||
SleighCompile compiler;
|
SleighCompile compiler;
|
||||||
initCompiler(compiler, defines, enableUnnecessaryPcodeWarning,
|
initCompiler(compiler, defines, enableUnnecessaryPcodeWarning,
|
||||||
disableLenientConflict, enableAllNopWarning, enableDeadTempWarning, enforceLocalKeyWord);
|
disableLenientConflict, enableAllCollisionWarning, enableAllNopWarning,
|
||||||
|
enableDeadTempWarning, enforceLocalKeyWord);
|
||||||
|
|
||||||
if (i < argc - 1) {
|
if (i < argc - 1) {
|
||||||
string fileoutExamine(argv[i+1]);
|
string fileoutExamine(argv[i+1]);
|
||||||
|
|
|
@ -195,6 +195,7 @@ private:
|
||||||
bool warnunnecessarypcode; // True if we warn of unnecessary ZEXT or SEXT
|
bool warnunnecessarypcode; // True if we warn of unnecessary ZEXT or SEXT
|
||||||
bool warndeadtemps; // True if we warn of temporaries that are written but not read
|
bool warndeadtemps; // True if we warn of temporaries that are written but not read
|
||||||
bool lenientconflicterrors; // True if we ignore most pattern conflict errors
|
bool lenientconflicterrors; // True if we ignore most pattern conflict errors
|
||||||
|
bool warnalllocalcollisions; // True if local export collisions generate individual warnings
|
||||||
bool warnallnops; // True if pcode NOPs generate individual warnings
|
bool warnallnops; // True if pcode NOPs generate individual warnings
|
||||||
vector<string> noplist; // List of individual NOP warnings
|
vector<string> noplist; // List of individual NOP warnings
|
||||||
int4 errors;
|
int4 errors;
|
||||||
|
@ -203,6 +204,9 @@ private:
|
||||||
void buildDecisionTrees(void);
|
void buildDecisionTrees(void);
|
||||||
void buildPatterns(void);
|
void buildPatterns(void);
|
||||||
void checkConsistency(void);
|
void checkConsistency(void);
|
||||||
|
static int4 findCollision(map<uintb,int4> &local2Operand,const vector<uintb> &locals,int operand);
|
||||||
|
bool checkLocalExports(Constructor *ct);
|
||||||
|
void checkLocalCollisions(void);
|
||||||
void checkNops(void);
|
void checkNops(void);
|
||||||
string checkSymbols(SymbolScope *scope);
|
string checkSymbols(SymbolScope *scope);
|
||||||
void addSymbol(SleighSymbol *sym);
|
void addSymbol(SleighSymbol *sym);
|
||||||
|
@ -224,6 +228,7 @@ public:
|
||||||
void setDeadTempWarning(bool val) { warndeadtemps = val; }
|
void setDeadTempWarning(bool val) { warndeadtemps = val; }
|
||||||
void setEnforceLocalKeyWord(bool val) { pcode.setEnforceLocalKey(val); }
|
void setEnforceLocalKeyWord(bool val) { pcode.setEnforceLocalKey(val); }
|
||||||
void setLenientConflict(bool val) { lenientconflicterrors = val; }
|
void setLenientConflict(bool val) { lenientconflicterrors = val; }
|
||||||
|
void setLocalCollisionWarning(bool val) { warnalllocalcollisions = val; }
|
||||||
void setAllNopWarning(bool val) { warnallnops = val; }
|
void setAllNopWarning(bool val) { warnallnops = val; }
|
||||||
void process(void);
|
void process(void);
|
||||||
|
|
||||||
|
|
|
@ -728,6 +728,13 @@ void VarnodeSymbol::getFixedHandle(FixedHandle &hand,ParserWalker &walker) const
|
||||||
hand.size = fix.size;
|
hand.size = fix.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VarnodeSymbol::collectLocalValues(vector<uintb> &results) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (fix.space->getType() == IPTR_INTERNAL)
|
||||||
|
results.push_back(fix.offset);
|
||||||
|
}
|
||||||
|
|
||||||
void VarnodeSymbol::saveXml(ostream &s) const
|
void VarnodeSymbol::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1034,6 +1041,13 @@ void OperandSymbol::print(ostream &s,ParserWalker &walker) const
|
||||||
walker.popOperand();
|
walker.popOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OperandSymbol::collectLocalValues(vector<uintb> &results) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (triple != (TripleSymbol *)0)
|
||||||
|
triple->collectLocalValues(results);
|
||||||
|
}
|
||||||
|
|
||||||
void OperandSymbol::saveXml(ostream &s) const
|
void OperandSymbol::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1542,6 +1556,29 @@ void Constructor::markSubtableOperands(vector<int4> &check) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Constructor::collectLocalExports(vector<uintb> &results) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (templ == (ConstructTpl *)0) return;
|
||||||
|
HandleTpl *handle = templ->getResult();
|
||||||
|
if (handle == (HandleTpl *)0) return;
|
||||||
|
if (handle->getSpace().isConstSpace()) return; // Even if the value is dynamic, the pointed to value won't get used
|
||||||
|
if (handle->getPtrSpace().getType() != ConstTpl::real) {
|
||||||
|
if (handle->getTempSpace().isUniqueSpace())
|
||||||
|
results.push_back(handle->getTempOffset().getReal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handle->getSpace().isUniqueSpace()) {
|
||||||
|
results.push_back(handle->getPtrOffset().getReal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handle->getSpace().getType() == ConstTpl::handle) {
|
||||||
|
int4 handleIndex = handle->getSpace().getHandleIndex();
|
||||||
|
OperandSymbol *opSym = getOperand(handleIndex);
|
||||||
|
opSym->collectLocalValues(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Constructor::isRecursive(void) const
|
bool Constructor::isRecursive(void) const
|
||||||
|
|
||||||
{ // Does this constructor cause recursion with its table
|
{ // Does this constructor cause recursion with its table
|
||||||
|
@ -1862,6 +1899,13 @@ SubtableSymbol::~SubtableSymbol(void)
|
||||||
delete *iter;
|
delete *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubtableSymbol::collectLocalValues(vector<uintb> &results) const
|
||||||
|
|
||||||
|
{
|
||||||
|
for(int4 i=0;i<construct.size();++i)
|
||||||
|
construct[i]->collectLocalExports(results);
|
||||||
|
}
|
||||||
|
|
||||||
void SubtableSymbol::saveXml(ostream &s) const
|
void SubtableSymbol::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,7 @@ public:
|
||||||
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
|
||||||
virtual int4 getSize(void) const { return 0; } // Size out of context
|
virtual int4 getSize(void) const { return 0; } // Size out of context
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const=0;
|
virtual void print(ostream &s,ParserWalker &walker) const=0;
|
||||||
|
virtual void collectLocalValues(vector<uintb> &results) const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FamilySymbol : public TripleSymbol {
|
class FamilySymbol : public TripleSymbol {
|
||||||
|
@ -254,6 +255,7 @@ public:
|
||||||
virtual int4 getSize(void) const { return fix.size; }
|
virtual int4 getSize(void) const { return fix.size; }
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const {
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
||||||
s << getName(); }
|
s << getName(); }
|
||||||
|
virtual void collectLocalValues(vector<uintb> &results) const;
|
||||||
virtual symbol_type getType(void) const { return varnode_symbol; }
|
virtual symbol_type getType(void) const { return varnode_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
@ -348,6 +350,7 @@ public:
|
||||||
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
|
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
|
||||||
virtual int4 getSize(void) const;
|
virtual int4 getSize(void) const;
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const;
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
||||||
|
virtual void collectLocalValues(vector<uintb> &results) const;
|
||||||
virtual symbol_type getType(void) const { return operand_symbol; }
|
virtual symbol_type getType(void) const { return operand_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
@ -513,6 +516,7 @@ public:
|
||||||
(*iter)->apply(walker);
|
(*iter)->apply(walker);
|
||||||
}
|
}
|
||||||
void markSubtableOperands(vector<int4> &check) const;
|
void markSubtableOperands(vector<int4> &check) const;
|
||||||
|
void collectLocalExports(vector<uintb> &results) const;
|
||||||
void setError(bool val) const { inerror = val; }
|
void setError(bool val) const { inerror = val; }
|
||||||
bool isError(void) const { return inerror; }
|
bool isError(void) const { return inerror; }
|
||||||
bool isRecursive(void) const;
|
bool isRecursive(void) const;
|
||||||
|
@ -578,6 +582,7 @@ public:
|
||||||
virtual int4 getSize(void) const { return -1; }
|
virtual int4 getSize(void) const { return -1; }
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const {
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
||||||
throw SleighError("Cannot use subtable in expression"); }
|
throw SleighError("Cannot use subtable in expression"); }
|
||||||
|
virtual void collectLocalValues(vector<uintb> &results) const;
|
||||||
virtual symbol_type getType(void) const { return subtable_symbol; }
|
virtual symbol_type getType(void) const { return subtable_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.pcodeCPort.semantics;
|
package ghidra.pcodeCPort.semantics;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
import generic.stl.*;
|
import generic.stl.*;
|
||||||
import ghidra.pcodeCPort.opcodes.OpCode;
|
import ghidra.pcodeCPort.opcodes.OpCode;
|
||||||
import ghidra.pcodeCPort.space.AddrSpace;
|
import ghidra.pcodeCPort.space.AddrSpace;
|
||||||
|
@ -24,11 +28,6 @@ import ghidra.pcodeCPort.utils.XmlUtils;
|
||||||
import ghidra.sleigh.grammar.Location;
|
import ghidra.sleigh.grammar.Location;
|
||||||
import ghidra.sleigh.grammar.LocationUtil;
|
import ghidra.sleigh.grammar.LocationUtil;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.jdom.Element;
|
|
||||||
|
|
||||||
public class ConstructTpl {
|
public class ConstructTpl {
|
||||||
public final Location loc;
|
public final Location loc;
|
||||||
protected int delayslot;
|
protected int delayslot;
|
||||||
|
@ -138,6 +137,15 @@ public class ConstructTpl {
|
||||||
return new Pair<Integer, Location>(0, null);
|
return new Pair<Integer, Location>(0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean buildOnly() {
|
||||||
|
for (OpTpl op : vec) {
|
||||||
|
if (op.getOpcode() != OpCode.CPUI_MULTIEQUAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void changeHandleIndex(VectorSTL<Integer> handmap) {
|
public void changeHandleIndex(VectorSTL<Integer> handmap) {
|
||||||
IteratorSTL<OpTpl> iter;
|
IteratorSTL<OpTpl> iter;
|
||||||
for (iter = vec.begin(); !iter.isEnd(); iter.increment()) {
|
for (iter = vec.begin(); !iter.isEnd(); iter.increment()) {
|
||||||
|
|
|
@ -255,6 +255,7 @@ public class SleighCompile extends SleighBase {
|
||||||
boolean warnunusedfields; // True if fields are defined but not used
|
boolean warnunusedfields; // True if fields are defined but not used
|
||||||
boolean enforcelocalkeyword; // Force slaspec to use 'local' keyword when defining temporary varnodes
|
boolean enforcelocalkeyword; // Force slaspec to use 'local' keyword when defining temporary varnodes
|
||||||
boolean lenientconflicterrors; // True if we ignore most pattern conflict errors
|
boolean lenientconflicterrors; // True if we ignore most pattern conflict errors
|
||||||
|
public boolean warnalllocalcollisions;
|
||||||
public boolean warnallnops;
|
public boolean warnallnops;
|
||||||
public VectorSTL<String> noplist = new VectorSTL<>();
|
public VectorSTL<String> noplist = new VectorSTL<>();
|
||||||
|
|
||||||
|
@ -517,6 +518,79 @@ public class SleighCompile extends SleighBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int findCollision(Map<Long, Integer> local2Operand, ArrayList<Long> locals,
|
||||||
|
int operand) {
|
||||||
|
Integer boxOperand = Integer.valueOf(operand);
|
||||||
|
for (int i = 0; i < locals.size(); ++i) {
|
||||||
|
Integer previous = local2Operand.putIfAbsent(locals.get(i), boxOperand);
|
||||||
|
if (previous != null) {
|
||||||
|
if (previous.intValue() != operand) {
|
||||||
|
return previous.intValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkLocalExports(Constructor ct) {
|
||||||
|
if (ct.getTempl() == null) {
|
||||||
|
return true; // No template, collisions impossible
|
||||||
|
}
|
||||||
|
if (ct.getTempl().buildOnly()) {
|
||||||
|
return true; // Operand exports aren't manipulated, so no collision is possible
|
||||||
|
}
|
||||||
|
if (ct.getNumOperands() < 2) {
|
||||||
|
return true; // Collisions can only happen with multiple operands
|
||||||
|
}
|
||||||
|
boolean noCollisions = true;
|
||||||
|
Map<Long, Integer> collect = new TreeMap<Long, Integer>();
|
||||||
|
for (int i = 0; i < ct.getNumOperands(); ++i) {
|
||||||
|
ArrayList<Long> newCollect = new ArrayList<Long>();
|
||||||
|
ct.getOperand(i).collectLocalValues(newCollect);
|
||||||
|
if (newCollect.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int collideOperand = findCollision(collect, newCollect, i);
|
||||||
|
if (collideOperand >= 0) {
|
||||||
|
noCollisions = false;
|
||||||
|
if (warnalllocalcollisions) {
|
||||||
|
Msg.warn(this, "Possible collision with symbol " +
|
||||||
|
ct.getOperand(collideOperand).getName() + " and " +
|
||||||
|
ct.getOperand(i).getName() + " in constructor from " + ct.getFilename() +
|
||||||
|
" starting at line " + Integer.toString(ct.getLineno()));
|
||||||
|
}
|
||||||
|
break; // Don't continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noCollisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkLocalCollisions() {
|
||||||
|
int collisionCount = 0;
|
||||||
|
SubtableSymbol sym = root; // Start with the instruction table
|
||||||
|
int i = -1;
|
||||||
|
for (;;) {
|
||||||
|
int numconst = sym.getNumConstructors();
|
||||||
|
for (int j = 0; j < numconst; ++j) {
|
||||||
|
if (!checkLocalExports(sym.getConstructor(j))) {
|
||||||
|
collisionCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
if (i >= tables.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sym = tables.get(i);
|
||||||
|
}
|
||||||
|
if (collisionCount > 0) {
|
||||||
|
Msg.warn(this, "WARNING: " + Integer.toString(collisionCount) +
|
||||||
|
" constructors with local collisions between operands");
|
||||||
|
if (!warnalllocalcollisions) {
|
||||||
|
Msg.warn(this, "Use -c switch to list each individually");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure label symbols are used properly
|
// Make sure label symbols are used properly
|
||||||
String checkSymbols(SymbolScope scope) {
|
String checkSymbols(SymbolScope scope) {
|
||||||
entry("checkSymbols", scope);
|
entry("checkSymbols", scope);
|
||||||
|
@ -638,6 +712,11 @@ public class SleighCompile extends SleighBase {
|
||||||
lenientconflicterrors = val;
|
lenientconflicterrors = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLocalCollisionWarning(boolean val) {
|
||||||
|
entry("setLocalCollisionWarning", val);
|
||||||
|
warnalllocalcollisions = val;
|
||||||
|
}
|
||||||
|
|
||||||
void setAllNopWarning(boolean val) {
|
void setAllNopWarning(boolean val) {
|
||||||
entry("setAllNopWarning", val);
|
entry("setAllNopWarning", val);
|
||||||
warnallnops = val;
|
warnallnops = val;
|
||||||
|
@ -656,6 +735,10 @@ public class SleighCompile extends SleighBase {
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
checkLocalCollisions();
|
||||||
|
if (errors > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
buildPatterns();
|
buildPatterns();
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -47,14 +47,16 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
pathname -> pathname.getName().endsWith(".slaspec");
|
pathname -> pathname.getName().endsWith(".slaspec");
|
||||||
|
|
||||||
private static void initCompiler(SleighCompile compiler, Map<String, String> preprocs,
|
private static void initCompiler(SleighCompile compiler, Map<String, String> preprocs,
|
||||||
boolean unnecessaryPcodeWarning, boolean lenientConflict, boolean allNopWarning,
|
boolean unnecessaryPcodeWarning, boolean lenientConflict, boolean allCollisionWarning,
|
||||||
boolean deadTempWarning, boolean unusedFieldWarning, boolean enforceLocalKeyWord) {
|
boolean allNopWarning, boolean deadTempWarning, boolean unusedFieldWarning,
|
||||||
|
boolean enforceLocalKeyWord) {
|
||||||
Set<Entry<String, String>> entrySet = preprocs.entrySet();
|
Set<Entry<String, String>> entrySet = preprocs.entrySet();
|
||||||
for (Entry<String, String> entry : entrySet) {
|
for (Entry<String, String> entry : entrySet) {
|
||||||
compiler.setPreprocValue(entry.getKey(), entry.getValue());
|
compiler.setPreprocValue(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
compiler.setUnnecessaryPcodeWarning(unnecessaryPcodeWarning);
|
compiler.setUnnecessaryPcodeWarning(unnecessaryPcodeWarning);
|
||||||
compiler.setLenientConflict(lenientConflict);
|
compiler.setLenientConflict(lenientConflict);
|
||||||
|
compiler.setLocalCollisionWarning(allCollisionWarning);
|
||||||
compiler.setAllNopWarning(allNopWarning);
|
compiler.setAllNopWarning(allNopWarning);
|
||||||
compiler.setDeadTempWarning(deadTempWarning);
|
compiler.setDeadTempWarning(deadTempWarning);
|
||||||
compiler.setUnusedFieldWarning(unusedFieldWarning);
|
compiler.setUnusedFieldWarning(unusedFieldWarning);
|
||||||
|
@ -107,6 +109,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
Msg.info(SleighCompile.class, " -n print warnings for all NOP constructors");
|
Msg.info(SleighCompile.class, " -n print warnings for all NOP constructors");
|
||||||
Msg.info(SleighCompile.class, " -t print warnings for dead temporaries");
|
Msg.info(SleighCompile.class, " -t print warnings for dead temporaries");
|
||||||
Msg.info(SleighCompile.class, " -e enforce use of 'local' keyword for temporaries");
|
Msg.info(SleighCompile.class, " -e enforce use of 'local' keyword for temporaries");
|
||||||
|
Msg.info(SleighCompile.class, " -c print warnings for all constructors with colliding operands");
|
||||||
Msg.info(SleighCompile.class, " -f print warnings for unused token fields");
|
Msg.info(SleighCompile.class, " -f print warnings for unused token fields");
|
||||||
Msg.info(SleighCompile.class, " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE (option may be repeated)");
|
Msg.info(SleighCompile.class, " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE (option may be repeated)");
|
||||||
Msg.info(SleighCompile.class, " -dMODULE defines a preprocessor macro MODULE with a value of its module path (option may be repeated)");
|
Msg.info(SleighCompile.class, " -dMODULE defines a preprocessor macro MODULE with a value of its module path (option may be repeated)");
|
||||||
|
@ -117,6 +120,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
|
|
||||||
boolean unnecessaryPcodeWarning = false;
|
boolean unnecessaryPcodeWarning = false;
|
||||||
boolean lenientConflict = true;
|
boolean lenientConflict = true;
|
||||||
|
boolean allCollisionWarning = false;
|
||||||
boolean allNopWarning = false;
|
boolean allNopWarning = false;
|
||||||
boolean deadTempWarning = false;
|
boolean deadTempWarning = false;
|
||||||
boolean enforceLocalKeyWord = false;
|
boolean enforceLocalKeyWord = false;
|
||||||
|
@ -172,6 +176,9 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
else if (args[i].charAt(1) == 'l') {
|
else if (args[i].charAt(1) == 'l') {
|
||||||
lenientConflict = false;
|
lenientConflict = false;
|
||||||
}
|
}
|
||||||
|
else if (args[i].charAt(1) == 'c') {
|
||||||
|
allCollisionWarning = true;
|
||||||
|
}
|
||||||
else if (args[i].charAt(1) == 'n') {
|
else if (args[i].charAt(1) == 'n') {
|
||||||
allNopWarning = true;
|
allNopWarning = true;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +218,7 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
System.out.println("Compiling " + input + ":");
|
System.out.println("Compiling " + input + ":");
|
||||||
SleighCompile compiler = new SleighCompile();
|
SleighCompile compiler = new SleighCompile();
|
||||||
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict,
|
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||||
|
allCollisionWarning,
|
||||||
allNopWarning, deadTempWarning, unusedFieldWarning, enforceLocalKeyWord);
|
allNopWarning, deadTempWarning, unusedFieldWarning, enforceLocalKeyWord);
|
||||||
|
|
||||||
String outname = input.getName().replace(".slaspec", ".sla");
|
String outname = input.getName().replace(".slaspec", ".sla");
|
||||||
|
@ -238,7 +246,8 @@ public class SleighCompileLauncher implements GhidraLaunchable {
|
||||||
|
|
||||||
// single file compile
|
// single file compile
|
||||||
SleighCompile compiler = new SleighCompile();
|
SleighCompile compiler = new SleighCompile();
|
||||||
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict, allNopWarning,
|
initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict,
|
||||||
|
allCollisionWarning, allNopWarning,
|
||||||
deadTempWarning, unusedFieldWarning, enforceLocalKeyWord);
|
deadTempWarning, unusedFieldWarning, enforceLocalKeyWord);
|
||||||
if (i == args.length) {
|
if (i == args.length) {
|
||||||
Msg.error(SleighCompile.class, "Missing input file name");
|
Msg.error(SleighCompile.class, "Missing input file name");
|
||||||
|
|
|
@ -16,15 +16,16 @@
|
||||||
package ghidra.pcodeCPort.slghsymbol;
|
package ghidra.pcodeCPort.slghsymbol;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
import generic.stl.IteratorSTL;
|
import generic.stl.IteratorSTL;
|
||||||
import generic.stl.VectorSTL;
|
import generic.stl.VectorSTL;
|
||||||
import ghidra.pcodeCPort.context.*;
|
import ghidra.pcodeCPort.context.*;
|
||||||
|
import ghidra.pcodeCPort.semantics.ConstTpl.const_type;
|
||||||
import ghidra.pcodeCPort.semantics.ConstructTpl;
|
import ghidra.pcodeCPort.semantics.ConstructTpl;
|
||||||
|
import ghidra.pcodeCPort.semantics.HandleTpl;
|
||||||
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
||||||
import ghidra.pcodeCPort.slghpatexpress.*;
|
import ghidra.pcodeCPort.slghpatexpress.*;
|
||||||
import ghidra.pcodeCPort.utils.XmlUtils;
|
import ghidra.pcodeCPort.utils.XmlUtils;
|
||||||
|
@ -132,6 +133,34 @@ public class Constructor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void collectLocalExports(ArrayList<Long> results) {
|
||||||
|
if (templ == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HandleTpl handle = templ.getResult();
|
||||||
|
if (handle == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handle.getSpace().isConstSpace()) {
|
||||||
|
return; // Even if the value is dynamic, the pointed to value won't get used
|
||||||
|
}
|
||||||
|
if (handle.getPtrSpace().getType() != const_type.real) {
|
||||||
|
if (handle.getTempSpace().isUniqueSpace()) {
|
||||||
|
results.add(handle.getTempOffset().getReal());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handle.getSpace().isUniqueSpace()) {
|
||||||
|
results.add(handle.getPtrOffset().getReal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (handle.getSpace().getType() == const_type.handle) {
|
||||||
|
int handleIndex = handle.getSpace().getHandleIndex();
|
||||||
|
OperandSymbol opSym = getOperand(handleIndex);
|
||||||
|
opSym.collectLocalValues(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setError(boolean val) {
|
public void setError(boolean val) {
|
||||||
inerror = val;
|
inerror = val;
|
||||||
}
|
}
|
||||||
|
@ -570,8 +599,9 @@ public class Constructor {
|
||||||
// in bytes
|
// in bytes
|
||||||
|
|
||||||
OperandResolve resolve = new OperandResolve(operands);
|
OperandResolve resolve = new OperandResolve(operands);
|
||||||
if (!pateq.resolveOperandLeft(resolve))
|
if (!pateq.resolveOperandLeft(resolve)) {
|
||||||
throw new SleighError("Unable to resolve operand offsets", location);
|
throw new SleighError("Unable to resolve operand offsets", location);
|
||||||
|
}
|
||||||
|
|
||||||
// Unravel relative offsets to absolute (if possible)
|
// Unravel relative offsets to absolute (if possible)
|
||||||
for (int i = 0; i < operands.size(); ++i) {
|
for (int i = 0; i < operands.size(); ++i) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.pcodeCPort.slghsymbol;
|
package ghidra.pcodeCPort.slghsymbol;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
import ghidra.pcodeCPort.context.*;
|
import ghidra.pcodeCPort.context.*;
|
||||||
import ghidra.pcodeCPort.semantics.VarnodeTpl;
|
import ghidra.pcodeCPort.semantics.VarnodeTpl;
|
||||||
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
||||||
|
@ -24,11 +29,6 @@ import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
|
||||||
import ghidra.pcodeCPort.utils.XmlUtils;
|
import ghidra.pcodeCPort.utils.XmlUtils;
|
||||||
import ghidra.sleigh.grammar.Location;
|
import ghidra.sleigh.grammar.Location;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jdom.Element;
|
|
||||||
|
|
||||||
public class OperandSymbol extends SpecificSymbol {
|
public class OperandSymbol extends SpecificSymbol {
|
||||||
|
|
||||||
public static final int code_address = 1;
|
public static final int code_address = 1;
|
||||||
|
@ -206,6 +206,13 @@ public class OperandSymbol extends SpecificSymbol {
|
||||||
pos.popOperand();
|
pos.popOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void collectLocalValues(ArrayList<Long> results) {
|
||||||
|
if (triple != null) {
|
||||||
|
triple.collectLocalValues(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveXml(PrintStream s) {
|
public void saveXml(PrintStream s) {
|
||||||
s.append("<operand_sym");
|
s.append("<operand_sym");
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.pcodeCPort.slghsymbol;
|
package ghidra.pcodeCPort.slghsymbol;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
import generic.stl.IteratorSTL;
|
import generic.stl.IteratorSTL;
|
||||||
import generic.stl.VectorSTL;
|
import generic.stl.VectorSTL;
|
||||||
import ghidra.pcodeCPort.context.*;
|
import ghidra.pcodeCPort.context.*;
|
||||||
|
@ -27,12 +31,6 @@ import ghidra.pcodeCPort.slghpattern.Pattern;
|
||||||
import ghidra.pcodeCPort.utils.XmlUtils;
|
import ghidra.pcodeCPort.utils.XmlUtils;
|
||||||
import ghidra.sleigh.grammar.Location;
|
import ghidra.sleigh.grammar.Location;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.jdom.Element;
|
|
||||||
|
|
||||||
public class SubtableSymbol extends TripleSymbol {
|
public class SubtableSymbol extends TripleSymbol {
|
||||||
|
|
||||||
private TokenPattern pattern;
|
private TokenPattern pattern;
|
||||||
|
@ -99,6 +97,13 @@ public class SubtableSymbol extends TripleSymbol {
|
||||||
throw new SleighError("Cannot use subtable in expression", null);
|
throw new SleighError("Cannot use subtable in expression", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void collectLocalValues(ArrayList<Long> results) {
|
||||||
|
for (Constructor curConstruct : construct) {
|
||||||
|
curConstruct.collectLocalExports(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public symbol_type getType() {
|
public symbol_type getType() {
|
||||||
return symbol_type.subtable_symbol;
|
return symbol_type.subtable_symbol;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,13 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.pcodeCPort.slghsymbol;
|
package ghidra.pcodeCPort.slghsymbol;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import ghidra.pcodeCPort.context.FixedHandle;
|
import ghidra.pcodeCPort.context.FixedHandle;
|
||||||
import ghidra.pcodeCPort.context.ParserWalker;
|
import ghidra.pcodeCPort.context.ParserWalker;
|
||||||
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
|
import ghidra.pcodeCPort.slghpatexpress.PatternExpression;
|
||||||
import ghidra.sleigh.grammar.Location;
|
import ghidra.sleigh.grammar.Location;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
// This is the central sleigh object
|
// This is the central sleigh object
|
||||||
public abstract class TripleSymbol extends SleighSymbol {
|
public abstract class TripleSymbol extends SleighSymbol {
|
||||||
|
|
||||||
|
@ -44,6 +44,10 @@ public abstract class TripleSymbol extends SleighSymbol {
|
||||||
|
|
||||||
public abstract void print(PrintStream s, ParserWalker pos);
|
public abstract void print(PrintStream s, ParserWalker pos);
|
||||||
|
|
||||||
|
public void collectLocalValues(ArrayList<Long> results) {
|
||||||
|
// By default, assume symbol has no local exports
|
||||||
|
}
|
||||||
|
|
||||||
public Constructor resolve(ParserWalker pos) {
|
public Constructor resolve(ParserWalker pos) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package ghidra.pcodeCPort.slghsymbol;
|
package ghidra.pcodeCPort.slghsymbol;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ import ghidra.pcodeCPort.semantics.ConstTpl;
|
||||||
import ghidra.pcodeCPort.semantics.VarnodeTpl;
|
import ghidra.pcodeCPort.semantics.VarnodeTpl;
|
||||||
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
import ghidra.pcodeCPort.sleighbase.SleighBase;
|
||||||
import ghidra.pcodeCPort.space.AddrSpace;
|
import ghidra.pcodeCPort.space.AddrSpace;
|
||||||
|
import ghidra.pcodeCPort.space.spacetype;
|
||||||
import ghidra.pcodeCPort.utils.XmlUtils;
|
import ghidra.pcodeCPort.utils.XmlUtils;
|
||||||
import ghidra.sleigh.grammar.Location;
|
import ghidra.sleigh.grammar.Location;
|
||||||
|
|
||||||
|
@ -57,6 +59,13 @@ public class VarnodeSymbol extends PatternlessSymbol {
|
||||||
s.append(getName());
|
s.append(getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void collectLocalValues(ArrayList<Long> results) {
|
||||||
|
if (fix.space.getType() == spacetype.IPTR_INTERNAL) {
|
||||||
|
results.add(fix.offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public symbol_type getType() {
|
public symbol_type getType() {
|
||||||
return symbol_type.varnode_symbol;
|
return symbol_type.varnode_symbol;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue