Mostly complete tracing. Probably a lot of bugs.
This commit is contained in:
@@ -12,18 +12,14 @@
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
|
||||
DECLARE_bool(trace_function_generation);
|
||||
DECLARE_bool(trace_kernel_calls);
|
||||
DECLARE_bool(trace_user_calls);
|
||||
DECLARE_bool(trace_instructions);
|
||||
DECLARE_bool(trace_registers);
|
||||
DECLARE_bool(trace_branches);
|
||||
DECLARE_bool(trace_user_calls);
|
||||
DECLARE_bool(trace_kernel_calls);
|
||||
DECLARE_uint64(trace_thread_mask);
|
||||
|
||||
DECLARE_string(load_module_map);
|
||||
|
||||
DECLARE_string(dump_path);
|
||||
DECLARE_bool(dump_module_map);
|
||||
|
||||
|
||||
#endif // XENIA_CPU_PRIVATE_H_
|
||||
|
||||
@@ -9,32 +9,22 @@
|
||||
|
||||
#include <xenia/cpu/cpu-private.h>
|
||||
|
||||
|
||||
// Tracing:
|
||||
DEFINE_bool(trace_instructions, false,
|
||||
"Trace all instructions.");
|
||||
DEFINE_bool(trace_registers, false,
|
||||
"Trace register values when tracing instructions.");
|
||||
DEFINE_bool(trace_branches, false,
|
||||
"Trace all branches.");
|
||||
DEFINE_bool(trace_user_calls, false,
|
||||
"Trace all user function calls.");
|
||||
DEFINE_bool(trace_kernel_calls, false,
|
||||
"Trace all kernel function calls.");
|
||||
DEFINE_uint64(trace_thread_mask, -1,
|
||||
"Trace threads with IDs in the mask, or -1 for all.");
|
||||
|
||||
|
||||
// Debugging:
|
||||
DEFINE_string(load_module_map, "",
|
||||
DEFINE_bool(trace_function_generation, false,
|
||||
"Trace function generation/JITing.");
|
||||
DEFINE_bool(trace_kernel_calls, false, "Trace all kernel function calls.");
|
||||
DEFINE_bool(trace_user_calls, false, "Trace all user function calls.");
|
||||
DEFINE_bool(trace_instructions, false, "Trace all instructions.");
|
||||
DEFINE_bool(trace_registers, false,
|
||||
"Trace register values when tracing instructions.");
|
||||
DEFINE_string(
|
||||
load_module_map, "",
|
||||
"Loads a .map for symbol names and to diff with the generated symbol "
|
||||
"database.");
|
||||
|
||||
|
||||
// Dumping:
|
||||
DEFINE_string(dump_path, "build/",
|
||||
"Directory that dump files are placed into.");
|
||||
"Directory that dump files are placed into.");
|
||||
DEFINE_bool(dump_module_bitcode, true,
|
||||
"Writes the module bitcode both before and after optimizations.");
|
||||
DEFINE_bool(dump_module_map, true,
|
||||
"Dumps the module symbol database.");
|
||||
"Writes the module bitcode both before and after optimizations.");
|
||||
DEFINE_bool(dump_module_map, true, "Dumps the module symbol database.");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/cpu/cpu-private.h>
|
||||
#include <xenia/cpu/xenon_memory.h>
|
||||
#include <xenia/cpu/xenon_runtime.h>
|
||||
#include <xenia/cpu/xex_module.h>
|
||||
@@ -70,7 +71,26 @@ Processor::~Processor() {
|
||||
int Processor::Setup() {
|
||||
assert_null(runtime_);
|
||||
|
||||
runtime_ = new XenonRuntime(memory_, export_resolver_);
|
||||
uint32_t debug_info_flags = DEBUG_INFO_DEFAULT;
|
||||
uint32_t trace_flags = 0;
|
||||
if (FLAGS_trace_function_generation) {
|
||||
trace_flags |= TRACE_FUNCTION_GENERATION;
|
||||
}
|
||||
if (FLAGS_trace_kernel_calls) {
|
||||
trace_flags |= TRACE_EXTERN_CALLS;
|
||||
}
|
||||
if (FLAGS_trace_user_calls) {
|
||||
trace_flags |= TRACE_USER_CALLS;
|
||||
}
|
||||
if (FLAGS_trace_instructions) {
|
||||
trace_flags |= TRACE_SOURCE;
|
||||
}
|
||||
if (FLAGS_trace_registers) {
|
||||
trace_flags |= TRACE_SOURCE_VALUES;
|
||||
}
|
||||
|
||||
runtime_ = new XenonRuntime(memory_, export_resolver_, debug_info_flags,
|
||||
trace_flags);
|
||||
if (!runtime_) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,11 @@ using namespace alloy::runtime;
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
|
||||
|
||||
XenonRuntime::XenonRuntime(
|
||||
alloy::Memory* memory, ExportResolver* export_resolver) :
|
||||
Runtime(memory),
|
||||
export_resolver_(export_resolver) {
|
||||
}
|
||||
XenonRuntime::XenonRuntime(alloy::Memory* memory,
|
||||
ExportResolver* export_resolver,
|
||||
uint32_t debug_info_flags, uint32_t trace_flags)
|
||||
: Runtime(memory, debug_info_flags, trace_flags),
|
||||
export_resolver_(export_resolver) {}
|
||||
|
||||
XenonRuntime::~XenonRuntime() = default;
|
||||
|
||||
|
||||
@@ -17,29 +17,26 @@
|
||||
|
||||
XEDECLARECLASS1(xe, ExportResolver);
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
|
||||
class XenonThreadState;
|
||||
|
||||
|
||||
class XenonRuntime : public alloy::runtime::Runtime {
|
||||
public:
|
||||
XenonRuntime(Memory* memory, ExportResolver* export_resolver);
|
||||
public:
|
||||
XenonRuntime(Memory* memory, ExportResolver* export_resolver,
|
||||
uint32_t debug_info_flags, uint32_t trace_flags);
|
||||
virtual ~XenonRuntime();
|
||||
|
||||
ExportResolver* export_resolver() const { return export_resolver_; }
|
||||
|
||||
virtual int Initialize(std::unique_ptr<alloy::backend::Backend> backend = 0);
|
||||
|
||||
private:
|
||||
private:
|
||||
ExportResolver* export_resolver_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_CPU_XENON_RUNTIME_H_
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <xenia/cpu/xenon_thread_state.h>
|
||||
|
||||
#include <xdb/protocol.h>
|
||||
#include <xenia/cpu/xenon_runtime.h>
|
||||
|
||||
using namespace alloy;
|
||||
@@ -36,6 +37,7 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id,
|
||||
context_->membase = memory_->membase();
|
||||
context_->runtime = runtime;
|
||||
context_->thread_state = this;
|
||||
context_->thread_id = thread_id_;
|
||||
|
||||
// Set initial registers.
|
||||
context_->r[1] = stack_address_ + stack_size;
|
||||
@@ -56,3 +58,28 @@ XenonThreadState::~XenonThreadState() {
|
||||
xe_free_aligned(context_);
|
||||
memory_->HeapFree(stack_address_, stack_size_);
|
||||
}
|
||||
|
||||
void XenonThreadState::WriteRegisters(xdb::protocol::Registers* registers) {
|
||||
registers->lr = context_->lr;
|
||||
registers->ctr = context_->ctr;
|
||||
registers->xer = 0xFEFEFEFE;
|
||||
registers->cr[0] = context_->cr0.value;
|
||||
registers->cr[1] = context_->cr1.value;
|
||||
registers->cr[2] = context_->cr2.value;
|
||||
registers->cr[3] = context_->cr3.value;
|
||||
registers->cr[4] = context_->cr4.value;
|
||||
registers->cr[5] = context_->cr5.value;
|
||||
registers->cr[6] = context_->cr6.value;
|
||||
registers->cr[7] = context_->cr7.value;
|
||||
registers->fpscr = context_->fpscr.value;
|
||||
registers->vscr = context_->vscr_sat;
|
||||
static_assert(sizeof(registers->gpr) == sizeof(context_->r),
|
||||
"structs must match");
|
||||
static_assert(sizeof(registers->fpr) == sizeof(context_->f),
|
||||
"structs must match");
|
||||
static_assert(sizeof(registers->vr) == sizeof(context_->v),
|
||||
"structs must match");
|
||||
memcpy(registers->gpr, context_->r, sizeof(context_->r));
|
||||
memcpy(registers->fpr, context_->f, sizeof(context_->f));
|
||||
memcpy(registers->vr, context_->v, sizeof(context_->v));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include <alloy/runtime/thread_state.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
namespace xdb {
|
||||
namespace protocol {
|
||||
struct Registers;
|
||||
} // namespace protocol
|
||||
} // namespace xdb
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -34,6 +39,8 @@ public:
|
||||
uint64_t thread_state_address() const { return thread_state_address_; }
|
||||
PPCContext* context() const { return context_; }
|
||||
|
||||
void WriteRegisters(xdb::protocol::Registers* registers);
|
||||
|
||||
private:
|
||||
uint64_t stack_address_;
|
||||
size_t stack_size_;
|
||||
|
||||
Reference in New Issue
Block a user