mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Refactor namespaces to use ids
This commit is contained in:
parent
7329198ad7
commit
44ed318672
9 changed files with 164 additions and 72 deletions
|
@ -35,46 +35,66 @@ ScopeGhidra::~ScopeGhidra(void)
|
|||
/// creates a dedicated Scope object to hold such a Symbol. The immediate
|
||||
/// parent for the new Scope must already exist.
|
||||
/// \param nm is the name of the new \e namespace
|
||||
/// \param id is the Ghidra specific id associated with the namespace
|
||||
/// \param par is the parent Scope
|
||||
/// \return the new \e namespace Scope
|
||||
Scope *ScopeGhidra::createNewScope(const string &nm,Scope *par) const
|
||||
Scope *ScopeGhidra::createNewScope(const string &nm,uint8 id,Scope *par) const
|
||||
|
||||
{
|
||||
Scope *newscope = new ScopeGhidraNamespace(nm,ghidra);
|
||||
Scope *newscope = par->resolveScope(nm);
|
||||
if (newscope != (Scope *)0) {
|
||||
// Its possible because of the way that we merge root namespaces that
|
||||
// Ghidra has distinct namespace ids for namespaces that we want merged
|
||||
// So we return any existing namespace even though the id is different.
|
||||
return newscope;
|
||||
}
|
||||
newscope = new ScopeGhidraNamespace(nm,id,ghidra);
|
||||
ghidra->symboltab->attachScope(newscope,par);
|
||||
// Document *doc = ghidra->getScopeProperties(newscope);
|
||||
// if (doc == (Document *)0)
|
||||
// throw LowlevelError("Bad getScopeProperties response");
|
||||
// const Element *root = doc->getRoot();
|
||||
// if (root->getName() == "rangelist") {
|
||||
// RangeList newrangetree;
|
||||
// newrangetree.restoreXml(root,ghidra);
|
||||
// ghidra->symboltab->set_range(newscope,newrangetree);
|
||||
// }
|
||||
// delete doc;
|
||||
if (id != 0)
|
||||
namespaceMap[id] = newscope;
|
||||
return newscope;
|
||||
}
|
||||
|
||||
/// The Ghidra client reports a \e namespace path associated with
|
||||
/// Symbol. Determine if this Scope already exists in the cache and built
|
||||
/// The Ghidra client reports a \e namespace id associated with
|
||||
/// Symbol. Determine if a matching \e namespac Scope already exists in the cache and build
|
||||
/// it if it isn't. This may mean creating a new \e namespace Scope.
|
||||
/// \param path is absolute path to the desired Scope
|
||||
/// \return the Scope matching the path.
|
||||
Scope *ScopeGhidra::reresolveScope(const vector<string> &path) const
|
||||
/// \param id is the ID associated with the Ghidra namespace
|
||||
/// \return the Scope matching the id.
|
||||
Scope *ScopeGhidra::reresolveScope(uint8 id) const
|
||||
|
||||
{
|
||||
if (path.size()==1) return cache;
|
||||
// Get pointer to ourselves (which is not const)
|
||||
Scope *curscope = glb->symboltab->getGlobalScope();
|
||||
int4 i;
|
||||
for(i=1;i<path.size();++i) {
|
||||
Scope *nextscope = curscope->resolveScope(path[i]);
|
||||
if (nextscope == (Scope *)0) break;
|
||||
curscope = nextscope;
|
||||
if (id == 0) return cache;
|
||||
map<uint8,Scope *>::const_iterator miter = namespaceMap.find(id);
|
||||
if (miter != namespaceMap.end())
|
||||
return (*miter).second; // Scope was previously cached
|
||||
|
||||
Document *doc = ghidra->getNamespacePath(id);
|
||||
if (doc == (Document *)0)
|
||||
throw LowlevelError("Could not get namespace info");
|
||||
|
||||
Scope *curscope = glb->symboltab->getGlobalScope(); // Get pointer to ourselves (which is not const)
|
||||
try {
|
||||
const List &list(doc->getRoot()->getChildren());
|
||||
List::const_iterator iter = list.begin();
|
||||
++iter; // Skip element describing the root scope
|
||||
while(iter != list.end()) {
|
||||
const Element *el = *iter;
|
||||
++iter;
|
||||
uint8 scopeId;
|
||||
istringstream s(el->getAttributeValue("id"));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> scopeId;
|
||||
miter = namespaceMap.find(scopeId);
|
||||
if (miter == namespaceMap.end())
|
||||
curscope = createNewScope(el->getContent(), scopeId, curscope);
|
||||
else
|
||||
curscope = (*miter).second;
|
||||
}
|
||||
delete doc;
|
||||
}
|
||||
while(i != path.size()) {
|
||||
curscope = createNewScope(path[i],curscope);
|
||||
i += 1;
|
||||
catch(LowlevelError &err) {
|
||||
delete doc;
|
||||
throw err;
|
||||
}
|
||||
return curscope;
|
||||
}
|
||||
|
@ -126,16 +146,14 @@ Symbol *ScopeGhidra::dump2Cache(Document *doc) const
|
|||
}
|
||||
|
||||
List::const_iterator iter = el->getChildren().begin();
|
||||
// The first subnode must be scope information
|
||||
el = *iter;
|
||||
vector<string> path;
|
||||
const List &list2(el->getChildren());
|
||||
List::const_iterator iter2;
|
||||
for(iter2=list2.begin();iter2!=list2.end();++iter2)
|
||||
path.push_back( (*iter2)->getContent() );
|
||||
uint8 scopeId;
|
||||
{
|
||||
istringstream s(el->getAttributeValue("id"));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> scopeId;
|
||||
}
|
||||
|
||||
Scope *scope = reresolveScope(path);
|
||||
++iter; // The second part is a <mapsym>
|
||||
Scope *scope = reresolveScope(scopeId);
|
||||
el = *iter;
|
||||
try {
|
||||
sym = scope->addMapSym(el);
|
||||
|
@ -255,6 +273,7 @@ void ScopeGhidra::clear(void)
|
|||
{
|
||||
cache->clear();
|
||||
holes.clear();
|
||||
namespaceMap.clear();
|
||||
if (cacheDirty) {
|
||||
ghidra->symboltab->setProperties(flagbaseDefault); // Restore database properties to defaults
|
||||
cacheDirty = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue