Refactoring of function types. Also fixes some library import bugs.
This commit is contained in:
@@ -648,7 +648,6 @@ json_t* Processor::DumpModule(XexModule* module, bool& succeeded) {
|
||||
json_object_set_new(import_library_json, "imports", imports_json);
|
||||
|
||||
json_array_append_new(library_imports_json, import_library_json);
|
||||
xe_free(import_infos);
|
||||
}
|
||||
json_object_set_new(module_json, "libraryImports", library_imports_json);
|
||||
|
||||
|
||||
@@ -135,14 +135,12 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
||||
if (kernel_export->type == KernelExport::Function) {
|
||||
// Not exactly sure what this should be...
|
||||
if (info->thunk_address) {
|
||||
// slot = XESWAP32BE(info->thunk_address);
|
||||
// Setting this breaks other emu code that relies on it not being
|
||||
// modified. Not sure what to do.
|
||||
*slot = XESWAP32BE(info->thunk_address);
|
||||
} else {
|
||||
// TODO(benvanik): find out what import variables are.
|
||||
XELOGW("kernel import variable not defined %.8X %s",
|
||||
info->value_address, kernel_export->name);
|
||||
//*slot = XESWAP32BE(0xF00DF00D);
|
||||
*slot = XESWAP32BE(0xF00DF00D);
|
||||
}
|
||||
} else {
|
||||
if (kernel_export->is_implemented) {
|
||||
@@ -165,39 +163,45 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
||||
info->ordinal);
|
||||
}
|
||||
|
||||
FunctionInfo* fn_info;
|
||||
DeclareFunction(info->thunk_address, &fn_info);
|
||||
fn_info->set_end_address(info->thunk_address + 16 - 4);
|
||||
//fn->type = FunctionSymbol::Kernel;
|
||||
//fn->kernel_export = kernel_export;
|
||||
fn_info->set_name(name);
|
||||
fn_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||
// On load we have something like this in memory:
|
||||
// li r3, 0
|
||||
// li r4, 0x1F5
|
||||
// mtspr CTR, r11
|
||||
// bctr
|
||||
// Real consoles rewrite this with some code that sets r11.
|
||||
// If we did that we'd still have to put a thunk somewhere and do the
|
||||
// dynamic lookup. Instead, we rewrite it to use syscalls, as they
|
||||
// aren't used on the 360. Alloy backends can either take the syscall
|
||||
// or do something smarter.
|
||||
// sc
|
||||
// blr
|
||||
// nop
|
||||
// nop
|
||||
uint8_t* p = memory()->Translate(info->thunk_address);
|
||||
XESETUINT32BE(p + 0x0, 0x44000002);
|
||||
XESETUINT32BE(p + 0x4, 0x4E800020);
|
||||
XESETUINT32BE(p + 0x8, 0x60000000);
|
||||
XESETUINT32BE(p + 0xC, 0x60000000);
|
||||
|
||||
ExternFunction::Handler handler = 0;
|
||||
FunctionInfo::ExternHandler handler = 0;
|
||||
void* handler_data = 0;
|
||||
if (kernel_export) {
|
||||
handler = (ExternFunction::Handler)kernel_export->function_data.shim;
|
||||
handler = (FunctionInfo::ExternHandler)kernel_export->function_data.shim;
|
||||
handler_data = kernel_export->function_data.shim_data;
|
||||
} else {
|
||||
handler = (ExternFunction::Handler)UndefinedImport;
|
||||
handler = (FunctionInfo::ExternHandler)UndefinedImport;
|
||||
handler_data = this;
|
||||
}
|
||||
|
||||
DefineFunction(fn_info);
|
||||
auto fn = new ExternFunction(
|
||||
info->thunk_address,
|
||||
handler,
|
||||
handler_data,
|
||||
NULL);
|
||||
if (kernel_export) {
|
||||
fn->set_name(kernel_export->name);
|
||||
}
|
||||
fn_info->set_function(fn);
|
||||
fn_info->set_status(SymbolInfo::STATUS_DEFINED);
|
||||
FunctionInfo* fn_info;
|
||||
DeclareFunction(info->thunk_address, &fn_info);
|
||||
fn_info->set_end_address(info->thunk_address + 16 - 4);
|
||||
fn_info->set_name(name);
|
||||
fn_info->SetupExtern(handler, handler_data, NULL);
|
||||
fn_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||
}
|
||||
}
|
||||
|
||||
xe_free(import_infos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,28 @@ void ExportResolver::RegisterTable(
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) {
|
||||
uint16_t n = 0;
|
||||
for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) {
|
||||
if (!xestrcmpa(library_name, it->name)) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
KernelExport* ExportResolver::GetExportByOrdinal(
|
||||
const uint16_t library_ordinal, const uint32_t ordinal) {
|
||||
auto& table = tables_[library_ordinal];
|
||||
// TODO(benvanik): binary search?
|
||||
for (size_t n = 0; n < table.count; n++) {
|
||||
if (table.exports[n].ordinal == ordinal) {
|
||||
return &table.exports[n];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name,
|
||||
const uint32_t ordinal) {
|
||||
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
||||
|
||||
@@ -68,6 +68,10 @@ public:
|
||||
void RegisterTable(const char* library_name, KernelExport* exports,
|
||||
const size_t count);
|
||||
|
||||
uint16_t GetLibraryOrdinal(const char* library_name);
|
||||
|
||||
KernelExport* GetExportByOrdinal(const uint16_t library_ordinal,
|
||||
const uint32_t ordinal);
|
||||
KernelExport* GetExportByOrdinal(const char* library_name,
|
||||
const uint32_t ordinal);
|
||||
KernelExport* GetExportByName(const char* library_name, const char* name);
|
||||
|
||||
@@ -345,8 +345,6 @@ void XUserModule::Dump() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
xe_free(import_infos);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
@@ -24,11 +24,16 @@ using namespace alloy;
|
||||
typedef struct xe_xex2 {
|
||||
xe_ref_t ref;
|
||||
|
||||
Memory* memory;
|
||||
Memory* memory;
|
||||
|
||||
xe_xex2_header_t header;
|
||||
xe_xex2_header_t header;
|
||||
|
||||
std::vector<PESection*>* sections;
|
||||
|
||||
struct {
|
||||
size_t count;
|
||||
xe_xex2_import_info_t* infos;
|
||||
} library_imports[16];
|
||||
} xe_xex2_t;
|
||||
|
||||
|
||||
@@ -39,6 +44,8 @@ int xe_xex2_read_image(xe_xex2_ref xex,
|
||||
const uint8_t *xex_addr, const size_t xex_length,
|
||||
Memory* memory);
|
||||
int xe_xex2_load_pe(xe_xex2_ref xex);
|
||||
int xe_xex2_find_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t* library);
|
||||
|
||||
|
||||
xe_xex2_ref xe_xex2_load(Memory* memory,
|
||||
@@ -58,6 +65,11 @@ xe_xex2_ref xe_xex2_load(Memory* memory,
|
||||
|
||||
XEEXPECTZERO(xe_xex2_load_pe(xex));
|
||||
|
||||
for (size_t n = 0; n < xex->header.import_library_count; n++) {
|
||||
auto library = &xex->header.import_libraries[n];
|
||||
XEEXPECTZERO(xe_xex2_find_import_infos(xex, library));
|
||||
}
|
||||
|
||||
return xex;
|
||||
|
||||
XECLEANUP:
|
||||
@@ -894,12 +906,10 @@ const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library,
|
||||
xe_xex2_import_info_t **out_import_infos,
|
||||
size_t *out_import_info_count) {
|
||||
uint8_t *mem = xex->memory->membase();
|
||||
const xe_xex2_header_t *header = xe_xex2_get_header(xex);
|
||||
int xe_xex2_find_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library) {
|
||||
uint8_t* mem = xex->memory->membase();
|
||||
auto header = xe_xex2_get_header(xex);
|
||||
|
||||
// Find library index for verification.
|
||||
size_t library_index = -1;
|
||||
@@ -970,13 +980,34 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
||||
}
|
||||
}
|
||||
|
||||
*out_import_info_count = info_count;
|
||||
*out_import_infos = infos;
|
||||
xex->library_imports[library_index].count = info_count;
|
||||
xex->library_imports[library_index].infos = infos;
|
||||
return 0;
|
||||
|
||||
XECLEANUP:
|
||||
xe_free(infos);
|
||||
*out_import_info_count = 0;
|
||||
*out_import_infos = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xe_xex2_get_import_infos(xe_xex2_ref xex,
|
||||
const xe_xex2_import_library_t *library,
|
||||
xe_xex2_import_info_t **out_import_infos,
|
||||
size_t *out_import_info_count) {
|
||||
auto header = xe_xex2_get_header(xex);
|
||||
|
||||
// Find library index for verification.
|
||||
size_t library_index = -1;
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
if (&header->import_libraries[n] == library) {
|
||||
library_index = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (library_index == (size_t)-1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
*out_import_info_count = xex->library_imports[library_index].count;
|
||||
*out_import_infos = xex->library_imports[library_index].infos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user