mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
isNameUsed added to DecompileCallback
This commit is contained in:
parent
44ed318672
commit
05c3358fe4
9 changed files with 198 additions and 50 deletions
|
@ -1420,23 +1420,6 @@ void Scope::getScopePath(vector<const Scope *> &vec) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test for the presence of a symbol with the given name in either \b this scope or
|
|
||||||
/// an ancestor scope up to but not including the given terminating scope.
|
|
||||||
/// If the name is used \b true is returned.
|
|
||||||
/// \param nm is the given name to test
|
|
||||||
/// \param op2 is the terminating ancestor scope (or null)
|
|
||||||
bool Scope::isNameUsed(const string &nm,const Scope *op2) const
|
|
||||||
|
|
||||||
{
|
|
||||||
const Scope *currentScope = this;
|
|
||||||
while(currentScope != op2) {
|
|
||||||
if (currentScope->isNameUsed(nm))
|
|
||||||
return true;
|
|
||||||
currentScope = currentScope->parent;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Any two scopes share at least the \e global scope as a common ancestor. We find the first scope
|
/// Any two scopes share at least the \e global scope as a common ancestor. We find the first scope
|
||||||
/// that is \e not in common. The scope returned will always be an ancestor of \b this.
|
/// that is \e not in common. The scope returned will always be an ancestor of \b this.
|
||||||
/// If \b this is an ancestor of the other given scope, then null is returned.
|
/// If \b this is an ancestor of the other given scope, then null is returned.
|
||||||
|
@ -2305,13 +2288,21 @@ void ScopeInternal::findByName(const string &name,vector<Symbol *> &res) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScopeInternal::isNameUsed(const string &name) const
|
bool ScopeInternal::isNameUsed(const string &nm,const Scope *op2) const
|
||||||
|
|
||||||
{
|
{
|
||||||
Symbol sym((Scope *)0,name,(Datatype *)0);
|
Symbol sym((Scope *)0,name,(Datatype *)0);
|
||||||
SymbolNameTree::const_iterator iter = nametree.lower_bound(&sym);
|
SymbolNameTree::const_iterator iter = nametree.lower_bound(&sym);
|
||||||
if (iter == nametree.end()) return false;
|
if (iter != nametree.end()) {
|
||||||
return ((*iter)->getName() == name);
|
if ((*iter)->getName() == name)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Scope *par = getParent();
|
||||||
|
if (par == (Scope *)0 || par == op2)
|
||||||
|
return false;
|
||||||
|
if (par->getParent() == (Scope *)0) // Never recurse into global scope
|
||||||
|
return false;
|
||||||
|
return par->isNameUsed(nm, op2);
|
||||||
}
|
}
|
||||||
|
|
||||||
string ScopeInternal::buildVariableName(const Address &addr,
|
string ScopeInternal::buildVariableName(const Address &addr,
|
||||||
|
|
|
@ -603,13 +603,14 @@ public:
|
||||||
/// \param res will contain any matching Symbols
|
/// \param res will contain any matching Symbols
|
||||||
virtual void findByName(const string &name,vector<Symbol *> &res) const=0;
|
virtual void findByName(const string &name,vector<Symbol *> &res) const=0;
|
||||||
|
|
||||||
/// \brief Check if the given name is used within \b this scope.
|
/// \brief Check if the given name is occurs within the given scope path.
|
||||||
///
|
///
|
||||||
/// Only \b this scope is checked. If one or more symbols exist with the given name,
|
/// Test for the presence of a symbol with the given name in either \b this scope or
|
||||||
/// \b true is returned.
|
/// an ancestor scope up to but not including the given terminating scope.
|
||||||
/// \param name is the given name to check for
|
/// If the name is used \b true is returned.
|
||||||
/// \return \b true if the name is used within \b this scope
|
/// \param nm is the given name to test
|
||||||
virtual bool isNameUsed(const string &name) const=0;
|
/// \param op2 is the terminating ancestor scope (or null)
|
||||||
|
virtual bool isNameUsed(const string &nm,const Scope *op2) const=0;
|
||||||
|
|
||||||
/// \brief Convert an \e external \e reference to the referenced function
|
/// \brief Convert an \e external \e reference to the referenced function
|
||||||
///
|
///
|
||||||
|
@ -694,7 +695,6 @@ public:
|
||||||
string getFullName(void) const; ///< Get the full name of \b this Scope
|
string getFullName(void) const; ///< Get the full name of \b this Scope
|
||||||
void getNameSegments(vector<string> &vec) const; ///< Get the fullname of \b this in segments
|
void getNameSegments(vector<string> &vec) const; ///< Get the fullname of \b this in segments
|
||||||
void getScopePath(vector<const Scope *> &vec) const; ///< Get the ordered list of scopes up to \b this
|
void getScopePath(vector<const Scope *> &vec) const; ///< Get the ordered list of scopes up to \b this
|
||||||
bool isNameUsed(const string &nm,const Scope *op2) const; ///< Is the given name in use within given scope path
|
|
||||||
const Scope *findDistinguishingScope(const Scope *op2) const; ///< Find first ancestor of \b this not shared by given scope
|
const Scope *findDistinguishingScope(const Scope *op2) const; ///< Find first ancestor of \b this not shared by given scope
|
||||||
Architecture *getArch(void) const { return glb; } ///< Get the Architecture associated with \b this
|
Architecture *getArch(void) const { return glb; } ///< Get the Architecture associated with \b this
|
||||||
Scope *getParent(void) const { return parent; } ///< Get the parent Scope (or NULL if \b this is the global Scope)
|
Scope *getParent(void) const { return parent; } ///< Get the parent Scope (or NULL if \b this is the global Scope)
|
||||||
|
@ -766,7 +766,7 @@ public:
|
||||||
virtual SymbolEntry *findOverlap(const Address &addr,int4 size) const;
|
virtual SymbolEntry *findOverlap(const Address &addr,int4 size) const;
|
||||||
|
|
||||||
virtual void findByName(const string &name,vector<Symbol *> &res) const;
|
virtual void findByName(const string &name,vector<Symbol *> &res) const;
|
||||||
virtual bool isNameUsed(const string &name) const;
|
virtual bool isNameUsed(const string &nm,const Scope *op2) const;
|
||||||
virtual Funcdata *resolveExternalRefFunction(ExternRefSymbol *sym) const;
|
virtual Funcdata *resolveExternalRefFunction(ExternRefSymbol *sym) const;
|
||||||
|
|
||||||
virtual string buildVariableName(const Address &addr,
|
virtual string buildVariableName(const Address &addr,
|
||||||
|
|
|
@ -421,3 +421,13 @@ SymbolEntry *ScopeGhidraNamespace::addMapInternal(Symbol *sym,uint4 exfl,const A
|
||||||
glb->symboltab->addRange(this,res->getAddr().getSpace(),res->getFirst(),res->getLast());
|
glb->symboltab->addRange(this,res->getAddr().getSpace(),res->getFirst(),res->getLast());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScopeGhidraNamespace::isNameUsed(const string &nm,const Scope *op2) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (ArchitectureGhidra::isDynamicSymbolName(nm))
|
||||||
|
return false; // Just assume default FUN_ and DAT_ names don't collide
|
||||||
|
const ScopeGhidraNamespace *otherScope = dynamic_cast<const ScopeGhidraNamespace *>(op2);
|
||||||
|
uint8 otherId = (otherScope != (const ScopeGhidraNamespace *)0) ? otherScope->getId() : 0;
|
||||||
|
return ghidra->isNameUsed(nm, scopeId, otherId);
|
||||||
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
|
|
||||||
virtual SymbolEntry *findOverlap(const Address &addr,int4 size) const { throw LowlevelError("findOverlap unimplemented"); }
|
virtual SymbolEntry *findOverlap(const Address &addr,int4 size) const { throw LowlevelError("findOverlap unimplemented"); }
|
||||||
virtual void findByName(const string &name,vector<Symbol *> &res) const { throw LowlevelError("findByName unimplemented"); }
|
virtual void findByName(const string &name,vector<Symbol *> &res) const { throw LowlevelError("findByName unimplemented"); }
|
||||||
virtual bool isNameUsed(const string &name) const { throw LowlevelError("isNameUsed unimplemented"); }
|
virtual bool isNameUsed(const string &nm,const Scope *op2) const { throw LowlevelError("isNameUsed unimplemented"); }
|
||||||
|
|
||||||
virtual MapIterator begin(void) const { throw LowlevelError("begin unimplemented"); }
|
virtual MapIterator begin(void) const { throw LowlevelError("begin unimplemented"); }
|
||||||
virtual MapIterator end(void) const { throw LowlevelError("end unimplemented"); }
|
virtual MapIterator end(void) const { throw LowlevelError("end unimplemented"); }
|
||||||
|
@ -125,14 +125,16 @@ public:
|
||||||
/// be a ScopeGhidra. This will query the Ghidra client on behalf of the \e namespace and
|
/// be a ScopeGhidra. This will query the Ghidra client on behalf of the \e namespace and
|
||||||
/// register any new symbols with \b this Scope.
|
/// register any new symbols with \b this Scope.
|
||||||
class ScopeGhidraNamespace : public ScopeInternal {
|
class ScopeGhidraNamespace : public ScopeInternal {
|
||||||
|
ArchitectureGhidra *ghidra; ///< Connection to the Ghidra client
|
||||||
uint8 scopeId; ///< Internal id allowing Ghidra client to reference formal namespaces
|
uint8 scopeId; ///< Internal id allowing Ghidra client to reference formal namespaces
|
||||||
virtual SymbolEntry *addMapInternal(Symbol *sym,uint4 exfl,const Address &addr,int4 off,int4 sz,
|
virtual SymbolEntry *addMapInternal(Symbol *sym,uint4 exfl,const Address &addr,int4 off,int4 sz,
|
||||||
const RangeList &uselim);
|
const RangeList &uselim);
|
||||||
public:
|
public:
|
||||||
ScopeGhidraNamespace(const string &nm,uint8 id,Architecture *g)
|
ScopeGhidraNamespace(const string &nm,uint8 id,ArchitectureGhidra *g)
|
||||||
: ScopeInternal(nm,g) { scopeId = id; } ///< Constructor
|
: ScopeInternal(nm,g) { ghidra = g; scopeId = id; } ///< Constructor
|
||||||
|
|
||||||
uint8 getId(void) const { return scopeId; } ///< Get the Ghidra specific id
|
uint8 getId(void) const { return scopeId; } ///< Get the Ghidra specific id
|
||||||
|
virtual bool isNameUsed(const string &nm,const Scope *op2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,6 +81,34 @@ int4 ArchitectureGhidra::readToAnyBurst(istream &s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the string protocol start, a single character, then the protocol end.
|
||||||
|
/// If the character is a 't', return \b true, otherwise \b false.
|
||||||
|
/// \param s is the input stream from the client
|
||||||
|
/// \return the passed back boolean value
|
||||||
|
bool ArchitectureGhidra::readBoolStream(istream &s)
|
||||||
|
|
||||||
|
{
|
||||||
|
int4 c;
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
int4 type = readToAnyBurst(s);
|
||||||
|
if (type != 14) throw JavaError("alignment","Expecting string");
|
||||||
|
c = s.get();
|
||||||
|
res = (c == 't');
|
||||||
|
c = s.get();
|
||||||
|
while(c==0) {
|
||||||
|
c = s.get();
|
||||||
|
}
|
||||||
|
if (c==1) {
|
||||||
|
c = s.get();
|
||||||
|
if (c == 15)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
if (c<0) // If pipe closed, our parent process is probably dead
|
||||||
|
exit(1); // So we exit to avoid a runaway process
|
||||||
|
throw JavaError("alignment","Expecting string terminator");
|
||||||
|
}
|
||||||
|
|
||||||
/// Characters are read up to the next protocol marked and placed into a string.
|
/// Characters are read up to the next protocol marked and placed into a string.
|
||||||
/// The protocol marker is consumed and must indicate the end of a string
|
/// The protocol marker is consumed and must indicate the end of a string
|
||||||
/// or an exception is thrown.
|
/// or an exception is thrown.
|
||||||
|
@ -534,6 +562,29 @@ Document *ArchitectureGhidra::getNamespacePath(uint8 id)
|
||||||
return readXMLAll(sin);
|
return readXMLAll(sin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArchitectureGhidra::isNameUsed(const string &nm,uint8 startId,uint8 stopId)
|
||||||
|
|
||||||
|
{
|
||||||
|
sout.write("\000\000\001\004",4);
|
||||||
|
writeStringStream(sout,"isNameUsed");
|
||||||
|
sout.write("\000\000\001\016",4); // Beginning of string header
|
||||||
|
sout << nm;
|
||||||
|
sout.write("\000\000\001\017",4);
|
||||||
|
sout.write("\000\000\001\016",4); // Beginning of string header
|
||||||
|
sout << hex << startId;
|
||||||
|
sout.write("\000\000\001\017",4);
|
||||||
|
sout.write("\000\000\001\016",4); // Beginning of string header
|
||||||
|
sout << hex << stopId;
|
||||||
|
sout.write("\000\000\001\017",4);
|
||||||
|
sout.write("\000\000\001\005",4);
|
||||||
|
sout.flush();
|
||||||
|
|
||||||
|
readToResponse(sin);
|
||||||
|
bool res = readBoolStream(sin);
|
||||||
|
readResponseEnd(sin);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the name of the primary symbol at the given address.
|
/// Get the name of the primary symbol at the given address.
|
||||||
/// This is used to fetch within function \e labels. Only a name is returned.
|
/// This is used to fetch within function \e labels. Only a name is returned.
|
||||||
/// \param addr is the given address
|
/// \param addr is the given address
|
||||||
|
@ -791,3 +842,25 @@ ArchitectureGhidra::ArchitectureGhidra(const string &pspec,const string &cspec,c
|
||||||
sendCcode = true;
|
sendCcode = true;
|
||||||
sendParamMeasures = false;
|
sendParamMeasures = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArchitectureGhidra::isDynamicSymbolName(const string &nm)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (nm.size() < 8) return false; // 4 characters of prefix, at least 4 of address
|
||||||
|
if (nm[3] != '_') return false;
|
||||||
|
if (nm[0]=='F' && nm[1]=='U' && nm[2]=='N') {
|
||||||
|
}
|
||||||
|
else if (nm[0]=='D' && nm[1]=='A' && nm[2]=='T') {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(int4 i=nm.size()-4;i<nm.size();++i) {
|
||||||
|
char c = nm[i];
|
||||||
|
if (c>='0' && c<='9') continue;
|
||||||
|
if (c>='a' && c<='f') continue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ public:
|
||||||
Document *getMappedSymbolsXML(const Address &addr); ///< Get symbols associated with the given address
|
Document *getMappedSymbolsXML(const Address &addr); ///< Get symbols associated with the given address
|
||||||
Document *getExternalRefXML(const Address &addr); ///< Retrieve a description of an external function
|
Document *getExternalRefXML(const Address &addr); ///< Retrieve a description of an external function
|
||||||
Document *getNamespacePath(uint8 id); ///< Get a description of a namespace path
|
Document *getNamespacePath(uint8 id); ///< Get a description of a namespace path
|
||||||
|
bool isNameUsed(const string &nm,uint8 startId,uint8 stopId); ///< Is given name used along namespace path
|
||||||
string getCodeLabel(const Address &addr); ///< Retrieve a label at the given address
|
string getCodeLabel(const Address &addr); ///< Retrieve a label at the given address
|
||||||
Document *getType(const string &name,uint8 id); ///< Retrieve a data-type description for the given name and id
|
Document *getType(const string &name,uint8 id); ///< Retrieve a data-type description for the given name and id
|
||||||
Document *getComments(const Address &fad,uint4 flags); ///< Retrieve comments for a particular function
|
Document *getComments(const Address &fad,uint4 flags); ///< Retrieve comments for a particular function
|
||||||
|
@ -131,6 +132,7 @@ public:
|
||||||
|
|
||||||
static void segvHandler(int4 sig); ///< Handler for a segment violation (SIGSEGV) signal
|
static void segvHandler(int4 sig); ///< Handler for a segment violation (SIGSEGV) signal
|
||||||
static int4 readToAnyBurst(istream &s); ///< Read the next message protocol marker
|
static int4 readToAnyBurst(istream &s); ///< Read the next message protocol marker
|
||||||
|
static bool readBoolStream(istream &s); ///< Read a boolean value from the client
|
||||||
static void readStringStream(istream &s,string &res); ///< Receive a string from the client
|
static void readStringStream(istream &s,string &res); ///< Receive a string from the client
|
||||||
static void writeStringStream(ostream &s,const string &msg); ///< Send a string to the client
|
static void writeStringStream(ostream &s,const string &msg); ///< Send a string to the client
|
||||||
static void readToResponse(istream &s); ///< Read the query response protocol marker
|
static void readToResponse(istream &s); ///< Read the query response protocol marker
|
||||||
|
@ -140,6 +142,8 @@ public:
|
||||||
static uint1 *readPackedStream(istream &s); ///< Read packed p-code op information
|
static uint1 *readPackedStream(istream &s); ///< Read packed p-code op information
|
||||||
static uint1 *readPackedAll(istream &s); ///< Read a whole response as packed p-code op information
|
static uint1 *readPackedAll(istream &s); ///< Read a whole response as packed p-code op information
|
||||||
static void passJavaException(ostream &s,const string &tp,const string &msg);
|
static void passJavaException(ostream &s,const string &tp,const string &msg);
|
||||||
|
|
||||||
|
static bool isDynamicSymbolName(const string &nm); ///< Check if name is of form FUN_.. or DAT_..
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,6 +54,7 @@ import ghidra.util.xml.XmlUtilities;
|
||||||
*/
|
*/
|
||||||
public class DecompileCallback {
|
public class DecompileCallback {
|
||||||
|
|
||||||
|
public final static int MAX_SYMBOL_COUNT = 16;
|
||||||
/**
|
/**
|
||||||
* Data returned for a query about strings
|
* Data returned for a query about strings
|
||||||
*/
|
*/
|
||||||
|
@ -552,6 +553,57 @@ public class DecompileCallback {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decide if a given name is used by any namespace between a starting namespace
|
||||||
|
* and a stopping namespace. I.e. check for a name collision along a specific namespace path.
|
||||||
|
* Currently, Ghidra is inefficient at calculating this perfectly, so this routine calculates
|
||||||
|
* an approximation that can occasionally indicate a collision when there isn't.
|
||||||
|
* @param name is the given name to check for collisions
|
||||||
|
* @param startId is the id specifying the starting namespace
|
||||||
|
* @param stopId is the id specifying the stopping namespace
|
||||||
|
* @return true if the name (likely) occurs in one of the namespaces on the path
|
||||||
|
*/
|
||||||
|
public boolean isNameUsed(String name, long startId, long stopId) {
|
||||||
|
Namespace namespace = getNameSpaceByID(startId);
|
||||||
|
int pathSize = 0;
|
||||||
|
Namespace curspace = namespace;
|
||||||
|
long curId = namespace.getID();
|
||||||
|
while (curId != stopId && curId != 0) {
|
||||||
|
pathSize += 1;
|
||||||
|
curspace = curspace.getParentNamespace();
|
||||||
|
curId = curspace.getID();
|
||||||
|
}
|
||||||
|
long path[] = new long[pathSize];
|
||||||
|
curspace = namespace;
|
||||||
|
path[0] = startId;
|
||||||
|
for (int i = 1; i < pathSize; ++i) {
|
||||||
|
curspace = curspace.getParentNamespace();
|
||||||
|
path[i] = curspace.getID();
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
SymbolIterator iter = program.getSymbolTable().getSymbols(name);
|
||||||
|
for (;;) {
|
||||||
|
if (!iter.hasNext()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
if (count > MAX_SYMBOL_COUNT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Namespace symSpace = iter.next().getParentNamespace();
|
||||||
|
long id = symSpace.getID();
|
||||||
|
if (id == Namespace.GLOBAL_NAMESPACE_ID) {
|
||||||
|
continue; // Common case we know can't match anything in path
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pathSize; ++i) {
|
||||||
|
if (path[i] == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (count > MAX_SYMBOL_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an XML description of the formal namespace path to the given namespace
|
* Return an XML description of the formal namespace path to the given namespace
|
||||||
* @param id is the ID of the given namespace
|
* @param id is the ID of the given namespace
|
||||||
|
|
|
@ -240,7 +240,7 @@ public class DecompileProcess {
|
||||||
/**
|
/**
|
||||||
* Transfer bytes written to -out- to decompiler process
|
* Transfer bytes written to -out- to decompiler process
|
||||||
* @param out has the collected byte for this write
|
* @param out has the collected byte for this write
|
||||||
* @throws IOException
|
* @throws IOException for any problems with the output stream
|
||||||
*/
|
*/
|
||||||
private void writeBytes(PackedBytes out) throws IOException {
|
private void writeBytes(PackedBytes out) throws IOException {
|
||||||
write(string_start);
|
write(string_start);
|
||||||
|
@ -288,6 +288,9 @@ public class DecompileProcess {
|
||||||
throw new Exception("Bad decompiler query: " + name);
|
throw new Exception("Bad decompiler query: " + name);
|
||||||
}
|
}
|
||||||
switch (name.charAt(3)) {
|
switch (name.charAt(3)) {
|
||||||
|
case 'a': // isNameUsed
|
||||||
|
isNameUsed();
|
||||||
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
getBytes(); // getBytes
|
getBytes(); // getBytes
|
||||||
break;
|
break;
|
||||||
|
@ -430,8 +433,9 @@ public class DecompileProcess {
|
||||||
* @param pspecxml = string containing .pspec xml
|
* @param pspecxml = string containing .pspec xml
|
||||||
* @param cspecxml = string containing .cspec xml
|
* @param cspecxml = string containing .cspec xml
|
||||||
* @param tspecxml = XML string containing translator spec
|
* @param tspecxml = XML string containing translator spec
|
||||||
* @throws IOException
|
* @param coretypesxml = XML description of core data-types
|
||||||
* @throws DecompileException
|
* @throws IOException for problems with the pipe to the decompiler process
|
||||||
|
* @throws DecompileException for problems executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized void registerProgram(DecompileCallback cback, String pspecxml,
|
public synchronized void registerProgram(DecompileCallback cback, String pspecxml,
|
||||||
String cspecxml, String tspecxml, String coretypesxml)
|
String cspecxml, String tspecxml, String coretypesxml)
|
||||||
|
@ -460,9 +464,9 @@ public class DecompileProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free decompiler resources
|
* Free decompiler resources
|
||||||
* @return
|
* @return 1 if a program was actively deregistered, 0 otherwise
|
||||||
* @throws IOException
|
* @throws IOException for problems with the pipe to the decompiler
|
||||||
* @throws DecompileException
|
* @throws DecompileException for problems executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized int deregisterProgram() throws IOException, DecompileException {
|
public synchronized int deregisterProgram() throws IOException, DecompileException {
|
||||||
if (!statusGood) {
|
if (!statusGood) {
|
||||||
|
@ -486,8 +490,8 @@ public class DecompileProcess {
|
||||||
* Send a single command to the decompiler with no parameters and return response
|
* Send a single command to the decompiler with no parameters and return response
|
||||||
* @param command is the name of the command to execute
|
* @param command is the name of the command to execute
|
||||||
* @return the response String
|
* @return the response String
|
||||||
* @throws IOException
|
* @throws IOException for any problems with the pipe to the decompiler process
|
||||||
* @throws DecompileException
|
* @throws DecompileException for any problems executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized LimitedByteBuffer sendCommand(String command)
|
public synchronized LimitedByteBuffer sendCommand(String command)
|
||||||
throws IOException, DecompileException {
|
throws IOException, DecompileException {
|
||||||
|
@ -518,8 +522,8 @@ public class DecompileProcess {
|
||||||
* @param param an additional parameter for the command
|
* @param param an additional parameter for the command
|
||||||
* @param timeoutSecs the number of seconds to run before timing out
|
* @param timeoutSecs the number of seconds to run before timing out
|
||||||
* @return the response string
|
* @return the response string
|
||||||
* @throws IOException
|
* @throws IOException for any problems with the pipe to the decompiler process
|
||||||
* @throws DecompileException
|
* @throws DecompileException for any problems while executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized LimitedByteBuffer sendCommand1ParamTimeout(String command, String param,
|
public synchronized LimitedByteBuffer sendCommand1ParamTimeout(String command, String param,
|
||||||
int timeoutSecs) throws IOException, DecompileException {
|
int timeoutSecs) throws IOException, DecompileException {
|
||||||
|
@ -558,8 +562,8 @@ public class DecompileProcess {
|
||||||
* @param param1 is the first parameter string
|
* @param param1 is the first parameter string
|
||||||
* @param param2 is the second parameter string
|
* @param param2 is the second parameter string
|
||||||
* @return the result string
|
* @return the result string
|
||||||
* @throws IOException
|
* @throws IOException for any problems with the pipe to the decompiler process
|
||||||
* @throws DecompileException
|
* @throws DecompileException for problems executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized LimitedByteBuffer sendCommand2Params(String command, String param1,
|
public synchronized LimitedByteBuffer sendCommand2Params(String command, String param1,
|
||||||
String param2) throws IOException, DecompileException {
|
String param2) throws IOException, DecompileException {
|
||||||
|
@ -597,8 +601,8 @@ public class DecompileProcess {
|
||||||
* @param command is the command string
|
* @param command is the command string
|
||||||
* @param param1 is the parameter as a string
|
* @param param1 is the parameter as a string
|
||||||
* @return the result string
|
* @return the result string
|
||||||
* @throws IOException
|
* @throws IOException for problems with the pipe to the decompiler process
|
||||||
* @throws DecompileException
|
* @throws DecompileException for problems executing the command
|
||||||
*/
|
*/
|
||||||
public synchronized LimitedByteBuffer sendCommand1Param(String command, String param1)
|
public synchronized LimitedByteBuffer sendCommand1Param(String command, String param1)
|
||||||
throws IOException, DecompileException {
|
throws IOException, DecompileException {
|
||||||
|
@ -725,6 +729,20 @@ public class DecompileProcess {
|
||||||
write(query_response_end);
|
write(query_response_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void isNameUsed() throws IOException {
|
||||||
|
String name = readQueryString();
|
||||||
|
String startString = readQueryString();
|
||||||
|
String stopString = readQueryString();
|
||||||
|
long startId = Long.parseLong(startString, 16);
|
||||||
|
long stopId = Long.parseLong(stopString, 16);
|
||||||
|
boolean res = callback.isNameUsed(name, startId, stopId);
|
||||||
|
write(query_response_start);
|
||||||
|
write(string_start);
|
||||||
|
write(res ? 't' : 'f');
|
||||||
|
write(string_end);
|
||||||
|
write(query_response_end);
|
||||||
|
}
|
||||||
|
|
||||||
private void getExternalRefXML() throws IOException {
|
private void getExternalRefXML() throws IOException {
|
||||||
String refaddr = readQueryString();
|
String refaddr = readQueryString();
|
||||||
String res = callback.getExternalRefXML(refaddr);
|
String res = callback.getExternalRefXML(refaddr);
|
||||||
|
|
|
@ -60,13 +60,11 @@ public class HighFunctionSymbol extends HighSymbol {
|
||||||
public Namespace getNamespace() {
|
public Namespace getNamespace() {
|
||||||
Function func = function.getFunction();
|
Function func = function.getFunction();
|
||||||
Namespace namespc = func.getParentNamespace();
|
Namespace namespc = func.getParentNamespace();
|
||||||
if (func.isThunk()) {
|
while (func.isThunk() && namespc.getID() == Namespace.GLOBAL_NAMESPACE_ID) {
|
||||||
// Thunks can be in a different namespace than the thunked function.
|
// Thunks can be in a different namespace than the thunked function.
|
||||||
// We choose the thunk's namespace unless it is the global namespace
|
// We choose the thunk's namespace unless it is the global namespace
|
||||||
if (namespc.getID() == Namespace.GLOBAL_NAMESPACE_ID) {
|
func = func.getThunkedFunction(false);
|
||||||
Function baseFunc = func.getThunkedFunction(true);
|
namespc = func.getParentNamespace();
|
||||||
namespc = baseFunc.getParentNamespace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return namespc;
|
return namespc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue