mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Print symbol namespace paths in context
This commit is contained in:
parent
a027a5cdd8
commit
f7a8e264aa
11 changed files with 196 additions and 72 deletions
|
@ -295,18 +295,32 @@ int4 Symbol::getMapEntryPosition(const SymbolEntry *entry) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
/// A value of 0 means the base Symbol name is visible and not overridden in the given use scope.
|
||||
/// For a given context scope where \b this Symbol is used, determine how many elements of
|
||||
/// the full namespace path need to be printed to correctly distinguish it.
|
||||
/// A value of 0 means the base symbol name is visible and not overridden in the context scope.
|
||||
/// A value of 1 means the base name may be overridden, but the parent scope name is not.
|
||||
/// The minimual number of names that distinguishes \b this Symbol uniquely within the
|
||||
/// The minimal number of names that distinguishes the symbol name uniquely within the
|
||||
/// use scope is returned.
|
||||
/// \param useScope is the given scope where \b this Symbol is being used
|
||||
/// \return the number of (extra) names needed to distinguish \b this Symbol
|
||||
/// \param useScope is the given scope where the symbol is being used
|
||||
/// \return the number of (extra) names needed to distinguish the symbol
|
||||
int4 Symbol::getResolutionDepth(const Scope *useScope) const
|
||||
|
||||
{
|
||||
if (scope == useScope) return 0; // Symbol is in scope where it is used
|
||||
if (useScope == (const Scope *)0) { // Treat null useScope as resolving the full path
|
||||
const Scope *point = scope;
|
||||
int4 count = 0;
|
||||
while(point != (const Scope *)0) {
|
||||
count += 1;
|
||||
point = point->getParent();
|
||||
}
|
||||
return count-1; // Don't print global scope
|
||||
}
|
||||
if (depthScope == useScope)
|
||||
return depthResolution;
|
||||
depthScope = useScope;
|
||||
const Scope *distinguishScope = scope->findDistinguishingScope(useScope);
|
||||
int4 depth = 0;
|
||||
depthResolution = 0;
|
||||
string distinguishName;
|
||||
const Scope *terminatingScope;
|
||||
if (distinguishScope == (const Scope *)0) { // Symbol scope is ancestor of use scope
|
||||
|
@ -317,15 +331,15 @@ int4 Symbol::getResolutionDepth(const Scope *useScope) const
|
|||
distinguishName = distinguishScope->getName();
|
||||
const Scope *currentScope = scope;
|
||||
while(currentScope != distinguishScope) { // For any scope up to the distinguishing scope
|
||||
depth += 1; // Print its name
|
||||
depthResolution += 1; // Print its name
|
||||
currentScope = currentScope->getParent();
|
||||
}
|
||||
depth += 1; // Also print the distinguishing scope name
|
||||
depthResolution += 1; // Also print the distinguishing scope name
|
||||
terminatingScope = distinguishScope->getParent();
|
||||
}
|
||||
if (useScope->isNameUsed(distinguishName,terminatingScope))
|
||||
depth += 1; // Name was overridden, we need one more distinguishing name
|
||||
return depth;
|
||||
depthResolution += 1; // Name was overridden, we need one more distinguishing name
|
||||
return depthResolution;
|
||||
}
|
||||
|
||||
/// \param s is the output stream
|
||||
|
@ -564,7 +578,7 @@ Funcdata *FunctionSymbol::getFunction(void)
|
|||
{
|
||||
if (fd != (Funcdata *)0) return fd;
|
||||
SymbolEntry *entry = getFirstWholeMap();
|
||||
fd = new Funcdata(name,scope,entry->getAddr());
|
||||
fd = new Funcdata(name,scope,entry->getAddr(),this);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -586,7 +600,7 @@ void FunctionSymbol::restoreXml(const Element *el)
|
|||
|
||||
{
|
||||
if (el->getName() == "function") {
|
||||
fd = new Funcdata("",scope,Address());
|
||||
fd = new Funcdata("",scope,Address(),this);
|
||||
symbolId = fd->restoreXml(el);
|
||||
name = fd->getName();
|
||||
if (consumeSize < fd->getSize()) {
|
||||
|
@ -1377,20 +1391,19 @@ void Scope::getNameSegments(vector<string> &vec) const
|
|||
}
|
||||
|
||||
/// Put the parent scopes of \b this into an array in order, starting with the global scope.
|
||||
/// This scope itself will not be in the array.
|
||||
/// \param vec is storage for the array of scopes
|
||||
void Scope::getScopePath(vector<Scope *> &vec) const
|
||||
void Scope::getScopePath(vector<const Scope *> &vec) const
|
||||
|
||||
{
|
||||
int4 count = 0;
|
||||
Scope *cur = parent;
|
||||
while(cur != (Scope *)0) { // Count number of elements in path
|
||||
const Scope *cur = this;
|
||||
while(cur != (const Scope *)0) { // Count number of elements in path
|
||||
count += 1;
|
||||
cur = cur->parent;
|
||||
}
|
||||
vec.resize(count);
|
||||
cur = parent;
|
||||
while(cur != (Scope *)0) {
|
||||
cur = this;
|
||||
while(cur != (const Scope *)0) {
|
||||
count -= 1;
|
||||
vec[count] = cur;
|
||||
cur = cur->parent;
|
||||
|
@ -1407,7 +1420,7 @@ bool Scope::isNameUsed(const string &nm,const Scope *op2) const
|
|||
{
|
||||
const Scope *currentScope = this;
|
||||
while(currentScope != op2) {
|
||||
if (currentScope->isNameUsed(name))
|
||||
if (currentScope->isNameUsed(nm))
|
||||
return true;
|
||||
currentScope = currentScope->parent;
|
||||
}
|
||||
|
@ -1422,12 +1435,12 @@ bool Scope::isNameUsed(const string &nm,const Scope *op2) const
|
|||
const Scope *Scope::findDistinguishingScope(const Scope *op2) const
|
||||
|
||||
{
|
||||
if (this == op2) return (Scope *)0; // Quickly check most common cases
|
||||
if (this == op2) return (const Scope *)0; // Quickly check most common cases
|
||||
if (parent == op2) return this;
|
||||
if (op2->parent == this) return op2;
|
||||
if (op2->parent == this) return (const Scope *)0;
|
||||
if (parent == op2->parent) return this;
|
||||
vector<Scope *> thisPath;
|
||||
vector<Scope *> op2Path;
|
||||
vector<const Scope *> thisPath;
|
||||
vector<const Scope *> op2Path;
|
||||
getScopePath(thisPath);
|
||||
op2->getScopePath(op2Path);
|
||||
int4 min = thisPath.size();
|
||||
|
@ -1440,7 +1453,7 @@ const Scope *Scope::findDistinguishingScope(const Scope *op2) const
|
|||
if (min < thisPath.size())
|
||||
return thisPath[min]; // thisPath matches op2Path but is longer
|
||||
if (min < op2Path.size())
|
||||
return (Scope *)0; // op2Path matches thisPath but is longer
|
||||
return (const Scope *)0; // op2Path matches thisPath but is longer
|
||||
return this; // ancestor paths are identical (only base scopes differ)
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1466,7 @@ Symbol *Scope::addSymbol(const string &name,Datatype *ct)
|
|||
{
|
||||
Symbol *sym;
|
||||
|
||||
sym = new Symbol(this,name,ct);
|
||||
sym = new Symbol(owner,name,ct);
|
||||
addSymbolInternal(sym); // Let this scope lay claim to the new object
|
||||
return sym;
|
||||
}
|
||||
|
@ -1474,7 +1487,7 @@ SymbolEntry *Scope::addSymbol(const string &name,Datatype *ct,
|
|||
{
|
||||
Symbol *sym;
|
||||
|
||||
sym = new Symbol(this,name,ct);
|
||||
sym = new Symbol(owner,name,ct);
|
||||
addSymbolInternal(sym);
|
||||
return addMapPoint(sym,addr,usepoint);
|
||||
}
|
||||
|
@ -1509,19 +1522,19 @@ Symbol *Scope::addMapSym(const Element *el)
|
|||
Symbol *sym;
|
||||
const string &symname( subel->getName() );
|
||||
if (symname == "symbol")
|
||||
sym = new Symbol(this);
|
||||
sym = new Symbol(owner);
|
||||
else if (symname == "dynsymbol")
|
||||
sym = new Symbol(this);
|
||||
sym = new Symbol(owner);
|
||||
else if (symname == "equatesymbol")
|
||||
sym = new EquateSymbol(this);
|
||||
sym = new EquateSymbol(owner);
|
||||
else if (symname == "function")
|
||||
sym = new FunctionSymbol(this,glb->min_funcsymbol_size);
|
||||
sym = new FunctionSymbol(owner,glb->min_funcsymbol_size);
|
||||
else if (symname == "functionshell")
|
||||
sym = new FunctionSymbol(this,glb->min_funcsymbol_size);
|
||||
sym = new FunctionSymbol(owner,glb->min_funcsymbol_size);
|
||||
else if (symname == "labelsym")
|
||||
sym = new LabSymbol(this);
|
||||
sym = new LabSymbol(owner);
|
||||
else if (symname == "externrefsymbol")
|
||||
sym = new ExternRefSymbol(this);
|
||||
sym = new ExternRefSymbol(owner);
|
||||
else
|
||||
throw LowlevelError("Unknown symbol type: "+symname);
|
||||
try { // Protect against duplicate scope errors
|
||||
|
@ -1563,7 +1576,7 @@ FunctionSymbol *Scope::addFunction(const Address &addr,const string &nm)
|
|||
errmsg += " overlaps object: "+overlap->getSymbol()->getName();
|
||||
glb->printMessage(errmsg);
|
||||
}
|
||||
sym = new FunctionSymbol(this,nm,glb->min_funcsymbol_size);
|
||||
sym = new FunctionSymbol(owner,nm,glb->min_funcsymbol_size);
|
||||
addSymbolInternal(sym);
|
||||
// Map symbol to base address of function
|
||||
// there is no limit on the applicability of this map within scope
|
||||
|
@ -1584,7 +1597,7 @@ ExternRefSymbol *Scope::addExternalRef(const Address &addr,const Address &refadd
|
|||
{
|
||||
ExternRefSymbol *sym;
|
||||
|
||||
sym = new ExternRefSymbol(this,refaddr,nm);
|
||||
sym = new ExternRefSymbol(owner,refaddr,nm);
|
||||
addSymbolInternal(sym);
|
||||
// Map symbol to given address
|
||||
// there is no limit on applicability of this map within scope
|
||||
|
@ -1612,7 +1625,7 @@ LabSymbol *Scope::addCodeLabel(const Address &addr,const string &nm)
|
|||
errmsg += " overlaps object: "+overlap->getSymbol()->getName();
|
||||
glb->printMessage(errmsg);
|
||||
}
|
||||
sym = new LabSymbol(this,nm);
|
||||
sym = new LabSymbol(owner,nm);
|
||||
addSymbolInternal(sym);
|
||||
addMapPoint(sym,addr,Address());
|
||||
return sym;
|
||||
|
@ -1632,7 +1645,7 @@ Symbol *Scope::addDynamicSymbol(const string &nm,Datatype *ct,const Address &cad
|
|||
{
|
||||
Symbol *sym;
|
||||
|
||||
sym = new Symbol(this,nm,ct);
|
||||
sym = new Symbol(owner,nm,ct);
|
||||
addSymbolInternal(sym);
|
||||
RangeList rnglist;
|
||||
if (!caddr.isInvalid())
|
||||
|
@ -1832,12 +1845,17 @@ list<SymbolEntry>::iterator ScopeInternal::endDynamic(void)
|
|||
/// \param nm is the name of the Scope
|
||||
/// \param g is the Architecture it belongs to
|
||||
ScopeInternal::ScopeInternal(const string &nm,Architecture *g)
|
||||
: Scope(nm,g)
|
||||
: Scope(nm,g,this)
|
||||
{
|
||||
nextUniqueId = 0;
|
||||
int4 numspaces = g->numSpaces();
|
||||
for(int4 i=0;i<numspaces;++i)
|
||||
maptable.push_back((EntryMap *)0);
|
||||
maptable.resize(g->numSpaces(),(EntryMap *)0);
|
||||
}
|
||||
|
||||
ScopeInternal::ScopeInternal(const string &nm,Architecture *g, Scope *own)
|
||||
: Scope(nm,g,own)
|
||||
{
|
||||
nextUniqueId = 0;
|
||||
maptable.resize(g->numSpaces(),(EntryMap *)0);
|
||||
}
|
||||
|
||||
ScopeInternal::~ScopeInternal(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue