Cleaning up the names in imports/functions.
This commit is contained in:
parent
68cc34bb79
commit
25af5f410a
|
@ -16,6 +16,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <xenia/kernel/export.h>
|
||||||
#include <xenia/kernel/user_module.h>
|
#include <xenia/kernel/user_module.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
FunctionSymbol() : Symbol(Function) {}
|
FunctionSymbol() : Symbol(Function) {}
|
||||||
virtual ~FunctionSymbol() {}
|
virtual ~FunctionSymbol();
|
||||||
|
|
||||||
FunctionBlock* GetBlock(uint32_t address);
|
FunctionBlock* GetBlock(uint32_t address);
|
||||||
FunctionBlock* SplitBlock(uint32_t address);
|
FunctionBlock* SplitBlock(uint32_t address);
|
||||||
|
@ -119,7 +120,7 @@ public:
|
||||||
class VariableSymbol : public Symbol {
|
class VariableSymbol : public Symbol {
|
||||||
public:
|
public:
|
||||||
VariableSymbol() : Symbol(Variable) {}
|
VariableSymbol() : Symbol(Variable) {}
|
||||||
virtual ~VariableSymbol() {}
|
virtual ~VariableSymbol();
|
||||||
|
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -137,7 +138,8 @@ public:
|
||||||
|
|
||||||
class SymbolDatabase {
|
class SymbolDatabase {
|
||||||
public:
|
public:
|
||||||
SymbolDatabase(xe_memory_ref memory, kernel::UserModule* user_module);
|
SymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver,
|
||||||
|
kernel::UserModule* module);
|
||||||
~SymbolDatabase();
|
~SymbolDatabase();
|
||||||
|
|
||||||
int Analyze();
|
int Analyze();
|
||||||
|
@ -170,6 +172,7 @@ private:
|
||||||
bool IsRestGprLr(uint32_t addr);
|
bool IsRestGprLr(uint32_t addr);
|
||||||
|
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
|
kernel::ExportResolver* export_resolver_;
|
||||||
kernel::UserModule* module_;
|
kernel::UserModule* module_;
|
||||||
size_t function_count_;
|
size_t function_count_;
|
||||||
size_t variable_count_;
|
size_t variable_count_;
|
||||||
|
|
|
@ -48,7 +48,7 @@ ExecModule::ExecModule(
|
||||||
module_ = user_module;
|
module_ = user_module;
|
||||||
engine_ = engine;
|
engine_ = engine;
|
||||||
sdb_ = shared_ptr<sdb::SymbolDatabase>(
|
sdb_ = shared_ptr<sdb::SymbolDatabase>(
|
||||||
new sdb::SymbolDatabase(memory_, module_));
|
new sdb::SymbolDatabase(memory_, export_resolver_.get(), module_));
|
||||||
|
|
||||||
context_ = shared_ptr<LLVMContext>(new LLVMContext());
|
context_ = shared_ptr<LLVMContext>(new LLVMContext());
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,14 @@ using namespace xe::cpu::sdb;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
|
|
||||||
|
|
||||||
|
FunctionSymbol::~FunctionSymbol() {
|
||||||
|
delete name;
|
||||||
|
for (std::map<uint32_t, FunctionBlock*>::iterator it = blocks.begin();
|
||||||
|
it != blocks.end(); ++it) {
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FunctionBlock* FunctionSymbol::GetBlock(uint32_t address) {
|
FunctionBlock* FunctionSymbol::GetBlock(uint32_t address) {
|
||||||
std::map<uint32_t, FunctionBlock*>::iterator it = blocks.find(address);
|
std::map<uint32_t, FunctionBlock*>::iterator it = blocks.find(address);
|
||||||
if (it != blocks.end()) {
|
if (it != blocks.end()) {
|
||||||
|
@ -60,8 +68,14 @@ FunctionBlock* FunctionSymbol::SplitBlock(uint32_t address) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolDatabase::SymbolDatabase(xe_memory_ref memory, UserModule* module) {
|
VariableSymbol::~VariableSymbol() {
|
||||||
|
delete name;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolDatabase::SymbolDatabase(
|
||||||
|
xe_memory_ref memory, ExportResolver* export_resolver, UserModule* module) {
|
||||||
memory_ = xe_memory_retain(memory);
|
memory_ = xe_memory_retain(memory);
|
||||||
|
export_resolver_ = export_resolver;
|
||||||
module_ = module;
|
module_ = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +113,7 @@ int SymbolDatabase::Analyze() {
|
||||||
|
|
||||||
// Queue entry point of the application.
|
// Queue entry point of the application.
|
||||||
FunctionSymbol* fn = GetOrInsertFunction(header->exe_entry_point);
|
FunctionSymbol* fn = GetOrInsertFunction(header->exe_entry_point);
|
||||||
fn->name = xestrdupa("<entry>");
|
fn->name = xestrdupa("start");
|
||||||
|
|
||||||
// Keep pumping the queue until there's nothing left to do.
|
// Keep pumping the queue until there's nothing left to do.
|
||||||
FlushQueue();
|
FlushQueue();
|
||||||
|
@ -240,8 +254,25 @@ void SymbolDatabase::Dump() {
|
||||||
void SymbolDatabase::DumpFunctionBlocks(FunctionSymbol* fn) {
|
void SymbolDatabase::DumpFunctionBlocks(FunctionSymbol* fn) {
|
||||||
for (std::map<uint32_t, FunctionBlock*>::iterator it = fn->blocks.begin();
|
for (std::map<uint32_t, FunctionBlock*>::iterator it = fn->blocks.begin();
|
||||||
it != fn->blocks.end(); ++it) {
|
it != fn->blocks.end(); ++it) {
|
||||||
FunctionBlock* bb = it->second;
|
FunctionBlock* block = it->second;
|
||||||
printf(" bb %.8X\n", bb->start_address);
|
printf(" bb %.8X-%.8X", block->start_address, block->end_address + 4);
|
||||||
|
switch (block->outgoing_type) {
|
||||||
|
case FunctionBlock::kTargetUnknown:
|
||||||
|
printf(" ?\n");
|
||||||
|
break;
|
||||||
|
case FunctionBlock::kTargetBlock:
|
||||||
|
printf(" branch %.8X\n", block->outgoing_block->start_address);
|
||||||
|
break;
|
||||||
|
case FunctionBlock::kTargetFunction:
|
||||||
|
printf(" call %.8X %s\n", block->outgoing_function->start_address, block->outgoing_function->name);
|
||||||
|
break;
|
||||||
|
case FunctionBlock::kTargetLR:
|
||||||
|
printf(" return\n");
|
||||||
|
break;
|
||||||
|
case FunctionBlock::kTargetNone:
|
||||||
|
printf("\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,22 +385,36 @@ int SymbolDatabase::AddImports(const xe_xex2_import_library_t* library) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char name[64];
|
char name[128];
|
||||||
for (size_t n = 0; n < import_info_count; n++) {
|
for (size_t n = 0; n < import_info_count; n++) {
|
||||||
const xe_xex2_import_info_t* info = &import_infos[n];
|
const xe_xex2_import_info_t* info = &import_infos[n];
|
||||||
|
|
||||||
|
KernelExport* kernel_export = export_resolver_->GetExportByOrdinal(
|
||||||
|
library->name, info->ordinal);
|
||||||
|
|
||||||
VariableSymbol* var = GetOrInsertVariable(info->value_address);
|
VariableSymbol* var = GetOrInsertVariable(info->value_address);
|
||||||
// TODO(benvanik): use kernel name
|
if (kernel_export) {
|
||||||
xesnprintf(name, XECOUNT(name), "__var_%s_%.3X", library->name,
|
if (info->thunk_address) {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "__imp__%s", kernel_export->name);
|
||||||
|
} else {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "__imp__%s_%.3X", library->name,
|
||||||
info->ordinal);
|
info->ordinal);
|
||||||
|
}
|
||||||
var->name = xestrdupa(name);
|
var->name = xestrdupa(name);
|
||||||
if (info->thunk_address) {
|
if (info->thunk_address) {
|
||||||
FunctionSymbol* fn = GetOrInsertFunction(info->thunk_address);
|
FunctionSymbol* fn = GetOrInsertFunction(info->thunk_address);
|
||||||
// TODO(benvanik): use kernel name
|
|
||||||
xesnprintf(name, XECOUNT(name), "__thunk_%s_%.3X", library->name,
|
|
||||||
info->ordinal);
|
|
||||||
fn->end_address = fn->start_address + 16 - 4;
|
fn->end_address = fn->start_address + 16 - 4;
|
||||||
fn->name = xestrdupa(name);
|
|
||||||
fn->type = FunctionSymbol::Kernel;
|
fn->type = FunctionSymbol::Kernel;
|
||||||
|
if (kernel_export) {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name);
|
||||||
|
} else {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "__kernel_%s_%.3X", library->name,
|
||||||
|
info->ordinal);
|
||||||
|
}
|
||||||
|
fn->name = xestrdupa(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +487,13 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
|
|
||||||
XELOGSDB("Analyzing function %.8X...\n", fn->start_address);
|
XELOGSDB("Analyzing function %.8X...\n", fn->start_address);
|
||||||
|
|
||||||
|
// Set a default name, if it hasn't been named already.
|
||||||
|
if (!fn->name) {
|
||||||
|
char name[32];
|
||||||
|
xesnprintfa(name, XECOUNT(name), "sub_%.8X", fn->start_address);
|
||||||
|
fn->name = xestrdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
InstrData i;
|
InstrData i;
|
||||||
FunctionBlock* block = NULL;
|
FunctionBlock* block = NULL;
|
||||||
uint32_t furthest_target = fn->start_address;
|
uint32_t furthest_target = fn->start_address;
|
||||||
|
@ -577,6 +629,12 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
fn->end_address = addr;
|
fn->end_address = addr;
|
||||||
|
|
||||||
// If there's spare bits at the end, split the function.
|
// If there's spare bits at the end, split the function.
|
||||||
|
// TODO(benvanik): splitting?
|
||||||
|
|
||||||
|
// TODO(benvanik): find and record stack information
|
||||||
|
// - look for __savegprlr_* and __restgprlr_*
|
||||||
|
// - if present, flag function as needing a stack
|
||||||
|
// - record prolog/epilog lengths/stack size/etc
|
||||||
|
|
||||||
XELOGSDB("Finished analyzing %.8X\n", fn->start_address);
|
XELOGSDB("Finished analyzing %.8X\n", fn->start_address);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -688,8 +746,12 @@ bool SymbolDatabase::FillHoles() {
|
||||||
uint32_t data_addr = XEGETUINT32BE(p + 1);
|
uint32_t data_addr = XEGETUINT32BE(p + 1);
|
||||||
if (data_addr) {
|
if (data_addr) {
|
||||||
VariableSymbol* var = GetOrInsertVariable(data_addr);
|
VariableSymbol* var = GetOrInsertVariable(data_addr);
|
||||||
char name[32];
|
char name[128];
|
||||||
xesnprintf(name, XECOUNT(name), "__ee_data_%.8X", *it);
|
if (ee->function) {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "__ee_data_%s", ee->function->name);
|
||||||
|
} else {
|
||||||
|
xesnprintfa(name, XECOUNT(name), "__ee_data_%.8X", *it);
|
||||||
|
}
|
||||||
var->name = xestrdupa(name);
|
var->name = xestrdupa(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue