Removing xdb and old tracing code before rewrite.

This commit is contained in:
Ben Vanik
2015-05-03 22:01:31 -07:00
parent d1ee1512b9
commit 4c8f3501ad
52 changed files with 14 additions and 1773 deletions

View File

@@ -10,6 +10,7 @@
#include "xenia/cpu/backend/x64/x64_emitter.h"
#include "xenia/base/assert.h"
#include "xenia/base/atomic.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/vec128.h"
@@ -25,7 +26,6 @@
#include "xenia/cpu/symbol_info.h"
#include "xenia/cpu/thread_state.h"
#include "xenia/profiling.h"
#include "xdb/protocol.h"
namespace xe {
namespace cpu {
@@ -161,19 +161,6 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
mov(rdx, qword[rcx + 8]); // membase
}
uint64_t trace_base = runtime_->memory()->trace_base();
if (trace_base && trace_flags_ & TRACE_USER_CALLS) {
mov(rax, trace_base);
mov(r8d, static_cast<uint32_t>(sizeof(xdb::protocol::UserCallEvent)));
lock();
xadd(qword[rax], r8);
mov(rax, static_cast<uint64_t>(xdb::protocol::EventType::USER_CALL) |
(static_cast<uint64_t>(0) << 8) | (0ull << 32));
mov(qword[r8], rax);
EmitGetCurrentThreadId();
mov(word[r8 + 2], ax);
}
// Body.
auto block = builder->first_block();
while (block) {
@@ -188,16 +175,6 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
const Instr* instr = block->instr_head;
while (instr) {
const Instr* new_tail = instr;
// Special handling of TRACE_SOURCE.
if (instr->opcode == &OPCODE_TRACE_SOURCE_info) {
if (trace_flags_ & TRACE_SOURCE) {
EmitTraceSource(instr);
}
instr = instr->next;
continue;
}
if (!SelectSequence(*this, instr, &new_tail)) {
// No sequence found!
assert_always();
@@ -238,129 +215,12 @@ void X64Emitter::MarkSourceOffset(const Instr* i) {
source_map_count_++;
}
void X64Emitter::EmitTraceSource(const Instr* instr) {
uint64_t trace_base = runtime_->memory()->trace_base();
if (!trace_base || !(trace_flags_ & TRACE_SOURCE)) {
return;
}
// TODO(benvanik): make this a function call to some append fn.
uint8_t dest_reg_0 = instr->flags & 0xFF;
uint8_t dest_reg_1 = instr->flags >> 8;
xdb::protocol::EventType event_type;
size_t event_size = 0;
if (dest_reg_0 == 100) {
event_type = xdb::protocol::EventType::INSTR;
event_size = sizeof(xdb::protocol::InstrEvent);
} else if (dest_reg_1 == 100) {
if (dest_reg_0 & (1 << 7)) {
event_type = xdb::protocol::EventType::INSTR_R16;
event_size = sizeof(xdb::protocol::InstrEventR16);
} else {
event_type = xdb::protocol::EventType::INSTR_R8;
event_size = sizeof(xdb::protocol::InstrEventR8);
}
} else {
if (dest_reg_0 & (1 << 7) && dest_reg_1 & (1 << 7)) {
event_type = xdb::protocol::EventType::INSTR_R16_R16;
event_size = sizeof(xdb::protocol::InstrEventR16R16);
} else if (dest_reg_0 & (1 << 7) && !(dest_reg_1 & (1 << 7))) {
event_type = xdb::protocol::EventType::INSTR_R16_R8;
event_size = sizeof(xdb::protocol::InstrEventR16R8);
} else if (!(dest_reg_0 & (1 << 7)) && dest_reg_1 & (1 << 7)) {
event_type = xdb::protocol::EventType::INSTR_R8_R16;
event_size = sizeof(xdb::protocol::InstrEventR8R16);
} else if (!(dest_reg_0 & (1 << 7)) && !(dest_reg_1 & (1 << 7))) {
event_type = xdb::protocol::EventType::INSTR_R8_R8;
event_size = sizeof(xdb::protocol::InstrEventR8R8);
}
}
assert_not_zero(event_size);
mov(rax, trace_base);
mov(r8d, static_cast<uint32_t>(event_size));
lock();
xadd(qword[rax], r8);
// r8 is now the pointer where we can write our event.
// Write the header, which is the same for everything (pretty much).
// Some event types ignore the dest reg, and that's fine.
uint64_t qword_0 = static_cast<uint64_t>(event_type) |
(static_cast<uint64_t>(dest_reg_0) << 8) |
(instr->src1.offset << 32);
mov(rax, qword_0);
mov(qword[r8], rax);
// Write thread ID.
EmitGetCurrentThreadId();
mov(word[r8 + 2], ax);
switch (event_type) {
default:
case xdb::protocol::EventType::INSTR:
break;
case xdb::protocol::EventType::INSTR_R8:
case xdb::protocol::EventType::INSTR_R16:
if (dest_reg_0 & (1 << 7)) {
EmitTraceSourceAppendValue(instr->src2.value, 8);
} else {
EmitTraceSourceAppendValue(instr->src2.value, 8);
}
break;
case xdb::protocol::EventType::INSTR_R8_R8:
case xdb::protocol::EventType::INSTR_R8_R16:
case xdb::protocol::EventType::INSTR_R16_R8:
case xdb::protocol::EventType::INSTR_R16_R16:
mov(word[r8 + 8], dest_reg_0 | static_cast<uint16_t>(dest_reg_1 << 8));
size_t offset = 8;
if (dest_reg_0 & (1 << 7)) {
EmitTraceSourceAppendValue(instr->src2.value, offset);
offset += 16;
} else {
EmitTraceSourceAppendValue(instr->src2.value, offset);
offset += 8;
}
if (dest_reg_1 & (1 << 7)) {
EmitTraceSourceAppendValue(instr->src3.value, offset);
offset += 16;
} else {
EmitTraceSourceAppendValue(instr->src3.value, offset);
offset += 8;
}
break;
}
}
void X64Emitter::EmitTraceSourceAppendValue(const Value* value,
size_t r8_offset) {
//
}
void X64Emitter::EmitGetCurrentThreadId() {
// rcx must point to context. We could fetch from the stack if needed.
mov(ax, word[rcx + runtime_->frontend()->context_info()->thread_id_offset()]);
}
void X64Emitter::EmitTraceUserCallReturn() {
auto trace_base = runtime_->memory()->trace_base();
if (!trace_base || !(trace_flags_ & TRACE_USER_CALLS)) {
return;
}
mov(rdx, rax);
mov(rax, trace_base);
mov(r8d, static_cast<uint32_t>(sizeof(xdb::protocol::UserCallReturnEvent)));
lock();
xadd(qword[rax], r8);
mov(rax, static_cast<uint64_t>(xdb::protocol::EventType::USER_CALL_RETURN) |
(static_cast<uint64_t>(0) << 8) | (0ull << 32));
mov(qword[r8], rax);
EmitGetCurrentThreadId();
mov(word[r8 + 2], ax);
mov(rax, rdx);
ReloadEDX();
}
void X64Emitter::EmitTraceUserCallReturn() {}
void X64Emitter::DebugBreak() {
// TODO(benvanik): notify debugger.
@@ -628,23 +488,6 @@ void X64Emitter::CallExtern(const hir::Instr* instr,
const FunctionInfo* symbol_info) {
assert_true(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN);
uint64_t trace_base = runtime_->memory()->trace_base();
if (trace_base & trace_flags_ & TRACE_EXTERN_CALLS) {
mov(rax, trace_base);
mov(r8d, static_cast<uint32_t>(sizeof(xdb::protocol::KernelCallEvent)));
lock();
xadd(qword[rax], r8);
// TODO(benvanik): get module/ordinal.
uint32_t module_id = 0;
uint32_t ordinal = 0;
mov(rax, static_cast<uint64_t>(xdb::protocol::EventType::KERNEL_CALL) |
(static_cast<uint64_t>(0) << 8) | (module_id << 16) |
(ordinal));
mov(qword[r8], rax);
EmitGetCurrentThreadId();
mov(word[r8 + 2], ax);
}
if (!symbol_info->extern_handler()) {
CallNative(UndefinedCallExtern, reinterpret_cast<uint64_t>(symbol_info));
} else {
@@ -662,19 +505,6 @@ void X64Emitter::CallExtern(const hir::Instr* instr,
ReloadEDX();
// rax = host return
}
if (trace_base && trace_flags_ & TRACE_EXTERN_CALLS) {
mov(rax, trace_base);
mov(r8d,
static_cast<uint32_t>(sizeof(xdb::protocol::KernelCallReturnEvent)));
lock();
xadd(qword[rax], r8);
mov(rax,
static_cast<uint64_t>(xdb::protocol::EventType::KERNEL_CALL_RETURN) |
(static_cast<uint64_t>(0) << 8) | (0));
mov(qword[r8], rax);
EmitGetCurrentThreadId();
mov(word[r8 + 2], ax);
}
}
void X64Emitter::CallNative(void* fn) {

View File

@@ -183,8 +183,6 @@ class X64Emitter : public Xbyak::CodeGenerator {
protected:
void* Emplace(size_t stack_size);
int Emit(hir::HIRBuilder* builder, size_t& out_stack_size);
void EmitTraceSource(const hir::Instr* instr);
void EmitTraceSourceAppendValue(const hir::Value* value, size_t r8_offset);
void EmitGetCurrentThreadId();
void EmitTraceUserCallReturn();

View File

@@ -12,11 +12,6 @@
#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_string(load_module_map);
DECLARE_string(dump_path);

View File

@@ -10,13 +10,6 @@
#include "xenia/cpu/cpu-private.h"
// Debugging:
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 "

View File

@@ -27,15 +27,6 @@ enum DebugInfoFlags {
DEBUG_INFO_ALL_DISASM = 0xFFFF,
};
enum TraceFlags {
TRACE_NONE = 0,
TRACE_EXTERN_CALLS = (1 << 0),
TRACE_USER_CALLS = (1 << 1),
TRACE_SOURCE = (1 << 2),
TRACE_SOURCE_VALUES = (1 << 3),
TRACE_FUNCTION_GENERATION = (1 << 4),
};
typedef struct SourceMapEntry_s {
uint32_t source_offset; // Original source address/offset.
uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b)

View File

@@ -139,30 +139,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
// DebugBreak();
// TraceInvalidInstruction(i);
}
if (flags & EMIT_TRACE_SOURCE) {
if (flags & EMIT_TRACE_SOURCE_VALUES) {
switch (trace_info_.dest_count) {
case 0:
TraceSource(i.address);
break;
case 1:
TraceSource(i.address, trace_info_.dests[0].reg,
trace_info_.dests[0].value);
break;
case 2:
TraceSource(i.address, trace_info_.dests[0].reg,
trace_info_.dests[0].value, trace_info_.dests[1].reg,
trace_info_.dests[1].value);
break;
default:
assert_unhandled_case(trace_info_.dest_count);
break;
}
} else {
TraceSource(i.address);
}
}
}
return Finalize();

View File

@@ -35,10 +35,6 @@ class PPCHIRBuilder : public hir::HIRBuilder {
enum EmitFlags {
// Emit comment nodes.
EMIT_DEBUG_COMMENTS = 1 << 0,
// Emit TraceSource nodes.
EMIT_TRACE_SOURCE = 1 << 1,
// Emit TraceSource nodes with the resulting values of the operations.
EMIT_TRACE_SOURCE_VALUES = EMIT_TRACE_SOURCE | (1 << 2),
};
int Emit(FunctionInfo* symbol_info, uint32_t flags);

View File

@@ -108,7 +108,7 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
typedef struct {
InstrType* type;
uint64_t address;
uint32_t address;
union {
uint32_t code;

View File

@@ -134,11 +134,6 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
if (debug_info) {
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
}
if (trace_flags & TRACE_SOURCE_VALUES) {
emit_flags |= PPCHIRBuilder::EMIT_TRACE_SOURCE_VALUES;
} else if (trace_flags & TRACE_SOURCE) {
emit_flags |= PPCHIRBuilder::EMIT_TRACE_SOURCE;
}
int result = builder_->Emit(symbol_info, emit_flags);
if (result) {
return result;

View File

@@ -9,7 +9,6 @@
#include "xenia/cpu/function.h"
#include "xdb/protocol.h"
#include "xenia/base/logging.h"
#include "xenia/cpu/debugger.h"
#include "xenia/cpu/symbol_info.h"
@@ -75,18 +74,9 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
int result = 0;
uint64_t trace_base = thread_state->memory()->trace_base();
if (symbol_info_->behavior() == FunctionInfo::BEHAVIOR_EXTERN) {
auto handler = symbol_info_->extern_handler();
if (trace_base && true) {
auto ev = xdb::protocol::KernelCallEvent::Append(trace_base);
ev->type = xdb::protocol::EventType::KERNEL_CALL;
ev->thread_id = thread_state->thread_id();
ev->module_id = 0;
ev->ordinal = 0;
}
if (handler) {
handler(thread_state->context(), symbol_info_->extern_arg0(),
symbol_info_->extern_arg1());
@@ -95,28 +85,8 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
symbol_info_->name().c_str());
result = 1;
}
if (trace_base && true) {
auto ev = xdb::protocol::KernelCallReturnEvent::Append(trace_base);
ev->type = xdb::protocol::EventType::KERNEL_CALL_RETURN;
ev->thread_id = thread_state->thread_id();
}
} else {
if (trace_base && true) {
auto ev = xdb::protocol::UserCallEvent::Append(trace_base);
ev->type = xdb::protocol::EventType::USER_CALL;
ev->call_type = 0; // ?
ev->thread_id = thread_state->thread_id();
ev->address = static_cast<uint32_t>(symbol_info_->address());
}
CallImpl(thread_state, return_address);
if (trace_base && true) {
auto ev = xdb::protocol::UserCallReturnEvent::Append(trace_base);
ev->type = xdb::protocol::EventType::USER_CALL_RETURN;
ev->thread_id = thread_state->thread_id();
}
}
if (original_thread_state != thread_state) {

View File

@@ -640,34 +640,12 @@ void HIRBuilder::Nop() {
i->src1.value = i->src2.value = i->src3.value = NULL;
}
void HIRBuilder::SourceOffset(uint64_t offset) {
void HIRBuilder::SourceOffset(uint32_t offset) {
Instr* i = AppendInstr(OPCODE_SOURCE_OFFSET_info, 0);
i->src1.offset = offset;
i->src2.value = i->src3.value = NULL;
}
void HIRBuilder::TraceSource(uint64_t offset) {
Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, 100 | (100 << 8));
i->src1.offset = offset;
i->set_src2(LoadZero(INT64_TYPE));
i->set_src3(LoadZero(INT64_TYPE));
}
void HIRBuilder::TraceSource(uint64_t offset, uint8_t index, Value* value) {
Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, index | (100 << 8));
i->src1.offset = offset;
i->set_src2(value);
i->set_src3(LoadZero(INT64_TYPE));
}
void HIRBuilder::TraceSource(uint64_t offset, uint8_t index_0, Value* value_0,
uint8_t index_1, Value* value_1) {
Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, index_0 | (index_1 << 8));
i->src1.offset = offset;
i->set_src2(value_0);
i->set_src3(value_1);
}
void HIRBuilder::DebugBreak() {
Instr* i = AppendInstr(OPCODE_DEBUG_BREAK_info, 0);
i->src1.value = i->src2.value = i->src3.value = NULL;

View File

@@ -68,11 +68,7 @@ class HIRBuilder {
void Nop();
void SourceOffset(uint64_t offset);
void TraceSource(uint64_t offset);
void TraceSource(uint64_t offset, uint8_t index, Value* value);
void TraceSource(uint64_t offset, uint8_t index_0, Value* value_0,
uint8_t index_1, Value* value_1);
void SourceOffset(uint32_t offset);
// trace info/etc
void DebugBreak();

View File

@@ -109,7 +109,6 @@ enum Opcode {
OPCODE_COMMENT,
OPCODE_NOP,
OPCODE_SOURCE_OFFSET,
OPCODE_TRACE_SOURCE,
OPCODE_DEBUG_BREAK,
OPCODE_DEBUG_BREAK_TRUE,
OPCODE_TRAP,

View File

@@ -26,12 +26,6 @@ DEFINE_OPCODE(
OPCODE_SIG_X_O,
OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE)
DEFINE_OPCODE(
OPCODE_TRACE_SOURCE,
"trace_source",
OPCODE_SIG_X_O_V_V,
OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE)
DEFINE_OPCODE(
OPCODE_DEBUG_BREAK,
"debug_break",

View File

@@ -72,21 +72,6 @@ int Processor::Setup() {
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 Runtime(memory_, export_resolver_, debug_info_flags, trace_flags);

View File

@@ -11,7 +11,6 @@
#include <gflags/gflags.h>
#include "xdb/protocol.h"
#include "xenia/base/assert.h"
#include "xenia/cpu/frontend/ppc_frontend.h"
#include "xenia/cpu/module.h"
@@ -254,16 +253,6 @@ int Runtime::DemandFunction(FunctionInfo* symbol_info,
}
symbol_info->set_function(function);
auto trace_base = memory()->trace_base();
if (trace_base && trace_flags_ & TRACE_FUNCTION_GENERATION) {
auto ev = xdb::protocol::FunctionCompiledEvent::Append(trace_base);
ev->type = xdb::protocol::EventType::FUNCTION_COMPILED;
ev->flags = 0;
ev->address = static_cast<uint32_t>(symbol_info->address());
ev->length =
static_cast<uint32_t>(symbol_info->end_address() - ev->address);
}
// Before we give the symbol back to the rest, let the debugger know.
debugger_->OnFunctionDefined(symbol_info, function);

View File

@@ -9,7 +9,6 @@
#include "xenia/cpu/thread_state.h"
#include "xdb/protocol.h"
#include "xenia/base/assert.h"
#include "xenia/base/threading.h"
#include "xenia/cpu/runtime.h"
@@ -100,30 +99,5 @@ ThreadState* ThreadState::Get() { return thread_state_; }
uint32_t ThreadState::GetThreadID() { return thread_state_->thread_id_; }
void ThreadState::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));
}
} // namespace cpu
} // namespace xe

View File

@@ -14,12 +14,6 @@
#include "xenia/cpu/thread_state.h"
#include "xenia/memory.h"
namespace xdb {
namespace protocol {
struct Registers;
} // namespace protocol
} // namespace xdb
namespace xe {
namespace cpu {
@@ -50,8 +44,6 @@ class ThreadState {
static ThreadState* Get();
static uint32_t GetThreadID();
void WriteRegisters(xdb::protocol::Registers* registers);
private:
Runtime* runtime_;
Memory* memory_;

View File

@@ -1,79 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/debug_agent.h"
#include <gflags/gflags.h>
#include "xenia/base/logging.h"
#include "xenia/base/memory.h"
#include "xenia/base/string.h"
DEFINE_string(trace_file, "", "Trace to the given file.");
DEFINE_uint64(trace_capacity, 0x40000000, "Trace file capacity to allocate.");
namespace xe {
DebugAgent::DebugAgent(Emulator* emulator)
: emulator_(emulator),
file_(nullptr),
file_mapping_(nullptr),
trace_base_(0) {}
DebugAgent::~DebugAgent() {
if (trace_base_) {
UnmapViewOfFile(trace_base_);
}
CloseHandle(file_mapping_);
CloseHandle(file_);
}
int DebugAgent::Initialize() {
if (!FLAGS_trace_file.empty()) {
if (SetupTracing(FLAGS_trace_file, FLAGS_trace_capacity)) {
XELOGE("Failed to setup tracing - out of disk space?");
return 1;
}
}
return 0;
}
int DebugAgent::SetupTracing(const std::string& trace_file, uint64_t capacity) {
auto file_path = xe::to_wstring(trace_file);
file_ = CreateFile(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, nullptr);
if (!file_) {
XELOGE("Could not open trace file for writing");
return 1;
}
file_mapping_ = CreateFileMapping(
file_, nullptr, PAGE_READWRITE, static_cast<uint32_t>(capacity >> 32),
static_cast<uint32_t>(capacity), L"Local\\xenia_xdb_trace");
if (!file_mapping_) {
XELOGE("Could not create trace file mapping - out of disk space?");
return 1;
}
trace_base_ = MapViewOfFile(file_mapping_, FILE_MAP_WRITE, 0, 0, 0);
if (!trace_base_) {
XELOGE("Could not map view of trace file - out of disk space?");
return 1;
}
// Store initial trace base.
xe::store<uint64_t>(trace_base_, trace_base() + 8);
return 0;
}
} // namespace xe

View File

@@ -1,44 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_DEBUG_AGENT_H_
#define XENIA_DEBUG_AGENT_H_
#include <string>
#include "xenia/base/platform.h"
namespace xe {
class Emulator;
class DebugAgent {
public:
DebugAgent(Emulator* emulator);
~DebugAgent();
uint64_t trace_base() const {
return reinterpret_cast<uint64_t>(trace_base_);
}
int Initialize();
private:
int SetupTracing(const std::string& trace_file, uint64_t capacity);
Emulator* emulator_;
HANDLE file_;
HANDLE file_mapping_;
void* trace_base_;
};
} // namespace xe
#endif // XENIA_DEBUG_AGENT_H_

View File

@@ -9,7 +9,6 @@
#include "xenia/emulator.h"
#include "xdb/protocol.h"
#include "xenia/apu/apu.h"
#include "xenia/base/assert.h"
#include "xenia/base/string.h"
@@ -39,13 +38,6 @@ Emulator::Emulator(const std::wstring& command_line)
Emulator::~Emulator() {
// Note that we delete things in the reverse order they were initialized.
auto ev = xdb::protocol::ProcessExitEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::PROCESS_EXIT;
}
debug_agent_.reset();
xam_.reset();
xboxkrnl_.reset();
kernel_state_.reset();
@@ -75,19 +67,12 @@ X_STATUS Emulator::Setup() {
main_window_ = std::make_unique<ui::MainWindow>(this);
main_window_->Start();
debug_agent_.reset(new DebugAgent(this));
result = debug_agent_->Initialize();
if (result) {
return result;
}
// Create memory system first, as it is required for other systems.
memory_ = std::make_unique<Memory>();
result = memory_->Initialize();
if (result) {
return result;
}
memory_->set_trace_base(debug_agent_->trace_base());
// Shared export resolver used to attach and query for HLE exports.
export_resolver_ = std::make_unique<xe::cpu::ExportResolver>();
@@ -200,15 +185,6 @@ X_STATUS Emulator::LaunchSTFSTitle(const std::wstring& path) {
X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
const std::string& module_path) {
auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::PROCESS_START;
ev->membase = reinterpret_cast<uint64_t>(memory()->virtual_membase());
auto path_length =
xe::to_string(path).copy(ev->launch_path, sizeof(ev->launch_path) - 1);
ev->launch_path[path_length] = 0;
}
return xboxkrnl_->LaunchModule(module_path.c_str());
}

View File

@@ -12,7 +12,6 @@
#include <string>
#include "xenia/debug_agent.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/memory.h"
#include "xenia/ui/main_window.h"
@@ -55,8 +54,6 @@ class Emulator {
Memory* memory() const { return memory_.get(); }
DebugAgent* debug_agent() const { return debug_agent_.get(); }
cpu::Processor* processor() const { return processor_.get(); }
apu::AudioSystem* audio_system() const { return audio_system_.get(); }
gpu::GraphicsSystem* graphics_system() const {
@@ -89,8 +86,6 @@ class Emulator {
std::unique_ptr<Memory> memory_;
std::unique_ptr<DebugAgent> debug_agent_;
std::unique_ptr<cpu::Processor> processor_;
std::unique_ptr<apu::AudioSystem> audio_system_;
std::unique_ptr<gpu::GraphicsSystem> graphics_system_;

View File

@@ -9,8 +9,6 @@
#include "xenia/kernel/objects/xmodule.h"
#include "xdb/protocol.h"
namespace xe {
namespace kernel {
@@ -32,22 +30,10 @@ XModule::XModule(KernelState* kernel_state, const std::string& path)
}
XModule::~XModule() {
auto ev = xdb::protocol::ModuleUnloadEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::MODULE_UNLOAD;
ev->module_id = handle();
}
kernel_state_->UnregisterModule(this);
}
void XModule::OnLoad() {
auto ev = xdb::protocol::ModuleLoadEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::MODULE_LOAD;
ev->module_id = handle();
}
kernel_state_->RegisterModule(this);
}

View File

@@ -9,7 +9,6 @@
#include "xenia/kernel/objects/xthread.h"
#include "xdb/protocol.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/threading.h"
@@ -63,12 +62,6 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
}
XThread::~XThread() {
auto ev = xdb::protocol::ThreadExitEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::THREAD_EXIT;
ev->thread_id = handle();
}
// Unregister first to prevent lookups while deleting.
kernel_state_->UnregisterThread(this);
@@ -208,13 +201,6 @@ X_STATUS XThread::Create() {
SetAffinity(proc_mask);
}
auto ev = xdb::protocol::ThreadCreateEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::THREAD_CREATE;
ev->thread_id = handle();
thread_state_->WriteRegisters(&ev->registers);
}
module->Release();
return X_STATUS_SUCCESS;
}

View File

@@ -121,7 +121,6 @@ Memory::Memory()
physical_membase_(nullptr),
reserve_address_(0),
reserve_value_(0),
trace_base_(0),
mapping_(0),
mapping_base_(nullptr) {
system_page_size_ = uint32_t(xe::page_size());

View File

@@ -76,9 +76,6 @@ class Memory {
inline uint64_t* reserve_address() { return &reserve_address_; }
inline uint64_t* reserve_value() { return &reserve_value_; }
uint64_t trace_base() const { return trace_base_; }
void set_trace_base(uint64_t value) { trace_base_ = value; }
// TODO(benvanik): make poly memory utils for these.
void Zero(uint32_t address, uint32_t size);
void Fill(uint32_t address, uint32_t size, uint8_t value);
@@ -118,7 +115,6 @@ class Memory {
uint8_t* physical_membase_;
uint64_t reserve_address_;
uint64_t reserve_value_;
uint64_t trace_base_;
HANDLE mapping_;
uint8_t* mapping_base_;

View File

@@ -1,8 +1,6 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'debug_agent.cc',
'debug_agent.h',
'emulator.cc',
'emulator.h',
'memory.cc',