Routing messages to debug targets.

This commit is contained in:
Ben Vanik 2013-12-22 00:51:50 -08:00
parent 88c8220951
commit a631ada0f7
7 changed files with 107 additions and 12 deletions

View File

@ -9,6 +9,8 @@
#include <xenia/cpu/processor.h>
#include <jansson.h>
#include <xenia/emulator.h>
#include <xenia/cpu/xenon_memory.h>
#include <xenia/cpu/xenon_runtime.h>
@ -51,11 +53,16 @@ Processor::Processor(Emulator* emulator) :
emulator_(emulator), export_resolver_(emulator->export_resolver()),
runtime_(0), memory_(emulator->memory()),
interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL),
interrupt_thread_block_(0) {
interrupt_thread_block_(0),
DebugTarget(emulator->debug_server()) {
InitializeIfNeeded();
emulator_->debug_server()->AddTarget("cpu", this);
}
Processor::~Processor() {
emulator_->debug_server()->RemoveTarget("cpu");
if (interrupt_thread_block_) {
memory_->HeapFree(interrupt_thread_block_, 2048);
delete interrupt_thread_state_;
@ -158,3 +165,9 @@ uint64_t Processor::ExecuteInterrupt(
xe_mutex_unlock(interrupt_thread_lock_);
return result;
}
json_t* Processor::OnDebugRequest(
const char* command, json_t* request, bool& succeeded) {
succeeded = true;
return json_null();
}

View File

@ -10,8 +10,9 @@
#ifndef XENIA_CPU_PROCESSOR_H_
#define XENIA_CPU_PROCESSOR_H_
#include <xenia/core.h>
#include <alloy/runtime/register_access.h>
#include <xenia/core.h>
#include <xenia/debug/debug_target.h>
#include <vector>
@ -31,7 +32,7 @@ using RegisterReadCallback = alloy::runtime::RegisterReadCallback;
using RegisterWriteCallback = alloy::runtime::RegisterWriteCallback;
class Processor {
class Processor : public debug::DebugTarget {
public:
Processor(Emulator* emulator);
~Processor();
@ -55,6 +56,9 @@ public:
uint64_t ExecuteInterrupt(
uint32_t cpu, uint64_t address, uint64_t arg0, uint64_t arg1);
virtual json_t* OnDebugRequest(
const char* command, json_t* request, bool& succeeded);
private:
Emulator* emulator_;
ExportResolver* export_resolver_;

View File

@ -106,6 +106,25 @@ void DebugServer::Shutdown() {
xe_mutex_unlock(lock_);
}
void DebugServer::AddTarget(const char* name, DebugTarget* target) {
xe_mutex_lock(lock_);
targets_[name] = target;
xe_mutex_unlock(lock_);
}
void DebugServer::RemoveTarget(const char* name) {
xe_mutex_lock(lock_);
targets_[name] = NULL;
xe_mutex_unlock(lock_);
}
DebugTarget* DebugServer::GetTarget(const char* name) {
xe_mutex_lock(lock_);
DebugTarget* target = targets_[name];
xe_mutex_unlock(lock_);
return target;
}
int DebugServer::WaitForClient() {
while (!has_clients()) {
WaitForSingleObject(client_event_, INFINITE);

View File

@ -18,6 +18,7 @@
XEDECLARECLASS1(xe, Emulator);
XEDECLARECLASS2(xe, debug, DebugClient);
XEDECLARECLASS2(xe, debug, DebugTarget);
XEDECLARECLASS2(xe, debug, Protocol);
@ -38,6 +39,10 @@ public:
int BeforeEntry();
void Shutdown();
void AddTarget(const char* name, DebugTarget* target);
void RemoveTarget(const char* name);
DebugTarget* GetTarget(const char* name);
int WaitForClient();
private:
@ -51,6 +56,8 @@ private:
std::vector<Protocol*> protocols_;
xe_mutex_t* lock_;
typedef std::unordered_map<std::string, DebugTarget*> TargetMap;
TargetMap targets_;
std::vector<DebugClient*> clients_;
HANDLE client_event_;
};

View File

@ -0,0 +1,45 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_DEBUG_DEBUG_TARGET_H_
#define XENIA_DEBUG_DEBUG_TARGET_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/debug/debug_server.h>
struct json_t;
namespace xe {
namespace debug {
class DebugTarget {
public:
DebugTarget(DebugServer* debug_server) :
debug_server_(debug_server) {}
virtual ~DebugTarget() {}
DebugServer* debug_server() const { return debug_server_; }
virtual json_t* OnDebugRequest(
const char* command, json_t* request, bool& succeeded) = 0;
protected:
DebugServer* debug_server_;
};
} // namespace debug
} // namespace xe
#endif // XENIA_DEBUG_DEBUG_TARGET_H_

View File

@ -15,6 +15,7 @@
#include <xenia/emulator.h>
#include <xenia/debug/debug_server.h>
#include <xenia/debug/debug_target.h>
#include <xenia/debug/protocols/ws/simple_sha1.h>
#include <xenia/kernel/xboxkrnl/kernel_state.h>
#include <xenia/kernel/xboxkrnl/xboxkrnl_module.h>
@ -494,17 +495,22 @@ json_t* WSClient::HandleMessage(const char* command, json_t* request,
// Get target.
char target_name[16] = { 0 };
const char* dot = xestrchra(command, '.');
if (dot) {
if (dot - command > XECOUNT(target_name)) {
return NULL;
}
xestrncpya(target_name, XECOUNT(target_name),
command, dot - command);
if (!dot) {
return json_string("No debug target specified.");
}
if (dot - command > XECOUNT(target_name)) {
return NULL;
}
xestrncpya(target_name, XECOUNT(target_name),
command, dot - command);
const char* sub_command = command + (dot - command + 1);
// Lookup target and dispatch.
// Lookup target.
DebugTarget* target = debug_server_->GetTarget(target_name);
if (!target) {
return json_string("Unknown debug target prefix.");
}
succeeded = true;
return json_null();
// Dispatch.
return target->OnDebugRequest(sub_command, request, succeeded);
}

View File

@ -5,6 +5,7 @@
'debug_client.h',
'debug_server.cc',
'debug_server.h',
'debug_target.h',
'protocol.cc',
'protocol.h',
],