Minor fixes and debug helpers to track externs.

This commit is contained in:
Ben Vanik 2014-01-04 13:20:19 -08:00
parent e362a65189
commit 615229bd87
6 changed files with 39 additions and 22 deletions

View File

@ -89,6 +89,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) {
MarkLabel(label); MarkLabel(label);
} }
Instr* first_instr = 0;
if (FLAGS_annotate_disassembly) { if (FLAGS_annotate_disassembly) {
if (label) { if (label) {
AnnotateLabel(address, label); AnnotateLabel(address, label);
@ -104,14 +105,20 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) {
} else { } else {
Comment("%.8X %.8X %s ???", address, i.code, i.type->name); Comment("%.8X %.8X %s ???", address, i.code, i.type->name);
} }
first_instr = last_instr();
} }
// Mark source offset for debugging. // Mark source offset for debugging.
// We could omit this if we never wanted to debug. // We could omit this if we never wanted to debug.
SourceOffset(i.address); 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) { if (!i.type) {
instr_offset_list_[offset] = prev_instr->next;
XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code); XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code);
Comment("INVALID!"); Comment("INVALID!");
//TraceInvalidInstruction(i); //TraceInvalidInstruction(i);
@ -136,22 +143,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) {
// This printf is handy for sort/uniquify to find instructions. // This printf is handy for sort/uniquify to find instructions.
printf("unimplinstr %s\n", i.type->name); 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(); return Finalize();

View File

@ -86,17 +86,25 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) {
ExternFunction::ExternFunction( ExternFunction::ExternFunction(
uint64_t address, Handler handler, void* arg0, void* arg1) : uint64_t address, Handler handler, void* arg0, void* arg1) :
name_(0),
handler_(handler), arg0_(arg0), arg1_(arg1), handler_(handler), arg0_(arg0), arg1_(arg1),
Function(Function::EXTERN_FUNCTION, address) { Function(Function::EXTERN_FUNCTION, address) {
} }
ExternFunction::~ExternFunction() { ExternFunction::~ExternFunction() {
if (name_) {
xe_free(name_);
}
}
void ExternFunction::set_name(const char* name) {
name_ = xestrdupa(name);
} }
int ExternFunction::CallImpl(ThreadState* thread_state, int ExternFunction::CallImpl(ThreadState* thread_state,
uint64_t return_address) { uint64_t return_address) {
if (!handler_) { if (!handler_) {
XELOGW("undefined extern call to %.8X", address()); XELOGW("undefined extern call to %.8X %s", address(), name());
return 0; return 0;
} }
handler_(thread_state->raw_context(), arg0_, arg1_); handler_(thread_state->raw_context(), arg0_, arg1_);

View File

@ -68,6 +68,9 @@ public:
ExternFunction(uint64_t address, Handler handler, void* arg0, void* arg1); ExternFunction(uint64_t address, Handler handler, void* arg0, void* arg1);
virtual ~ExternFunction(); virtual ~ExternFunction();
const char* name() const { return name_; }
void set_name(const char* name);
Handler handler() const { return handler_; } Handler handler() const { return handler_; }
void* arg0() const { return arg0_; } void* arg0() const { return arg0_; }
void* arg1() const { return arg1_; } void* arg1() const { return arg1_; }
@ -76,6 +79,7 @@ protected:
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address); virtual int CallImpl(ThreadState* thread_state, uint64_t return_address);
protected: protected:
char* name_;
Handler handler_; Handler handler_;
void* arg0_; void* arg0_;
void* arg1_; void* arg1_;

View File

@ -134,8 +134,16 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
uint32_t* slot = (uint32_t*)(membase + info->value_address); uint32_t* slot = (uint32_t*)(membase + info->value_address);
if (kernel_export->type == KernelExport::Function) { if (kernel_export->type == KernelExport::Function) {
// Not exactly sure what this should be... // 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.
} else {
// TODO(benvanik): find out what import variables are. // TODO(benvanik): find out what import variables are.
XELOGW("kernel import variable not defined"); XELOGW("kernel import variable not defined %.8X %s",
info->value_address, kernel_export->name);
//*slot = XESWAP32BE(0xF00DF00D);
}
} else { } else {
if (kernel_export->is_implemented) { if (kernel_export->is_implemented) {
// Implemented - replace with pointer. // Implemented - replace with pointer.
@ -176,11 +184,14 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
} }
DefineFunction(fn_info); DefineFunction(fn_info);
Function* fn = new ExternFunction( auto fn = new ExternFunction(
info->thunk_address, info->thunk_address,
handler, handler,
handler_data, handler_data,
NULL); NULL);
if (kernel_export) {
fn->set_name(kernel_export->name);
}
fn_info->set_function(fn); fn_info->set_function(fn);
fn_info->set_status(SymbolInfo::STATUS_DEFINED); fn_info->set_status(SymbolInfo::STATUS_DEFINED);
} }

View File

@ -27,6 +27,7 @@ namespace xboxkrnl {
void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) { 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); XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4);
fflush(stdout);
DebugBreak(); DebugBreak();
XEASSERTALWAYS(); XEASSERTALWAYS();
} }

View File

@ -931,6 +931,8 @@ int xe_xex2_get_import_infos(xe_xex2_ref xex,
info_count * sizeof(xe_xex2_import_info_t)); info_count * sizeof(xe_xex2_import_info_t));
XEEXPECTNOTNULL(infos); XEEXPECTNOTNULL(infos);
XEASSERTNOTZERO(info_count);
// Construct infos. // Construct infos.
for (size_t n = 0, i = 0; n < library->record_count; n++) { for (size_t n = 0, i = 0; n < library->record_count; n++) {
const uint32_t record = library->records[n]; const uint32_t record = library->records[n];