Adding thread ID to trace lines and cleaning up their formatting.
This commit is contained in:
parent
82ee749515
commit
6f602d120a
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <xenia/cpu/global_exports.h>
|
#include <xenia/cpu/global_exports.h>
|
||||||
|
|
||||||
|
#include <xenia/logging.h>
|
||||||
#include <xenia/cpu/cpu-private.h>
|
#include <xenia/cpu/cpu-private.h>
|
||||||
#include <xenia/cpu/processor.h>
|
#include <xenia/cpu/processor.h>
|
||||||
#include <xenia/cpu/sdb.h>
|
#include <xenia/cpu/sdb.h>
|
||||||
|
@ -75,7 +76,9 @@ void _cdecl XeAccessViolation(
|
||||||
void _cdecl XeTraceKernelCall(
|
void _cdecl XeTraceKernelCall(
|
||||||
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||||
KernelExport* kernel_export) {
|
KernelExport* kernel_export) {
|
||||||
XELOGCPU("TRACE: %.8X -> k.%.8X (%s)",
|
uint32_t thread_id = state->thread_state->thread_id();
|
||||||
|
xe_log_line("", thread_id, "XeTraceKernelCall", 't',
|
||||||
|
"KERNEL CALL: %.8X -> k.%.8X (%s)",
|
||||||
(uint32_t)call_ia - 4, (uint32_t)cia,
|
(uint32_t)call_ia - 4, (uint32_t)cia,
|
||||||
kernel_export ? kernel_export->name : "unknown");
|
kernel_export ? kernel_export->name : "unknown");
|
||||||
}
|
}
|
||||||
|
@ -83,7 +86,9 @@ void _cdecl XeTraceKernelCall(
|
||||||
void _cdecl XeTraceUserCall(
|
void _cdecl XeTraceUserCall(
|
||||||
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||||
FunctionSymbol* fn) {
|
FunctionSymbol* fn) {
|
||||||
XELOGCPU("TRACE: %.8X -> u.%.8X (%s)",
|
uint32_t thread_id = state->thread_state->thread_id();
|
||||||
|
xe_log_line("", thread_id, "XeTraceUserCall", 't',
|
||||||
|
"USER CALL %.8X -> u.%.8X (%s)",
|
||||||
(uint32_t)call_ia - 4, (uint32_t)cia, fn->name());
|
(uint32_t)call_ia - 4, (uint32_t)cia, fn->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,14 +102,43 @@ void _cdecl XeTraceBranch(
|
||||||
target_ia = state->ctr;
|
target_ia = state->ctr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
XELOGCPU("TRACE: %.8X -> b.%.8X",
|
|
||||||
|
uint32_t thread_id = state->thread_state->thread_id();
|
||||||
|
xe_log_line("", thread_id, "XeTraceBranch", 't',
|
||||||
|
"BRANCH %.8X -> b.%.8X",
|
||||||
(uint32_t)cia, (uint32_t)target_ia);
|
(uint32_t)cia, (uint32_t)target_ia);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cdecl XeTraceInstruction(
|
void _cdecl XeTraceInstruction(
|
||||||
xe_ppc_state_t* state, uint64_t cia, uint64_t data) {
|
xe_ppc_state_t* state, uint64_t cia, uint64_t data) {
|
||||||
|
char buffer[2048];
|
||||||
|
buffer[0] = 0;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
ppc::InstrData i;
|
||||||
|
i.address = (uint32_t)cia;
|
||||||
|
i.code = (uint32_t)data;
|
||||||
|
i.type = ppc::GetInstrType(i.code);
|
||||||
|
if (i.type && i.type->disassemble) {
|
||||||
|
ppc::InstrDisasm d;
|
||||||
|
i.type->disassemble(i, d);
|
||||||
|
std::string disasm;
|
||||||
|
d.Dump(disasm);
|
||||||
|
offset += xesnprintfa(buffer + offset, XECOUNT(buffer) - offset,
|
||||||
|
"%.8X %.8X %s %s",
|
||||||
|
i.address, i.code,
|
||||||
|
i.type && i.type->emit ? " " : "X",
|
||||||
|
disasm.c_str());
|
||||||
|
} else {
|
||||||
|
offset += xesnprintfa(buffer + offset, XECOUNT(buffer) - offset,
|
||||||
|
"%.8X %.8X %s %s",
|
||||||
|
i.address, i.code,
|
||||||
|
i.type && i.type->emit ? " " : "X",
|
||||||
|
i.type ? i.type->name : "<unknown>");
|
||||||
|
}
|
||||||
|
|
||||||
if (FLAGS_trace_registers) {
|
if (FLAGS_trace_registers) {
|
||||||
XELOGCPU(
|
offset += xesnprintfa(buffer + offset, XECOUNT(buffer) - offset,
|
||||||
"\n"
|
"\n"
|
||||||
" lr=%.16llX ctr=%.16llX cr=%.4X xer=%.16llX\n"
|
" lr=%.16llX ctr=%.16llX cr=%.4X xer=%.16llX\n"
|
||||||
" r0=%.16llX r1=%.16llX r2=%.16llX r3=%.16llX\n"
|
" r0=%.16llX r1=%.16llX r2=%.16llX r3=%.16llX\n"
|
||||||
|
@ -126,25 +160,8 @@ void _cdecl XeTraceInstruction(
|
||||||
state->r[28], state->r[29], state->r[30], state->r[31]);
|
state->r[28], state->r[29], state->r[30], state->r[31]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ppc::InstrData i;
|
uint32_t thread_id = state->thread_state->thread_id();
|
||||||
i.address = (uint32_t)cia;
|
xe_log_line("", thread_id, "XeTraceInstruction", 't', buffer);
|
||||||
i.code = (uint32_t)data;
|
|
||||||
i.type = ppc::GetInstrType(i.code);
|
|
||||||
if (i.type && i.type->disassemble) {
|
|
||||||
ppc::InstrDisasm d;
|
|
||||||
i.type->disassemble(i, d);
|
|
||||||
std::string disasm;
|
|
||||||
d.Dump(disasm);
|
|
||||||
XELOGCPU("TRACE: %.8X %.8X %s %s",
|
|
||||||
i.address, i.code,
|
|
||||||
i.type && i.type->emit ? " " : "X",
|
|
||||||
disasm.c_str());
|
|
||||||
} else {
|
|
||||||
XELOGCPU("TRACE: %.8X %.8X %s %s",
|
|
||||||
i.address, i.code,
|
|
||||||
i.type && i.type->emit ? " " : "X",
|
|
||||||
i.type ? i.type->name : "<unknown>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (cia == 0x82012074) {
|
// if (cia == 0x82012074) {
|
||||||
// printf("BREAKBREAKBREAK\n");
|
// printf("BREAKBREAKBREAK\n");
|
||||||
|
|
|
@ -13,6 +13,14 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace cpu {
|
||||||
|
class Processor;
|
||||||
|
class ThreadState;
|
||||||
|
} // namespace cpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
// namespace FPRF {
|
// namespace FPRF {
|
||||||
// enum FPRF_e {
|
// enum FPRF_e {
|
||||||
// QUIET_NAN = 0x00088000,
|
// QUIET_NAN = 0x00088000,
|
||||||
|
@ -144,9 +152,8 @@ typedef struct XECACHEALIGN64 xe_ppc_state {
|
||||||
// Runtime-specific data pointer. Used on callbacks to get access to the
|
// Runtime-specific data pointer. Used on callbacks to get access to the
|
||||||
// current runtime and its data.
|
// current runtime and its data.
|
||||||
uint8_t* membase;
|
uint8_t* membase;
|
||||||
void* processor;
|
xe::cpu::Processor* processor;
|
||||||
void* thread_state;
|
xe::cpu::ThreadState* thread_state;
|
||||||
void* runtime;
|
|
||||||
|
|
||||||
void SetRegFromString(const char* name, const char* value);
|
void SetRegFromString(const char* name, const char* value);
|
||||||
bool CompareRegWithString(const char* name, const char* value,
|
bool CompareRegWithString(const char* name, const char* value,
|
||||||
|
|
|
@ -191,9 +191,10 @@ uint32_t Processor::CreateCallback(void (*callback)(void* data), void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadState* Processor::AllocThread(uint32_t stack_size,
|
ThreadState* Processor::AllocThread(uint32_t stack_size,
|
||||||
uint32_t thread_state_address) {
|
uint32_t thread_state_address,
|
||||||
|
uint32_t thread_id) {
|
||||||
ThreadState* thread_state = new ThreadState(
|
ThreadState* thread_state = new ThreadState(
|
||||||
this, stack_size, thread_state_address);
|
this, stack_size, thread_state_address, thread_id);
|
||||||
return thread_state;
|
return thread_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@ public:
|
||||||
|
|
||||||
uint32_t CreateCallback(void (*callback)(void* data), void* data);
|
uint32_t CreateCallback(void (*callback)(void* data), void* data);
|
||||||
|
|
||||||
ThreadState* AllocThread(uint32_t stack_size, uint32_t thread_state_address);
|
ThreadState* AllocThread(uint32_t stack_size, uint32_t thread_state_address,
|
||||||
|
uint32_t thread_id);
|
||||||
void DeallocThread(ThreadState* thread_state);
|
void DeallocThread(ThreadState* thread_state);
|
||||||
int Execute(ThreadState* thread_state, uint32_t address);
|
int Execute(ThreadState* thread_state, uint32_t address);
|
||||||
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t arg0);
|
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t arg0);
|
||||||
|
|
|
@ -19,8 +19,9 @@ using namespace xe::cpu;
|
||||||
|
|
||||||
ThreadState::ThreadState(
|
ThreadState::ThreadState(
|
||||||
Processor* processor,
|
Processor* processor,
|
||||||
uint32_t stack_size, uint32_t thread_state_address) :
|
uint32_t stack_size, uint32_t thread_state_address, uint32_t thread_id) :
|
||||||
stack_size_(stack_size), thread_state_address_(thread_state_address) {
|
stack_size_(stack_size), thread_state_address_(thread_state_address),
|
||||||
|
thread_id_(thread_id) {
|
||||||
memory_ = processor->memory();
|
memory_ = processor->memory();
|
||||||
|
|
||||||
stack_address_ = xe_memory_heap_alloc(memory_, 0, stack_size, 0);
|
stack_address_ = xe_memory_heap_alloc(memory_, 0, stack_size, 0);
|
||||||
|
@ -42,6 +43,10 @@ ThreadState::~ThreadState() {
|
||||||
xe_memory_release(memory_);
|
xe_memory_release(memory_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ThreadState::thread_id() const {
|
||||||
|
return thread_id_;
|
||||||
|
}
|
||||||
|
|
||||||
xe_ppc_state_t* ThreadState::ppc_state() {
|
xe_ppc_state_t* ThreadState::ppc_state() {
|
||||||
return &ppc_state_;
|
return &ppc_state_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,12 @@ class Processor;
|
||||||
class ThreadState {
|
class ThreadState {
|
||||||
public:
|
public:
|
||||||
ThreadState(Processor* processor,
|
ThreadState(Processor* processor,
|
||||||
uint32_t stack_size, uint32_t thread_state_address);
|
uint32_t stack_size, uint32_t thread_state_address,
|
||||||
|
uint32_t thread_id);
|
||||||
~ThreadState();
|
~ThreadState();
|
||||||
|
|
||||||
|
uint32_t thread_id() const;
|
||||||
|
|
||||||
xe_ppc_state_t* ppc_state();
|
xe_ppc_state_t* ppc_state();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -37,6 +40,7 @@ private:
|
||||||
|
|
||||||
uint32_t stack_address_;
|
uint32_t stack_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
|
uint32_t thread_id_;
|
||||||
|
|
||||||
xe_ppc_state_t ppc_state_;
|
xe_ppc_state_t ppc_state_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -616,8 +616,6 @@ void X64Emitter::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceInstruction(i);
|
|
||||||
|
|
||||||
if (!i.type) {
|
if (!i.type) {
|
||||||
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
|
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
|
||||||
TraceInvalidInstruction(i);
|
TraceInvalidInstruction(i);
|
||||||
|
@ -634,6 +632,8 @@ void X64Emitter::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
ia, i.code, i.type->name);
|
ia, i.code, i.type->name);
|
||||||
TraceInvalidInstruction(i);
|
TraceInvalidInstruction(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TraceInstruction(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we fall through, create the branch.
|
// If we fall through, create the branch.
|
||||||
|
|
|
@ -31,7 +31,7 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
thread_id_(++next_xthread_id),
|
thread_id_(++next_xthread_id),
|
||||||
thread_handle_(0),
|
thread_handle_(0),
|
||||||
thread_state_address_(0),
|
thread_state_address_(0),
|
||||||
processor_state_(0) {
|
thread_state_(0) {
|
||||||
creation_params_.stack_size = stack_size;
|
creation_params_.stack_size = stack_size;
|
||||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||||
creation_params_.start_address = start_address;
|
creation_params_.start_address = start_address;
|
||||||
|
@ -47,8 +47,8 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
XThread::~XThread() {
|
XThread::~XThread() {
|
||||||
PlatformDestroy();
|
PlatformDestroy();
|
||||||
|
|
||||||
if (processor_state_) {
|
if (thread_state_) {
|
||||||
kernel_state()->processor()->DeallocThread(processor_state_);
|
kernel_state()->processor()->DeallocThread(thread_state_);
|
||||||
}
|
}
|
||||||
if (tls_address_) {
|
if (tls_address_) {
|
||||||
xe_memory_heap_free(kernel_state()->memory(), tls_address_, 0);
|
xe_memory_heap_free(kernel_state()->memory(), tls_address_, 0);
|
||||||
|
@ -125,9 +125,9 @@ X_STATUS XThread::Create() {
|
||||||
|
|
||||||
// Allocate processor thread state.
|
// Allocate processor thread state.
|
||||||
// This is thread safe.
|
// This is thread safe.
|
||||||
processor_state_ = kernel_state()->processor()->AllocThread(
|
thread_state_ = kernel_state()->processor()->AllocThread(
|
||||||
creation_params_.stack_size, thread_state_address_);
|
creation_params_.stack_size, thread_state_address_, thread_id_);
|
||||||
if (!processor_state_) {
|
if (!thread_state_) {
|
||||||
XELOGW("Unable to allocate processor thread state");
|
XELOGW("Unable to allocate processor thread state");
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ void XThread::Execute() {
|
||||||
|
|
||||||
// Run user code.
|
// Run user code.
|
||||||
int exit_code = (int)kernel_state()->processor()->Execute(
|
int exit_code = (int)kernel_state()->processor()->Execute(
|
||||||
processor_state_,
|
thread_state_,
|
||||||
creation_params_.start_address, creation_params_.start_context);
|
creation_params_.start_address, creation_params_.start_context);
|
||||||
|
|
||||||
// If we got here it means the execute completed without an exit being called.
|
// If we got here it means the execute completed without an exit being called.
|
||||||
|
|
|
@ -57,7 +57,7 @@ private:
|
||||||
void* thread_handle_;
|
void* thread_handle_;
|
||||||
uint32_t tls_address_;
|
uint32_t tls_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
cpu::ThreadState* processor_state_;
|
cpu::ThreadState* thread_state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ int run_test(string& src_file_path) {
|
||||||
XEEXPECTZERO(processor->LoadRawBinary(bin_file_path_str, 0x82010000));
|
XEEXPECTZERO(processor->LoadRawBinary(bin_file_path_str, 0x82010000));
|
||||||
|
|
||||||
// Simulate a thread.
|
// Simulate a thread.
|
||||||
thread_state = processor->AllocThread(256 * 1024, 0);
|
thread_state = processor->AllocThread(256 * 1024, 0, 100);
|
||||||
|
|
||||||
// Setup test state from annotations.
|
// Setup test state from annotations.
|
||||||
XEEXPECTZERO(setup_test_state(memory, processor.get(), thread_state,
|
XEEXPECTZERO(setup_test_state(memory, processor.get(), thread_state,
|
||||||
|
|
Loading…
Reference in New Issue