From 615229bd87f1730c25f0822b52fd9c41b1865806 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 4 Jan 2014 13:20:19 -0800 Subject: [PATCH] Minor fixes and debug helpers to track externs. --- src/alloy/frontend/ppc/ppc_hir_builder.cc | 25 +++++++--------------- src/alloy/runtime/function.cc | 10 ++++++++- src/alloy/runtime/function.h | 4 ++++ src/xenia/cpu/xex_module.cc | 19 ++++++++++++---- src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc | 1 + src/xenia/kernel/xex2.cc | 2 ++ 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 69780ea93..e83675c84 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -89,6 +89,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) { MarkLabel(label); } + Instr* first_instr = 0; if (FLAGS_annotate_disassembly) { if (label) { AnnotateLabel(address, label); @@ -104,14 +105,20 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) { } else { Comment("%.8X %.8X %s ???", address, i.code, i.type->name); } + first_instr = last_instr(); } // Mark source offset for debugging. // We could omit this if we never wanted to debug. SourceOffset(i.address); + if (!first_instr) { + first_instr = last_instr(); + } + + // Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT. + instr_offset_list_[offset] = first_instr; if (!i.type) { - instr_offset_list_[offset] = prev_instr->next; XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code); Comment("INVALID!"); //TraceInvalidInstruction(i); @@ -136,22 +143,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) { // This printf is handy for sort/uniquify to find instructions. printf("unimplinstr %s\n", i.type->name); } - - // Stash instruction offset. We do this down here so that if the function - // splits blocks we don't have weird pointers. - if (prev_instr && prev_instr->next) { - instr_offset_list_[offset] = prev_instr->next; - } else if (prev_instr) { - instr_offset_list_[offset] = prev_instr->block->next->instr_head; - } else if (current_block_) { - instr_offset_list_[offset] = current_block_->instr_head; - } else if (block_tail_) { - instr_offset_list_[offset] = block_tail_->instr_head; - } else { - XEASSERTALWAYS(); - } - XEASSERT(instr_offset_list_[offset]->next->opcode == &OPCODE_TRAP_TRUE_info || - instr_offset_list_[offset]->next->src1.offset == i.address); } return Finalize(); diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 0f393ebba..0fbe95ab2 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -86,17 +86,25 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { ExternFunction::ExternFunction( uint64_t address, Handler handler, void* arg0, void* arg1) : + name_(0), handler_(handler), arg0_(arg0), arg1_(arg1), Function(Function::EXTERN_FUNCTION, address) { } ExternFunction::~ExternFunction() { + if (name_) { + xe_free(name_); + } +} + +void ExternFunction::set_name(const char* name) { + name_ = xestrdupa(name); } int ExternFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { if (!handler_) { - XELOGW("undefined extern call to %.8X", address()); + XELOGW("undefined extern call to %.8X %s", address(), name()); return 0; } handler_(thread_state->raw_context(), arg0_, arg1_); diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index 634f93e5f..40bad6aa8 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -68,6 +68,9 @@ public: ExternFunction(uint64_t address, Handler handler, void* arg0, void* arg1); virtual ~ExternFunction(); + const char* name() const { return name_; } + void set_name(const char* name); + Handler handler() const { return handler_; } void* arg0() const { return arg0_; } void* arg1() const { return arg1_; } @@ -76,6 +79,7 @@ protected: virtual int CallImpl(ThreadState* thread_state, uint64_t return_address); protected: + char* name_; Handler handler_; void* arg0_; void* arg1_; diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index d782297f2..fd6f74c2f 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -134,8 +134,16 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { uint32_t* slot = (uint32_t*)(membase + info->value_address); if (kernel_export->type == KernelExport::Function) { // Not exactly sure what this should be... - // TODO(benvanik): find out what import variables are. - XELOGW("kernel import variable not defined"); + 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. + } 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); + } } else { if (kernel_export->is_implemented) { // Implemented - replace with pointer. @@ -176,11 +184,14 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { } DefineFunction(fn_info); - Function* fn = new ExternFunction( - info->thunk_address, + 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); } diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc index 8c5381155..dc2f2b1f1 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc @@ -27,6 +27,7 @@ namespace xboxkrnl { void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) { XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4); + fflush(stdout); DebugBreak(); XEASSERTALWAYS(); } diff --git a/src/xenia/kernel/xex2.cc b/src/xenia/kernel/xex2.cc index c2663542b..e31814f03 100644 --- a/src/xenia/kernel/xex2.cc +++ b/src/xenia/kernel/xex2.cc @@ -931,6 +931,8 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex, info_count * sizeof(xe_xex2_import_info_t)); XEEXPECTNOTNULL(infos); + XEASSERTNOTZERO(info_count); + // Construct infos. for (size_t n = 0, i = 0; n < library->record_count; n++) { const uint32_t record = library->records[n];