Minor fixes and debug helpers to track externs.
This commit is contained in:
parent
e362a65189
commit
615229bd87
|
@ -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();
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue