mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
645 lines
28 KiB
C++
645 lines
28 KiB
C++
/* ###
|
|
* 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.
|
|
*/
|
|
#ifndef __SLGHSYMBOL_HH__
|
|
#define __SLGHSYMBOL_HH__
|
|
|
|
#include "semantics.hh"
|
|
#include "slghpatexpress.hh"
|
|
|
|
namespace ghidra {
|
|
|
|
class SleighBase; // Forward declaration
|
|
class SleighSymbol {
|
|
friend class SymbolTable;
|
|
public:
|
|
enum symbol_type { space_symbol, token_symbol, userop_symbol, value_symbol, valuemap_symbol,
|
|
name_symbol, varnode_symbol, varnodelist_symbol, operand_symbol,
|
|
start_symbol, end_symbol, next2_symbol, subtable_symbol, macro_symbol, section_symbol,
|
|
bitrange_symbol, context_symbol, epsilon_symbol, label_symbol,
|
|
dummy_symbol };
|
|
private:
|
|
string name;
|
|
uintm id; // Unique id across all symbols
|
|
uintm scopeid; // Unique id of scope this symbol is in
|
|
public:
|
|
SleighSymbol(void) {} // For use with restoreXml
|
|
SleighSymbol(const string &nm) { name = nm; id = 0; }
|
|
virtual ~SleighSymbol(void) {}
|
|
const string &getName(void) const { return name; }
|
|
uintm getId(void) const { return id; }
|
|
virtual symbol_type getType(void) const { return dummy_symbol; }
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
void restoreXmlHeader(const Element *el);
|
|
virtual void saveXml(ostream &s) const {}
|
|
virtual void restoreXml(const Element *el,SleighBase *trans) {}
|
|
};
|
|
|
|
struct SymbolCompare {
|
|
bool operator()(const SleighSymbol *a,const SleighSymbol *b) const {
|
|
return (a->getName() < b->getName()); }
|
|
};
|
|
|
|
typedef set<SleighSymbol *,SymbolCompare> SymbolTree;
|
|
class SymbolScope {
|
|
friend class SymbolTable;
|
|
SymbolScope *parent;
|
|
SymbolTree tree;
|
|
uintm id;
|
|
public:
|
|
SymbolScope(SymbolScope *p,uintm i) { parent = p; id = i; }
|
|
SymbolScope *getParent(void) const { return parent; }
|
|
SleighSymbol *addSymbol(SleighSymbol *a);
|
|
SleighSymbol *findSymbol(const string &nm) const;
|
|
SymbolTree::const_iterator begin(void) const { return tree.begin(); }
|
|
SymbolTree::const_iterator end(void) const { return tree.end(); }
|
|
uintm getId(void) const { return id; }
|
|
void removeSymbol(SleighSymbol *a) { tree.erase(a); }
|
|
};
|
|
|
|
class SymbolTable {
|
|
vector<SleighSymbol *> symbollist;
|
|
vector<SymbolScope *> table;
|
|
SymbolScope *curscope;
|
|
SymbolScope *skipScope(int4 i) const;
|
|
SleighSymbol *findSymbolInternal(SymbolScope *scope,const string &nm) const;
|
|
void renumber(void);
|
|
public:
|
|
SymbolTable(void) { curscope = (SymbolScope *)0; }
|
|
~SymbolTable(void);
|
|
SymbolScope *getCurrentScope(void) { return curscope; }
|
|
SymbolScope *getGlobalScope(void) { return table[0]; }
|
|
|
|
void setCurrentScope(SymbolScope *scope) { curscope = scope; }
|
|
void addScope(void); // Add new scope off of current scope, make it current
|
|
void popScope(void); // Make parent of current scope current
|
|
void addGlobalSymbol(SleighSymbol *a);
|
|
void addSymbol(SleighSymbol *a);
|
|
SleighSymbol *findSymbol(const string &nm) const { return findSymbolInternal(curscope,nm); }
|
|
SleighSymbol *findSymbol(const string &nm,int4 skip) const { return findSymbolInternal(skipScope(skip),nm); }
|
|
SleighSymbol *findGlobalSymbol(const string &nm) const { return findSymbolInternal(table[0],nm); }
|
|
SleighSymbol *findSymbol(uintm id) const { return symbollist[id]; }
|
|
void replaceSymbol(SleighSymbol *a,SleighSymbol *b);
|
|
void saveXml(ostream &s) const;
|
|
void restoreXml(const Element *el,SleighBase *trans);
|
|
void restoreSymbolHeader(const Element *el);
|
|
void purge(void);
|
|
};
|
|
|
|
class SpaceSymbol : public SleighSymbol {
|
|
AddrSpace *space;
|
|
public:
|
|
SpaceSymbol(AddrSpace *spc) : SleighSymbol(spc->getName()) { space = spc; }
|
|
AddrSpace *getSpace(void) const { return space; }
|
|
virtual symbol_type getType(void) const { return space_symbol; }
|
|
};
|
|
|
|
class TokenSymbol : public SleighSymbol {
|
|
Token *tok;
|
|
public:
|
|
TokenSymbol(Token *t) : SleighSymbol(t->getName()) { tok = t; }
|
|
~TokenSymbol(void) { delete tok; }
|
|
Token *getToken(void) const { return tok; }
|
|
virtual symbol_type getType(void) const { return token_symbol; }
|
|
};
|
|
|
|
class SectionSymbol : public SleighSymbol { // Named p-code sections
|
|
int4 templateid; // Index into the ConstructTpl array
|
|
int4 define_count; // Number of definitions of this named section
|
|
int4 ref_count; // Number of references to this named section
|
|
public:
|
|
SectionSymbol(const string &nm,int4 id) : SleighSymbol(nm) { templateid=id; define_count=0; ref_count=0; }
|
|
int4 getTemplateId(void) const { return templateid; }
|
|
void incrementDefineCount(void) { define_count += 1; }
|
|
void incrementRefCount(void) { ref_count += 1; }
|
|
int4 getDefineCount(void) const { return define_count; }
|
|
int4 getRefCount(void) const { return ref_count; }
|
|
virtual symbol_type getType(void) const { return section_symbol; }
|
|
// Not saved or restored
|
|
};
|
|
|
|
class UserOpSymbol : public SleighSymbol { // A user-defined pcode-op
|
|
uint4 index;
|
|
public:
|
|
UserOpSymbol(void) {} // For use with restoreXml
|
|
UserOpSymbol(const string &nm) : SleighSymbol(nm) { index = 0; }
|
|
void setIndex(uint4 ind) { index = ind; }
|
|
uint4 getIndex(void) const { return index; }
|
|
virtual symbol_type getType(void) const { return userop_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class Constructor; // Forward declaration
|
|
// This is the central sleigh object
|
|
class TripleSymbol : public SleighSymbol {
|
|
public:
|
|
TripleSymbol(void) {}
|
|
TripleSymbol(const string &nm) : SleighSymbol(nm) {}
|
|
virtual Constructor *resolve(ParserWalker &walker) { return (Constructor *)0; }
|
|
virtual PatternExpression *getPatternExpression(void) const=0;
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
|
|
virtual int4 getSize(void) const { return 0; } // Size out of context
|
|
virtual void print(ostream &s,ParserWalker &walker) const=0;
|
|
virtual void collectLocalValues(vector<uintb> &results) const {}
|
|
};
|
|
|
|
class FamilySymbol : public TripleSymbol {
|
|
public:
|
|
FamilySymbol(void) {}
|
|
FamilySymbol(const string &nm) : TripleSymbol(nm) {}
|
|
virtual PatternValue *getPatternValue(void) const=0;
|
|
};
|
|
|
|
class SpecificSymbol : public TripleSymbol {
|
|
public:
|
|
SpecificSymbol(void) {}
|
|
SpecificSymbol(const string &nm) : TripleSymbol(nm) {}
|
|
virtual VarnodeTpl *getVarnode(void) const=0;
|
|
};
|
|
|
|
class PatternlessSymbol : public SpecificSymbol { // Behaves like constant 0 pattern
|
|
ConstantValue *patexp;
|
|
public:
|
|
PatternlessSymbol(void); // For use with restoreXml
|
|
PatternlessSymbol(const string &nm);
|
|
virtual ~PatternlessSymbol(void);
|
|
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
|
|
virtual void saveXml(ostream &s) const {}
|
|
virtual void restoreXml(const Element *el,SleighBase *trans) {}
|
|
};
|
|
|
|
class EpsilonSymbol : public PatternlessSymbol { // Another name for zero pattern/value
|
|
AddrSpace *const_space;
|
|
public:
|
|
EpsilonSymbol(void) {} // For use with restoreXml
|
|
EpsilonSymbol(const string &nm,AddrSpace *spc) : PatternlessSymbol(nm) { const_space=spc; }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return epsilon_symbol; }
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class ValueSymbol : public FamilySymbol {
|
|
protected:
|
|
PatternValue *patval;
|
|
public:
|
|
ValueSymbol(void) { patval = (PatternValue *)0; } // For use with restoreXml
|
|
ValueSymbol(const string &nm,PatternValue *pv);
|
|
virtual ~ValueSymbol(void);
|
|
virtual PatternValue *getPatternValue(void) const { return patval; }
|
|
virtual PatternExpression *getPatternExpression(void) const { return patval; }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return value_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class ValueMapSymbol : public ValueSymbol {
|
|
vector<intb> valuetable;
|
|
bool tableisfilled;
|
|
void checkTableFill(void);
|
|
public:
|
|
ValueMapSymbol(void) {} // For use with restoreXml
|
|
ValueMapSymbol(const string &nm,PatternValue *pv,const vector<intb> &vt) : ValueSymbol(nm,pv) { valuetable=vt; checkTableFill(); }
|
|
virtual Constructor *resolve(ParserWalker &walker);
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return valuemap_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class NameSymbol : public ValueSymbol {
|
|
vector<string> nametable;
|
|
bool tableisfilled;
|
|
void checkTableFill(void);
|
|
public:
|
|
NameSymbol(void) {} // For use with restoreXml
|
|
NameSymbol(const string &nm,PatternValue *pv,const vector<string> &nt) : ValueSymbol(nm,pv) { nametable=nt; checkTableFill(); }
|
|
virtual Constructor *resolve(ParserWalker &walker);
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return name_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class VarnodeSymbol : public PatternlessSymbol { // A global varnode
|
|
VarnodeData fix;
|
|
bool context_bits;
|
|
public:
|
|
VarnodeSymbol(void) {} // For use with restoreXml
|
|
VarnodeSymbol(const string &nm,AddrSpace *base,uintb offset,int4 size);
|
|
void markAsContext(void) { context_bits = true; }
|
|
const VarnodeData &getFixedVarnode(void) const { return fix; }
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual int4 getSize(void) const { return fix.size; }
|
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
|
s << getName(); }
|
|
virtual void collectLocalValues(vector<uintb> &results) const;
|
|
virtual symbol_type getType(void) const { return varnode_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class BitrangeSymbol : public SleighSymbol { // A smaller bitrange within a varnode
|
|
VarnodeSymbol *varsym; // Varnode containing the bitrange
|
|
uint4 bitoffset; // least significant bit of range
|
|
uint4 numbits; // number of bits in the range
|
|
public:
|
|
BitrangeSymbol(void) {} // For use with restoreXml
|
|
BitrangeSymbol(const string &nm,VarnodeSymbol *sym,uint4 bitoff,uint4 num)
|
|
: SleighSymbol(nm) { varsym=sym; bitoffset=bitoff; numbits=num; }
|
|
VarnodeSymbol *getParentSymbol(void) const { return varsym; }
|
|
uint4 getBitOffset(void) const { return bitoffset; }
|
|
uint4 numBits(void) const { return numbits; }
|
|
virtual symbol_type getType(void) const { return bitrange_symbol; }
|
|
};
|
|
|
|
class ContextSymbol : public ValueSymbol {
|
|
VarnodeSymbol *vn;
|
|
uint4 low,high; // into a varnode
|
|
bool flow;
|
|
public:
|
|
ContextSymbol(void) {} // For use with restoreXml
|
|
ContextSymbol(const string &nm,ContextField *pate,VarnodeSymbol *v,uint4 l,uint4 h,bool flow);
|
|
VarnodeSymbol *getVarnode(void) const { return vn; }
|
|
uint4 getLow(void) const { return low; }
|
|
uint4 getHigh(void) const { return high; }
|
|
bool getFlow(void) const { return flow; }
|
|
virtual symbol_type getType(void) const { return context_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class VarnodeListSymbol : public ValueSymbol {
|
|
vector<VarnodeSymbol *> varnode_table;
|
|
bool tableisfilled;
|
|
void checkTableFill(void);
|
|
public:
|
|
VarnodeListSymbol(void) {} // For use with restoreXml
|
|
VarnodeListSymbol(const string &nm,PatternValue *pv,const vector<SleighSymbol *> &vt);
|
|
virtual Constructor *resolve(ParserWalker &walker);
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual int4 getSize(void) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return varnodelist_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class OperandSymbol : public SpecificSymbol {
|
|
friend class Constructor;
|
|
friend class OperandEquation;
|
|
public:
|
|
enum { code_address=1, offset_irrel=2, variable_len=4, marked=8 };
|
|
private:
|
|
uint4 reloffset; // Relative offset
|
|
int4 offsetbase; // Base operand to which offset is relative (-1=constructor start)
|
|
int4 minimumlength; // Minimum size of operand (within instruction tokens)
|
|
int4 hand; // Handle index
|
|
OperandValue *localexp;
|
|
TripleSymbol *triple; // Defining symbol
|
|
PatternExpression *defexp; // OR defining expression
|
|
uint4 flags;
|
|
void setVariableLength(void) { flags |= variable_len; }
|
|
bool isVariableLength(void) const { return ((flags&variable_len)!=0); }
|
|
public:
|
|
OperandSymbol(void) {} // For use with restoreXml
|
|
OperandSymbol(const string &nm,int4 index,Constructor *ct);
|
|
uint4 getRelativeOffset(void) const { return reloffset; }
|
|
int4 getOffsetBase(void) const { return offsetbase; }
|
|
int4 getMinimumLength(void) const { return minimumlength; }
|
|
PatternExpression *getDefiningExpression(void) const { return defexp; }
|
|
TripleSymbol *getDefiningSymbol(void) const { return triple; }
|
|
int4 getIndex(void) const { return hand; }
|
|
void defineOperand(PatternExpression *pe);
|
|
void defineOperand(TripleSymbol *tri);
|
|
void setCodeAddress(void) { flags |= code_address; }
|
|
bool isCodeAddress(void) const { return ((flags&code_address)!=0); }
|
|
void setOffsetIrrelevant(void) { flags |= offset_irrel; }
|
|
bool isOffsetIrrelevant(void) const { return ((flags&offset_irrel)!=0); }
|
|
void setMark(void) { flags |= marked; }
|
|
void clearMark(void) { flags &= ~((uint4)marked); }
|
|
bool isMarked(void) const { return ((flags&marked)!=0); }
|
|
virtual ~OperandSymbol(void);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { return localexp; }
|
|
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
|
|
virtual int4 getSize(void) 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 void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class StartSymbol : public SpecificSymbol {
|
|
AddrSpace *const_space;
|
|
PatternExpression *patexp;
|
|
public:
|
|
StartSymbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
|
|
StartSymbol(const string &nm,AddrSpace *cspc);
|
|
virtual ~StartSymbol(void);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return start_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class EndSymbol : public SpecificSymbol {
|
|
AddrSpace *const_space;
|
|
PatternExpression *patexp;
|
|
public:
|
|
EndSymbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
|
|
EndSymbol(const string &nm,AddrSpace *cspc);
|
|
virtual ~EndSymbol(void);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return end_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class Next2Symbol : public SpecificSymbol {
|
|
AddrSpace *const_space;
|
|
PatternExpression *patexp;
|
|
public:
|
|
Next2Symbol(void) { patexp = (PatternExpression *)0; } // For use with restoreXml
|
|
Next2Symbol(const string &nm,AddrSpace *cspc);
|
|
virtual ~Next2Symbol(void);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { return patexp; }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return next2_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class FlowDestSymbol : public SpecificSymbol {
|
|
AddrSpace *const_space;
|
|
public:
|
|
FlowDestSymbol(void) {} // For use with restoreXml
|
|
FlowDestSymbol(const string &nm,AddrSpace *cspc);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { throw SleighError("Cannot use symbol in pattern"); }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return start_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class FlowRefSymbol : public SpecificSymbol {
|
|
AddrSpace *const_space;
|
|
public:
|
|
FlowRefSymbol(void) {} // For use with restoreXml
|
|
FlowRefSymbol(const string &nm,AddrSpace *cspc);
|
|
virtual VarnodeTpl *getVarnode(void) const;
|
|
virtual PatternExpression *getPatternExpression(void) const { throw SleighError("Cannot use symbol in pattern"); }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const;
|
|
virtual void print(ostream &s,ParserWalker &walker) const;
|
|
virtual symbol_type getType(void) const { return start_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class ContextChange { // Change to context command
|
|
public:
|
|
virtual ~ContextChange(void) {}
|
|
virtual void validate(void) const=0;
|
|
virtual void saveXml(ostream &s) const=0;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans)=0;
|
|
virtual void apply(ParserWalkerChange &walker) const=0;
|
|
virtual ContextChange *clone(void) const=0;
|
|
};
|
|
|
|
class ContextOp : public ContextChange {
|
|
PatternExpression *patexp; // Expression determining value
|
|
int4 num; // index of word containing context variable to set
|
|
uintm mask; // Mask off size of variable
|
|
int4 shift; // Number of bits to shift value into place
|
|
public:
|
|
ContextOp(int4 startbit,int4 endbit,PatternExpression *pe);
|
|
ContextOp(void) {} // For use with restoreXml
|
|
virtual ~ContextOp(void) { PatternExpression::release(patexp); }
|
|
virtual void validate(void) const;
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
virtual void apply(ParserWalkerChange &walker) const;
|
|
virtual ContextChange *clone(void) const;
|
|
};
|
|
|
|
class ContextCommit : public ContextChange {
|
|
TripleSymbol *sym;
|
|
int4 num; // Index of word containing context commit
|
|
uintm mask; // mask of bits in word being committed
|
|
bool flow; // Whether the context "flows" from the point of change
|
|
public:
|
|
ContextCommit(void) {} // For use with restoreXml
|
|
ContextCommit(TripleSymbol *s,int4 sbit,int4 ebit,bool fl);
|
|
virtual void validate(void) const {}
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
virtual void apply(ParserWalkerChange &walker) const;
|
|
virtual ContextChange *clone(void) const;
|
|
};
|
|
|
|
class SubtableSymbol;
|
|
class Constructor { // This is NOT a symbol
|
|
TokenPattern *pattern;
|
|
SubtableSymbol *parent;
|
|
PatternEquation *pateq;
|
|
vector<OperandSymbol *> operands;
|
|
vector<string> printpiece;
|
|
vector<ContextChange *> context; // Context commands
|
|
ConstructTpl *templ; // The main p-code section
|
|
vector<ConstructTpl *> namedtempl; // Other named p-code sections
|
|
int4 minimumlength; // Minimum length taken up by this constructor in bytes
|
|
uintm id; // Unique id of constructor within subtable
|
|
int4 firstwhitespace; // Index of first whitespace piece in -printpiece-
|
|
int4 flowthruindex; // if >=0 then print only a single operand no markup
|
|
int4 lineno;
|
|
int4 src_index; //source file index
|
|
mutable bool inerror; // An error is associated with this Constructor
|
|
void orderOperands(void);
|
|
public:
|
|
Constructor(void); // For use with restoreXml
|
|
Constructor(SubtableSymbol *p);
|
|
~Constructor(void);
|
|
TokenPattern *buildPattern(ostream &s);
|
|
TokenPattern *getPattern(void) const { return pattern; }
|
|
void setMinimumLength(int4 l) { minimumlength = l; }
|
|
int4 getMinimumLength(void) const { return minimumlength; }
|
|
void setId(uintm i) { id = i; }
|
|
uintm getId(void) const { return id; }
|
|
void setLineno(int4 ln) { lineno = ln; }
|
|
int4 getLineno(void) const { return lineno; }
|
|
void setSrcIndex(int4 index) {src_index = index;}
|
|
int4 getSrcIndex(void) {return src_index;}
|
|
void addContext(const vector<ContextChange *> &vec) { context = vec; }
|
|
void addOperand(OperandSymbol *sym);
|
|
void addInvisibleOperand(OperandSymbol *sym);
|
|
void addSyntax(const string &syn);
|
|
void addEquation(PatternEquation *pe);
|
|
void setMainSection(ConstructTpl *tpl) { templ = tpl; }
|
|
void setNamedSection(ConstructTpl *tpl,int4 id);
|
|
SubtableSymbol *getParent(void) const { return parent; }
|
|
int4 getNumOperands(void) const { return operands.size(); }
|
|
OperandSymbol *getOperand(int4 i) const { return operands[i]; }
|
|
PatternEquation *getPatternEquation(void) const { return pateq; }
|
|
ConstructTpl *getTempl(void) const { return templ; }
|
|
ConstructTpl *getNamedTempl(int4 secnum) const;
|
|
int4 getNumSections(void) const { return namedtempl.size(); }
|
|
void printInfo(ostream &s) const;
|
|
void print(ostream &s,ParserWalker &pos) const;
|
|
void printMnemonic(ostream &s,ParserWalker &walker) const;
|
|
void printBody(ostream &s,ParserWalker &walker) const;
|
|
void removeTrailingSpace(void);
|
|
void applyContext(ParserWalkerChange &walker) const {
|
|
vector<ContextChange *>::const_iterator iter;
|
|
for(iter=context.begin();iter!=context.end();++iter)
|
|
(*iter)->apply(walker);
|
|
}
|
|
void markSubtableOperands(vector<int4> &check) const;
|
|
void collectLocalExports(vector<uintb> &results) const;
|
|
void setError(bool val) const { inerror = val; }
|
|
bool isError(void) const { return inerror; }
|
|
bool isRecursive(void) const;
|
|
void saveXml(ostream &s) const;
|
|
void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class DecisionProperties {
|
|
vector<pair<Constructor *, Constructor *> > identerrors;
|
|
vector<pair<Constructor *, Constructor *> > conflicterrors;
|
|
public:
|
|
void identicalPattern(Constructor *a,Constructor *b);
|
|
void conflictingPattern(Constructor *a,Constructor *b);
|
|
const vector<pair<Constructor *, Constructor *> > &getIdentErrors(void) const { return identerrors; }
|
|
const vector<pair<Constructor *, Constructor *> > &getConflictErrors(void) const { return conflicterrors; }
|
|
};
|
|
|
|
class DecisionNode {
|
|
vector<pair<DisjointPattern *,Constructor *> > list;
|
|
vector<DecisionNode *> children;
|
|
int4 num; // Total number of patterns we distinguish
|
|
bool contextdecision; // True if this is decision based on context
|
|
int4 startbit,bitsize; // Bits in the stream on which to base the decision
|
|
DecisionNode *parent;
|
|
void chooseOptimalField(void);
|
|
double getScore(int4 low,int4 size,bool context);
|
|
int4 getNumFixed(int4 low,int4 size,bool context);
|
|
int4 getMaximumLength(bool context);
|
|
void consistentValues(vector<uint4> &bins,DisjointPattern *pat);
|
|
public:
|
|
DecisionNode(void) {} // For use with restoreXml
|
|
DecisionNode(DecisionNode *p);
|
|
~DecisionNode(void);
|
|
Constructor *resolve(ParserWalker &walker) const;
|
|
void addConstructorPair(const DisjointPattern *pat,Constructor *ct);
|
|
void split(DecisionProperties &props);
|
|
void orderPatterns(DecisionProperties &props);
|
|
void saveXml(ostream &s) const;
|
|
void restoreXml(const Element *el,DecisionNode *par,SubtableSymbol *sub);
|
|
};
|
|
|
|
class SubtableSymbol : public TripleSymbol {
|
|
TokenPattern *pattern;
|
|
bool beingbuilt,errors;
|
|
vector<Constructor *> construct; // All the Constructors in this table
|
|
DecisionNode *decisiontree;
|
|
public:
|
|
SubtableSymbol(void) { pattern = (TokenPattern *)0; decisiontree = (DecisionNode *)0; } // For use with restoreXml
|
|
SubtableSymbol(const string &nm);
|
|
virtual ~SubtableSymbol(void);
|
|
bool isBeingBuilt(void) const { return beingbuilt; }
|
|
bool isError(void) const { return errors; }
|
|
void addConstructor(Constructor *ct) { ct->setId(construct.size()); construct.push_back(ct); }
|
|
void buildDecisionTree(DecisionProperties &props);
|
|
TokenPattern *buildPattern(ostream &s);
|
|
TokenPattern *getPattern(void) const { return pattern; }
|
|
int4 getNumConstructors(void) const { return construct.size(); }
|
|
Constructor *getConstructor(uintm id) const { return construct[id]; }
|
|
virtual Constructor *resolve(ParserWalker &walker) { return decisiontree->resolve(walker); }
|
|
virtual PatternExpression *getPatternExpression(void) const { throw SleighError("Cannot use subtable in expression"); }
|
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const {
|
|
throw SleighError("Cannot use subtable in expression"); }
|
|
virtual int4 getSize(void) const { return -1; }
|
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
|
throw SleighError("Cannot use subtable in expression"); }
|
|
virtual void collectLocalValues(vector<uintb> &results) const;
|
|
virtual symbol_type getType(void) const { return subtable_symbol; }
|
|
virtual void saveXml(ostream &s) const;
|
|
virtual void saveXmlHeader(ostream &s) const;
|
|
virtual void restoreXml(const Element *el,SleighBase *trans);
|
|
};
|
|
|
|
class MacroSymbol : public SleighSymbol { // A user-defined pcode-macro
|
|
int4 index;
|
|
ConstructTpl *construct;
|
|
vector<OperandSymbol *> operands;
|
|
public:
|
|
MacroSymbol(const string &nm,int4 i) : SleighSymbol(nm) { index = i; construct = (ConstructTpl *)0; }
|
|
int4 getIndex(void) const { return index; }
|
|
void setConstruct(ConstructTpl *ct) { construct = ct; }
|
|
ConstructTpl *getConstruct(void) const { return construct; }
|
|
void addOperand(OperandSymbol *sym) { operands.push_back(sym); }
|
|
int4 getNumOperands(void) const { return operands.size(); }
|
|
OperandSymbol *getOperand(int4 i) const { return operands[i]; }
|
|
virtual ~MacroSymbol(void) { if (construct != (ConstructTpl *)0) delete construct; }
|
|
virtual symbol_type getType(void) const { return macro_symbol; }
|
|
};
|
|
|
|
class LabelSymbol : public SleighSymbol { // A branch label
|
|
uint4 index; // Local 1 up index of label
|
|
bool isplaced; // Has the label been placed (not just referenced)
|
|
uint4 refcount; // Number of references to this label
|
|
public:
|
|
LabelSymbol(const string &nm,uint4 i) : SleighSymbol(nm) { index = i; refcount = 0; isplaced=false; }
|
|
uint4 getIndex(void) const { return index; }
|
|
void incrementRefCount(void) { refcount += 1; }
|
|
uint4 getRefCount(void) const { return refcount; }
|
|
void setPlaced(void) { isplaced = true; }
|
|
bool isPlaced(void) const { return isplaced; }
|
|
virtual symbol_type getType(void) const { return label_symbol; }
|
|
};
|
|
|
|
} // End namespace ghidra
|
|
#endif
|