Very basic, super slow, nasty indirection.

This commit is contained in:
Ben Vanik
2013-05-25 20:32:58 -07:00
parent 2986a0be82
commit 4073028188
11 changed files with 113 additions and 63 deletions

View File

@@ -448,18 +448,6 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
// TODO(benvanik): queue for add without expensive locks?
sym_table_->AddFunction(fn->start_address, fn);
XELOGSDB("Finished analyzing %.8X", fn->start_address);
return 0;
}
int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
// Find variable accesses.
// TODO(benvanik): data analysis to find variable accesses.
// A list of function targets that were undefined.
// This will run another analysis pass and it'd be best to avoid this.
std::vector<uint32_t> new_fns;
// For each basic block:
// - find outgoing target block or function
for (std::map<uint32_t, FunctionBlock*>::iterator it = fn->blocks.begin();
@@ -485,26 +473,19 @@ int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
// Function call.
block->outgoing_type = FunctionBlock::kTargetFunction;
block->outgoing_function = GetFunction(block->outgoing_address);
if (block->outgoing_function) {
FunctionSymbol::AddCall(fn, block->outgoing_function);
} else {
XELOGE("call target not found: %.8X -> %.8X",
block->end_address, block->outgoing_address);
new_fns.push_back(block->outgoing_address);
}
XEASSERTNOTNULL(block->outgoing_function);
FunctionSymbol::AddCall(fn, block->outgoing_function);
}
}
}
if (new_fns.size()) {
XELOGW("Repeat analysis required to find %d new functions",
(uint32_t)new_fns.size());
for (std::vector<uint32_t>::iterator it = new_fns.begin();
it != new_fns.end(); ++it) {
GetOrInsertFunction(*it, fn);
}
return 1;
}
XELOGSDB("Finished analyzing %.8X", fn->start_address);
return 0;
}
int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
// Find variable accesses.
// TODO(benvanik): data analysis to find variable accesses.
return 0;
}

View File

@@ -16,17 +16,26 @@ using namespace xe::cpu::sdb;
SymbolTable::SymbolTable() {
lock_ = xe_mutex_alloc(10000);
XEASSERTNOTNULL(lock_);
}
SymbolTable::~SymbolTable() {
xe_mutex_free(lock_);
lock_ = NULL;
}
int SymbolTable::AddFunction(uint32_t address, FunctionSymbol* symbol) {
xe_mutex_lock(lock_);
map_[address] = symbol;
xe_mutex_unlock(lock_);
return 0;
}
FunctionSymbol* SymbolTable::GetFunction(uint32_t address) {
xe_mutex_lock(lock_);
FunctionMap::const_iterator it = map_.find(address);
return it != map_.end() ? it->second : NULL;
FunctionSymbol* result = it != map_.end() ? it->second : NULL;
xe_mutex_unlock(lock_);
return result;
}

View File

@@ -29,6 +29,8 @@ public:
sdb::FunctionSymbol* GetFunction(uint32_t address);
private:
// TODO(benvanik): replace with a better data structure.
xe_mutex_t* lock_;
typedef std::tr1::unordered_map<uint32_t, sdb::FunctionSymbol*> FunctionMap;
FunctionMap map_;
};