GP-6967 Add getScopeDelimiter

This commit is contained in:
caheckman
2026-06-16 21:41:18 +00:00
parent 4982080ee7
commit e465f9b3d6
19 changed files with 740 additions and 313 deletions
@@ -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