mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-29 08:23:00 +08:00
GP-6967 Add getScopeDelimiter
This commit is contained in:
@@ -457,7 +457,7 @@ RECURSIVE = NO
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE = unify.hh unify.cc rulecompile.hh rulecompile.cc slghparse.cc slghparse.hh slghscan.cc slghpattern.hh slghpattern.cc slghpatexpress.hh slghpatexpress.cc slghsymbol.hh slghsymbol.cc codedata.hh codedata.cc semantics.hh semantics.cc grammar.hh grammar.cc callgraph.hh callgraph.cc filemanage.hh filemanage.cc graph.hh graph.cc loadimage_bfd.hh loadimage_bfd.cc pcodecompile.cc pcodecompile.hh pcodeparse.hh pcodeparse.cc consolemain.cc sleighexample.cc xml.cc double.hh double.cc paramid.hh paramid.cc prefersplit.hh prefersplit.cc
|
||||
EXCLUDE = unify.hh unify.cc rulecompile.hh rulecompile.cc slghparse.cc slghparse.hh slghscan.cc slghpattern.hh slghpattern.cc slghpatexpress.hh slghpatexpress.cc slghsymbol.hh slghsymbol.cc codedata.hh codedata.cc grammar.hh grammar.cc callgraph.hh callgraph.cc filemanage.hh filemanage.cc graph.hh graph.cc loadimage_bfd.hh loadimage_bfd.cc pcodeparse.hh pcodeparse.cc consolemain.cc sleighexample.cc xml.cc double.hh double.cc paramid.hh paramid.cc prefersplit.hh prefersplit.cc
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
|
||||
# directories that are symbolic links (a Unix filesystem feature) are excluded
|
||||
|
||||
@@ -342,8 +342,7 @@ void Architecture::clearAnalysis(Funcdata *fd)
|
||||
|
||||
/// Symbols do not necessarily need to be available for the decompiler.
|
||||
/// This routine loads all the \e load \e image knows about into the symbol table
|
||||
/// \param delim is the delimiter separating namespaces from symbol base names
|
||||
void Architecture::readLoaderSymbols(const string &delim)
|
||||
void Architecture::readLoaderSymbols(void)
|
||||
|
||||
{
|
||||
if (loadersymbols_parsed) return; // already read
|
||||
@@ -352,7 +351,7 @@ void Architecture::readLoaderSymbols(const string &delim)
|
||||
LoadImageFunc record;
|
||||
while(loader->getNextSymbol(record)) {
|
||||
string basename;
|
||||
Scope *scope = symboltab->findCreateScopeFromSymbolName(record.name, delim, basename, (Scope *)0);
|
||||
Scope *scope = symboltab->findCreateScopeFromSymbolName(record.name, basename, (Scope *)0);
|
||||
scope->addFunction(record.address,basename);
|
||||
}
|
||||
loader->closeSymbols();
|
||||
@@ -393,7 +392,7 @@ void Architecture::setPrototype(const PrototypePieces &pieces)
|
||||
|
||||
{
|
||||
string basename;
|
||||
Scope *scope = symboltab->resolveScopeFromSymbolName(pieces.name, "::", basename, (Scope *)0);
|
||||
Scope *scope = symboltab->resolveScopeFromSymbolName(pieces.name, basename, (Scope *)0);
|
||||
if (scope == (Scope *)0)
|
||||
throw ParseError("Unknown namespace: " + pieces.name);
|
||||
Funcdata *fd = scope->queryFunction( basename );
|
||||
|
||||
@@ -230,7 +230,7 @@ public:
|
||||
int4 getMinimumLanedRegisterSize(void) const; ///< Get the minimum size of a laned register in bytes
|
||||
void setDefaultModel(ProtoModel *model); ///< Set the default PrototypeModel
|
||||
void clearAnalysis(Funcdata *fd); ///< Clear analysis specific to a function
|
||||
void readLoaderSymbols(const string &delim); ///< Read any symbols from loader into database
|
||||
void readLoaderSymbols(void); ///< Read any symbols from loader into database
|
||||
void collectBehaviors(vector<OpBehavior *> &behave) const; ///< Provide a list of OpBehavior objects
|
||||
SegmentOp *getSegmentOp(AddrSpace *spc) const; ///< Retrieve the \e segment op for the given space if any
|
||||
void setPrototype(const PrototypePieces &pieces); ///< Set the prototype for a particular function
|
||||
@@ -251,6 +251,7 @@ public:
|
||||
virtual void encode(Encoder &encoder) const; ///< Encode \b this architecture to a stream
|
||||
virtual void restoreXml(DocumentStorage &store); ///< Restore the Architecture state from XML documents
|
||||
virtual void nameFunction(const Address &addr,string &name) const; ///< Pick a default name for a function
|
||||
string getScopeDelimiter(void) const { return print->getScopeDelimiter(); } ///< Get the character string separating scope names
|
||||
#ifdef OPACTION_DEBUG
|
||||
void setDebugStream(ostream *s) { debugstream = s; } ///< Establish the debug console stream
|
||||
void printDebug(const string &message) const { *debugstream << message << endl; } ///< Print message to the debug stream
|
||||
|
||||
@@ -101,7 +101,7 @@ void IfcLoadFile::execute(istream &s)
|
||||
return;
|
||||
}
|
||||
if (capa->getName() == "xml") // If file is xml
|
||||
dcp->conf->readLoaderSymbols("::"); // Read in loader symbols
|
||||
dcp->conf->readLoaderSymbols(); // Read in loader symbols
|
||||
#ifdef OPACTION_DEBUG
|
||||
dcp->conf->setDebugStream(status->fileoptr);
|
||||
#endif
|
||||
|
||||
@@ -2461,6 +2461,7 @@ bool ActionSetCasts::testStructOffset0(Datatype *reqtype,Datatype *curtype,CastS
|
||||
/// \param dt is the data-type needed by the p-code op
|
||||
/// \param op is the p-code op
|
||||
/// \param slot is the index of the slot to test for resolution (-1 for output, >= 0 for input)
|
||||
/// \param data is the function
|
||||
/// \return \b true if the resolution was successfully changed and a CAST is not needed
|
||||
bool ActionSetCasts::tryResolutionAdjustment(Datatype *dt,PcodeOp *op,int4 slot,Funcdata &data)
|
||||
|
||||
|
||||
@@ -1451,7 +1451,7 @@ string Scope::getFullName(void) const
|
||||
string fname = name;
|
||||
Scope *scope = parent;
|
||||
while(scope->parent != (Scope *)0) {
|
||||
fname = scope->name + "::" + fname;
|
||||
fname = scope->name + glb->getScopeDelimiter() + fname;
|
||||
scope = scope->parent;
|
||||
}
|
||||
return fname;
|
||||
@@ -2778,6 +2778,12 @@ void ScopeInternal::decode(Decoder &decoder)
|
||||
SymbolEntry *e = sym->getFirstWholeMap();
|
||||
glb->symboltab->addRange(this,e->getAddr().getSpace(),e->getFirst(),e->getLast());
|
||||
}
|
||||
uint4 props = sym->getFlags() & (Varnode::readonly | Varnode::volatil);
|
||||
if (props != 0) {
|
||||
SymbolEntry *e = sym->getFirstWholeMap();
|
||||
Range rng(e->getAddr().getSpace(),e->getFirst(),e->getLast());
|
||||
glb->symboltab->setPropertyRange(props,rng);
|
||||
}
|
||||
}
|
||||
else if (symId == ELEM_HOLE)
|
||||
decodeHole(decoder);
|
||||
@@ -3106,21 +3112,24 @@ Scope *Database::resolveScope(uint8 id) const
|
||||
/// starts with the delimiter, the name is assumed to be relative to the global Scope.
|
||||
/// The unqualified (base) name of the Symbol is passed back to the caller.
|
||||
/// \param fullname is the qualified Symbol name
|
||||
/// \param delim is the delimiter separating names
|
||||
/// \param basename will hold the passed back base Symbol name
|
||||
/// \param start is the Scope to start drilling down from, or NULL for the global scope
|
||||
/// \return the Scope being referred to by the name
|
||||
Scope *Database::resolveScopeFromSymbolName(const string &fullname,const string &delim,string &basename,
|
||||
Scope *start) const
|
||||
Scope *Database::resolveScopeFromSymbolName(const string &fullname,string &basename,Scope *start) const
|
||||
|
||||
{
|
||||
if (start == (Scope *)0)
|
||||
start = globalscope;
|
||||
|
||||
string::size_type mark = 0;
|
||||
string::size_type endmark;
|
||||
string::size_type templateopen = fullname.find("<");
|
||||
string delim = glb->getScopeDelimiter();
|
||||
for(;;) {
|
||||
endmark = fullname.find(delim,mark);
|
||||
if (endmark == string::npos) break;
|
||||
if (templateopen != string::npos && endmark > templateopen)
|
||||
break;
|
||||
if (endmark == 0) { // Path is "absolute"
|
||||
start = globalscope; // Start from the global scope
|
||||
}
|
||||
@@ -3132,7 +3141,7 @@ Scope *Database::resolveScopeFromSymbolName(const string &fullname,const string
|
||||
}
|
||||
mark = endmark + delim.size();
|
||||
}
|
||||
basename = fullname.substr(mark,endmark);
|
||||
basename = fullname.substr(mark);
|
||||
return start;
|
||||
}
|
||||
|
||||
@@ -3144,21 +3153,24 @@ Scope *Database::resolveScopeFromSymbolName(const string &fullname,const string
|
||||
/// relative to the global Scope. The unqualified (base) name of the Symbol
|
||||
/// is passed back to the caller. Any missing scope in the path is created.
|
||||
/// \param fullname is the qualified Symbol name
|
||||
/// \param delim is the delimiter separating names
|
||||
/// \param basename will hold the passed back base Symbol name
|
||||
/// \param start is the Scope to start drilling down from, or NULL for the global scope
|
||||
/// \return the Scope being referred to by the name
|
||||
Scope *Database::findCreateScopeFromSymbolName(const string &fullname,const string &delim,string &basename,
|
||||
Scope *start)
|
||||
Scope *Database::findCreateScopeFromSymbolName(const string &fullname,string &basename,Scope *start)
|
||||
|
||||
{
|
||||
if (start == (Scope *)0)
|
||||
start = globalscope;
|
||||
|
||||
string::size_type mark = 0;
|
||||
string::size_type endmark;
|
||||
string::size_type templateopen = fullname.find("<");
|
||||
string delim = glb->getScopeDelimiter();
|
||||
for(;;) {
|
||||
endmark = fullname.find(delim,mark);
|
||||
if (endmark == string::npos) break;
|
||||
if (templateopen != string::npos && endmark > templateopen)
|
||||
break;
|
||||
if (!idByNameHash)
|
||||
throw LowlevelError("Scope name hashes not allowed");
|
||||
string scopename = fullname.substr(mark,endmark-mark);
|
||||
@@ -3166,7 +3178,7 @@ Scope *Database::findCreateScopeFromSymbolName(const string &fullname,const stri
|
||||
start = findCreateScope(nameId, scopename, start);
|
||||
mark = endmark + delim.size();
|
||||
}
|
||||
basename = fullname.substr(mark,endmark);
|
||||
basename = fullname.substr(mark);
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
@@ -940,9 +940,9 @@ public:
|
||||
void removeRange(Scope *scope,AddrSpace *spc,uintb first,uintb last); ///< Remove an address range from \e ownership of a Scope
|
||||
Scope *getGlobalScope(void) const { return globalscope; } ///< Get the global Scope
|
||||
Scope *resolveScope(uint8 id) const; ///< Look-up a Scope by id
|
||||
Scope *resolveScopeFromSymbolName(const string &fullname,const string &delim,string &basename,Scope *start) const;
|
||||
Scope *resolveScopeFromSymbolName(const string &fullname,string &basename,Scope *start) const;
|
||||
Scope *findCreateScope(uint8,const string &nm,Scope *parent); /// Find (and if not found create) a specific subscope
|
||||
Scope *findCreateScopeFromSymbolName(const string &fullname,const string &delim,string &basename,Scope *start);
|
||||
Scope *findCreateScopeFromSymbolName(const string &fullname,string &basename,Scope *start);
|
||||
const Scope *mapScope(const Scope *qpoint,const Address &addr,const Address &usepoint) const;
|
||||
Scope *mapScope(Scope *qpoint,const Address &addr,const Address &usepoint);
|
||||
uint4 getProperty(const Address &addr) const { return flagbase.getValue(addr); } ///< Get boolean properties at the given address
|
||||
|
||||
@@ -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.
|
||||
@@ -21,10 +21,8 @@
|
||||
- \ref capabilities
|
||||
- \ref design
|
||||
- \ref workflow
|
||||
- \ref ghidraimpl
|
||||
- \subpage sleigh
|
||||
- \subpage coreclasses
|
||||
- \subpage termrewriting
|
||||
|
||||
\section overview Overview
|
||||
|
||||
|
||||
@@ -459,7 +459,7 @@ void IfaceDecompData::followFlow(ostream &s,int4 size)
|
||||
/// \class IfcFuncload
|
||||
/// \brief Make a specific function current: `load function <functionname>`
|
||||
///
|
||||
/// The name must be a fully qualified symbol with "::" separating namespaces.
|
||||
/// The name must be a fully qualified symbol with namespaces.
|
||||
/// If the symbol represents a function, that function becomes \e current for
|
||||
/// the console. If there are bytes for the function, raw p-code and control-flow
|
||||
/// are calculated.
|
||||
@@ -475,7 +475,7 @@ void IfcFuncload::execute(istream &s)
|
||||
throw IfaceExecutionError("No image loaded");
|
||||
|
||||
string basename;
|
||||
Scope *funcscope = dcp->conf->symboltab->resolveScopeFromSymbolName(funcname,"::",basename,(Scope *)0);
|
||||
Scope *funcscope = dcp->conf->symboltab->resolveScopeFromSymbolName(funcname,basename,(Scope *)0);
|
||||
if (funcscope == (Scope *)0)
|
||||
throw IfaceExecutionError("Bad namespace: "+funcname);
|
||||
dcp->fd = funcscope->queryFunction( basename ); // Is function already in database
|
||||
@@ -534,7 +534,7 @@ void IfcReadSymbols::execute(istream &s)
|
||||
if (dcp->conf->loader == (LoadImage *)0)
|
||||
throw IfaceExecutionError("No binary loaded");
|
||||
|
||||
dcp->conf->readLoaderSymbols("::");
|
||||
dcp->conf->readLoaderSymbols();
|
||||
}
|
||||
|
||||
/// \class IfcMapaddress
|
||||
@@ -544,8 +544,8 @@ void IfcReadSymbols::execute(istream &s)
|
||||
/// \code
|
||||
/// map address r0x1000 int4 globalvar
|
||||
/// \endcode
|
||||
/// The symbol specified in the type declaration can qualify the namespace using the "::"
|
||||
/// specifier. If there is a current function, the variable is local to the function.
|
||||
/// The symbol specified in the type declaration can qualify the namespace.
|
||||
/// If there is a current function, the variable is local to the function.
|
||||
/// Otherwise the symbol is created relative to the global scope.
|
||||
void IfcMapaddress::execute(istream &s)
|
||||
|
||||
@@ -567,7 +567,7 @@ void IfcMapaddress::execute(istream &s)
|
||||
uint4 flags = Varnode::namelock|Varnode::typelock;
|
||||
flags |= dcp->conf->symboltab->getProperty(addr); // Inherit existing properties
|
||||
string basename;
|
||||
Scope *scope = dcp->conf->symboltab->findCreateScopeFromSymbolName(name, "::", basename, (Scope *)0);
|
||||
Scope *scope = dcp->conf->symboltab->findCreateScopeFromSymbolName(name, basename, (Scope *)0);
|
||||
sym = scope->addSymbol(basename,ct,addr,Address())->getSymbol();
|
||||
sym->getScope()->setAttribute(sym,flags);
|
||||
if (scope->getParent() != (Scope *)0) { // If this is a global namespace scope
|
||||
@@ -670,7 +670,7 @@ void IfcMapfunction::execute(istream &s)
|
||||
if (name.empty())
|
||||
dcp->conf->nameFunction(addr,name); // Pick default name if necessary
|
||||
string basename;
|
||||
Scope *scope = dcp->conf->symboltab->findCreateScopeFromSymbolName(name, "::", basename, (Scope *)0);
|
||||
Scope *scope = dcp->conf->symboltab->findCreateScopeFromSymbolName(name, basename, (Scope *)0);
|
||||
dcp->fd = scope->addFunction(addr,name)->getFunction();
|
||||
|
||||
string nocode;
|
||||
@@ -1525,7 +1525,7 @@ void IfaceDecompData::readSymbol(const string &name,vector<Symbol *> &res)
|
||||
{
|
||||
Scope *scope = (fd == (Funcdata *)0) ? conf->symboltab->getGlobalScope() : fd->getScopeLocal();
|
||||
string basename;
|
||||
scope = conf->symboltab->resolveScopeFromSymbolName(name, "::", basename, scope);
|
||||
scope = conf->symboltab->resolveScopeFromSymbolName(name, basename, scope);
|
||||
if (scope == (Scope *)0)
|
||||
throw IfaceParseError("Bad namespace for symbol: " + name);
|
||||
scope->queryByName(basename,res);
|
||||
@@ -2339,7 +2339,7 @@ void IfcPrintMap::execute(istream &s)
|
||||
throw IfaceExecutionError("No load image");
|
||||
if (name.size() != 0 || dcp->fd==(Funcdata *)0) {
|
||||
string fullname = name + "::a"; // Add fake variable name
|
||||
scope = dcp->conf->symboltab->resolveScopeFromSymbolName(fullname, "::", fullname, (Scope *)0);
|
||||
scope = dcp->conf->symboltab->resolveScopeFromSymbolName(fullname, fullname, (Scope *)0);
|
||||
}
|
||||
else
|
||||
scope = dcp->fd->getScopeLocal();
|
||||
@@ -2987,7 +2987,7 @@ void IfcFixupApply::execute(istream &s)
|
||||
throw IfaceExecutionError("Unknown fixup: " + fixupName);
|
||||
|
||||
string basename;
|
||||
Scope *funcscope = dcp->conf->symboltab->resolveScopeFromSymbolName(funcName,"::",basename,(Scope *)0);
|
||||
Scope *funcscope = dcp->conf->symboltab->resolveScopeFromSymbolName(funcName,basename,(Scope *)0);
|
||||
if (funcscope == (Scope *)0)
|
||||
throw IfaceExecutionError("Bad namespace: "+funcName);
|
||||
Funcdata *fd = funcscope->queryFunction( basename ); // Is function already in database
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,18 @@
|
||||
* 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.
|
||||
*/
|
||||
/// \file pcodecompile.hh
|
||||
/// \brief Classes for compiling p-code expressions from SLEIGH or other text specifications
|
||||
|
||||
#ifndef __PCODECOMPILE_HH__
|
||||
#define __PCODECOMPILE_HH__
|
||||
|
||||
@@ -20,69 +23,104 @@
|
||||
|
||||
namespace ghidra {
|
||||
|
||||
/// \brief A location within a specification being parsed
|
||||
class Location {
|
||||
string filename;
|
||||
int4 lineno;
|
||||
string filename; ///< Base name of the file being parsed
|
||||
int4 lineno; ///< Line number within the file
|
||||
public:
|
||||
Location(void) {}
|
||||
Location(const string &fname, const int4 line) { filename = fname; lineno = line; }
|
||||
string getFilename(void) const { return filename; }
|
||||
int4 getLineno(void) const { return lineno; }
|
||||
string format(void) const;
|
||||
Location(void) {} ///< Construct an uninitialized location
|
||||
Location(const string &fname, const int4 line) { filename = fname; lineno = line; } ///< Constructor
|
||||
string getFilename(void) const { return filename; } ///< Get the base file name
|
||||
int4 getLineno(void) const { return lineno; } ///< Get the line number
|
||||
string format(void) const; ///< Return a text representation of \b this
|
||||
};
|
||||
|
||||
/// \brief The address space and pointer size associated with a SLEIGH '*' operator
|
||||
struct StarQuality {
|
||||
ConstTpl id;
|
||||
uint4 size;
|
||||
ConstTpl id; ///< The id of the address space
|
||||
uint4 size; ///< Number of bytes being LOADed or STOREd
|
||||
};
|
||||
|
||||
class ExprTree { // A flattened expression tree
|
||||
/// \brief A p-code expression tree
|
||||
///
|
||||
/// A single connected tree of OpTpl and VarnodeTpl nodes, with either a root VarnodeTpl or a root OpTpl with no output.
|
||||
/// The OpTpl are stored in the flattened order the will be emitted as.
|
||||
class ExprTree {
|
||||
friend class PcodeCompile;
|
||||
vector<OpTpl *> *ops; // flattened ops making up the expression
|
||||
VarnodeTpl *outvn; // Output varnode of the expression
|
||||
// If the last op has an output, -outvn- is
|
||||
// a COPY of that varnode
|
||||
vector<OpTpl *> *ops; ///< Flattened ops making up the expression
|
||||
VarnodeTpl *outvn; ///< Root VarnodeTpl: Copy of the output from the final OpTpl (or NULL)
|
||||
public:
|
||||
ExprTree(void) { ops = (vector<OpTpl *> *)0; outvn = (VarnodeTpl *)0; }
|
||||
ExprTree(VarnodeTpl *vn);
|
||||
ExprTree(OpTpl *op);
|
||||
~ExprTree(void);
|
||||
void setOutput(VarnodeTpl *newout);
|
||||
VarnodeTpl *getOut(void) { return outvn; }
|
||||
const ConstTpl &getSize(void) const { return outvn->getSize(); }
|
||||
ExprTree(void) { ops = (vector<OpTpl *> *)0; outvn = (VarnodeTpl *)0; } ///< Construct an empty expression
|
||||
ExprTree(VarnodeTpl *vn); ///< Construct an expression with a single VarnodeTpl
|
||||
~ExprTree(void); ///< Destructor
|
||||
void setOutput(VarnodeTpl *newout); ///< Force the output of the expression to be a new VarnodeTpl
|
||||
VarnodeTpl *getOut(void) { return outvn; } ///< Get the root VarnodeTpl
|
||||
const ConstTpl &getSize(void) const { return outvn->getSize(); } ///< Get the size of the root VarnodeTpl
|
||||
static vector<OpTpl *> *appendParams(OpTpl *op,vector<ExprTree *> *param);
|
||||
static vector<OpTpl *> *toVector(ExprTree *expr);
|
||||
};
|
||||
|
||||
/// \brief The base class for compiling p-code expressions from SLEIGH syntax
|
||||
///
|
||||
/// This is essentially a utility class for building OpTpl, VarnodeTpl, and their associated expressions.
|
||||
/// Address spaces must be provided via the setXXXSpace() methods, so that the class can model the
|
||||
/// corresponding SLEIGH concepts.
|
||||
class PcodeCompile {
|
||||
AddrSpace *defaultspace;
|
||||
AddrSpace *constantspace;
|
||||
AddrSpace *uniqspace;
|
||||
uint4 local_labelcount; // Number of labels in current constructor
|
||||
bool enforceLocalKey; // Force slaspec to use 'local' keyword when defining temporary varnodes
|
||||
AddrSpace *defaultspace; ///< SLEIGH's \e default address space
|
||||
AddrSpace *constantspace; ///< SLEIGH's \e constant address space
|
||||
AddrSpace *uniqspace; ///< SLEIGH's \e unique address space
|
||||
uint4 local_labelcount; ///< Number of labels in current constructor
|
||||
bool enforceLocalKey; ///< If \b true, force specification to use 'local' keyword when defining temporary varnodes
|
||||
|
||||
/// \brief Get the offset for the next available temporary register
|
||||
///
|
||||
/// A fixed number of bytes in the \e unique space is consumed.
|
||||
/// \return the reserved offset
|
||||
virtual uint4 allocateTemp(void)=0;
|
||||
|
||||
/// \brief Add a new symbol to the current scope
|
||||
///
|
||||
/// \param sym is the symbol being added
|
||||
virtual void addSymbol(SleighSymbol *sym)=0;
|
||||
public:
|
||||
PcodeCompile(void) { defaultspace=(AddrSpace *)0; constantspace=(AddrSpace *)0;
|
||||
uniqspace=(AddrSpace *)0; local_labelcount=0; enforceLocalKey=false; }
|
||||
virtual ~PcodeCompile(void) {}
|
||||
uniqspace=(AddrSpace *)0; local_labelcount=0; enforceLocalKey=false; } ///< Constructor
|
||||
virtual ~PcodeCompile(void) {} ///< Destructor
|
||||
|
||||
/// \brief Get the parse location associated with the given symbol
|
||||
///
|
||||
/// This is generally where the symbol is first defined.
|
||||
/// \param sym is the given symbol
|
||||
/// \return the location if known, or NULL otherwise
|
||||
virtual const Location *getLocation(SleighSymbol *sym) const=0;
|
||||
|
||||
/// \brief Report a fatal error in parsing
|
||||
///
|
||||
/// Parsing may continue, but a final output is not produced.
|
||||
/// \param loc is the location of the error
|
||||
/// \param msg is a description of the error
|
||||
virtual void reportError(const Location *loc, const string &msg)=0;
|
||||
|
||||
/// \brief Report a non-fatal issue encountered during parsing
|
||||
///
|
||||
/// \param loc is the location of the issue
|
||||
/// \param msg is a description of the issue
|
||||
virtual void reportWarning(const Location *loc, const string &msg)=0;
|
||||
void resetLabelCount(void) { local_labelcount=0; }
|
||||
void setDefaultSpace(AddrSpace *spc) { defaultspace = spc; }
|
||||
void setConstantSpace(AddrSpace *spc) { constantspace = spc; }
|
||||
void setUniqueSpace(AddrSpace *spc) { uniqspace = spc; }
|
||||
void setEnforceLocalKey(bool val) { enforceLocalKey = val; }
|
||||
AddrSpace *getDefaultSpace(void) const { return defaultspace; }
|
||||
AddrSpace *getConstantSpace(void) const { return constantspace; }
|
||||
VarnodeTpl *buildTemporary(void);
|
||||
LabelSymbol *defineLabel(string *name);
|
||||
vector<OpTpl *> *placeLabel(LabelSymbol *sym);
|
||||
vector<OpTpl *> *newOutput(bool usesLocalKey,ExprTree *rhs,string *varname,uint4 size=0);
|
||||
void newLocalDefinition(string *varname,uint4 size=0);
|
||||
ExprTree *createOp(OpCode opc,ExprTree *vn);
|
||||
ExprTree *createOp(OpCode opc,ExprTree *vn1,ExprTree *vn2);
|
||||
|
||||
void resetLabelCount(void) { local_labelcount=0; } ///< Reset labels. The next label generated will have id 0
|
||||
void setDefaultSpace(AddrSpace *spc) { defaultspace = spc; } ///< Set the SLEIGH \e default address space
|
||||
void setConstantSpace(AddrSpace *spc) { constantspace = spc; } ///< Set the SLEIGH \e constant address space
|
||||
void setUniqueSpace(AddrSpace *spc) { uniqspace = spc; } ///< Set the SLEIGH \e unique address space
|
||||
void setEnforceLocalKey(bool val) { enforceLocalKey = val; } ///< Toggle whether use of the 'local' key is enforced
|
||||
AddrSpace *getDefaultSpace(void) const { return defaultspace; } ///< Get the \e default address space
|
||||
AddrSpace *getConstantSpace(void) const { return constantspace; } ///< Get the \e constant address space
|
||||
VarnodeTpl *buildTemporary(void); ///< Create a temporary register (with 0 size)
|
||||
LabelSymbol *defineLabel(string *name); ///< Create a SLEIGH label symbol
|
||||
vector<OpTpl *> *placeLabel(LabelSymbol *sym); ///< Create a \e raw expression containing the given label
|
||||
vector<OpTpl *> *newOutput(bool usesLocalKey,ExprTree *rhs,string *varname,uint4 size=0); ///< Create a new output VarnodeTpl for an expression
|
||||
void newLocalDefinition(string *varname,uint4 size=0); ///< Create a new temporary symbol (without generating any p-code)
|
||||
ExprTree *createOp(OpCode opc,ExprTree *vn); ///< Add a new unary operation to the given expression
|
||||
ExprTree *createOp(OpCode opc,ExprTree *vn1,ExprTree *vn2); ///< Create a new binary operation combining the given expressions
|
||||
ExprTree *createOpOut(VarnodeTpl *outvn,OpCode opc,ExprTree *vn1,ExprTree *vn2);
|
||||
ExprTree *createOpOutUnary(VarnodeTpl *outvn,OpCode opc,ExprTree *vn);
|
||||
vector<OpTpl *> *createOpNoOut(OpCode opc,ExprTree *vn);
|
||||
|
||||
@@ -346,6 +346,7 @@ public:
|
||||
virtual void opSpullOp(const PcodeOp *op);
|
||||
virtual void opPopcountOp(const PcodeOp *op) { opFunc(op); }
|
||||
virtual void opLzcountOp(const PcodeOp *op) { opFunc(op); }
|
||||
virtual string getScopeDelimiter(void) const { return scope.print1; }
|
||||
};
|
||||
|
||||
/// \brief Set of print commands for displaying an open brace '{' and setting a new indent level
|
||||
|
||||
@@ -602,6 +602,7 @@ public:
|
||||
virtual void opLzcountOp(const PcodeOp *op)=0; ///< Emit a LZCOUNT operator
|
||||
virtual void opSpullOp(const PcodeOp *op)=0; ///< Emit an SPULL operator
|
||||
virtual string unnamedField(int4 off,int4 size); ///< Generate an artificial field name
|
||||
virtual string getScopeDelimiter(void) const=0; ///< Return the character string used to separate scope names
|
||||
|
||||
static int4 mostNaturalBase(uintb val); ///< Determine the most natural base for an integer
|
||||
static void formatBinary(ostream &s,uintb val); ///< Print a number in binary form
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -301,8 +301,8 @@ public:
|
||||
/// various set*() methods prior to calling run_compilation.
|
||||
class SleighCompile : public SleighBase {
|
||||
friend class SleighPcode;
|
||||
static const int4 UNIQUE_CROSSBUILD_POSITION = 8;
|
||||
static const int4 UNIQUE_CROSSBUILD_NUMBITS = 8;
|
||||
static const int4 UNIQUE_CROSSBUILD_POSITION = 8; ///< The position to insert a cross-build region, within a unique varnode
|
||||
static const int4 UNIQUE_CROSSBUILD_NUMBITS = 8; ///< Number of bits inserted for the cross-build region
|
||||
public:
|
||||
SleighPcode pcode; ///< The p-code parsing (sub)engine
|
||||
private:
|
||||
|
||||
@@ -2137,9 +2137,11 @@ bool SplitDatatype::RootPointer::backUpPointer(Datatype *impliedBase)
|
||||
/// find it, we back up one level (through a PTRSUB, PTRADD, or INT_ADD). If it isn't found after 1 hop,
|
||||
/// \b false is returned. Once this pointer is found, we back up through any single path of nested TYPE_STRUCT
|
||||
/// and TYPE_ARRAY offsets to establish the final root \b pointer, and \b true is returned. Any accumulated offset,
|
||||
/// relative to the original LOAD or STORE pointer is recorded in the \b baseOffset.
|
||||
/// relative to the original LOAD or STORE pointer is recorded in the \b baseOffset. If we encounter
|
||||
/// union data-types during the traversal, we record their resolution for later reproduction.
|
||||
/// \param op is the LOAD or STORE
|
||||
/// \param valueType is the specific data-type to match
|
||||
/// \param resolver records any resolved union fields
|
||||
/// \return \b true if the root pointer is found
|
||||
bool SplitDatatype::RootPointer::find(PcodeOp *op,Datatype *valueType,ResolveCache &resolver)
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ void FunctionTestCollection::buildProgram(DocumentStorage &docStorage)
|
||||
bool iserror = false;
|
||||
try {
|
||||
dcp->conf->init(docStorage);
|
||||
dcp->conf->readLoaderSymbols("::"); // Read in loader symbols
|
||||
dcp->conf->readLoaderSymbols(); // Read in loader symbols
|
||||
} catch(DecoderError &err) {
|
||||
errmsg = err.explain;
|
||||
iserror = true;
|
||||
|
||||
@@ -255,11 +255,11 @@ int4 ScoreUnionFields::scoreReturnType(Datatype *ct,const FuncProto *proto)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Test if the data-type is a pointer and if the pointed-to data-type is
|
||||
/// Test if a parameter trial data-type is a pointer and if the pointed-to data-type is
|
||||
/// compatible with the size of the value being loaded or stored. A \b score is
|
||||
/// passed back for how closely the data-type fits this scenario, and if it
|
||||
/// does we return the data-type of the pointer value.
|
||||
/// \param ct is the trial data-type
|
||||
/// \param trial is the parameter trial whose data-type is tested
|
||||
/// \param vn is the Varnode holding the value being loaded or stored
|
||||
/// \param score is used to pass back the score
|
||||
/// \return the data-type of the value or null
|
||||
|
||||
Reference in New Issue
Block a user