Skeleton of the debugger host.

This commit is contained in:
Ben Vanik 2013-02-01 05:37:42 -08:00
parent b6a9dfe7e0
commit c2fbafdc28
20 changed files with 679 additions and 2 deletions

42
debugger/debugger.js Normal file
View File

@ -0,0 +1,42 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
// TODO(benvanik): closure or something fancy
var DebugClient = function(endpoint) {
/**
* Target websocket endpoint.
* @type {string}
* @private
*/
this.endpoint_ = endpoint;
/**
* Connected socket.
* @type {!WebSocket}
* @private
*/
this.socket_ = new WebSocket(endpoint, []);
this.socket_.onopen = (function() {
console.log('opened');
}).bind(this);
this.socket_.onerror = (function(e) {
console.log('error', e);
}).bind(this);
this.socket_.onmessage = (function(e) {
console.log('message', e.data);
}).bind(this);
}
var client = new DebugClient('ws://127.0.0.1:6200');

9
debugger/index.html Normal file
View File

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<title>Xenia Debugger</title>
<script src="debugger.js"></script>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,38 @@
/**
******************************************************************************
* 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_KERNEL_DBG_CLIENT_H_
#define XENIA_KERNEL_DBG_CLIENT_H_
#include <xenia/common.h>
#include <xenia/core.h>
namespace xe {
namespace dbg {
class Client {
public:
Client();
virtual ~Client();
void Write(const uint8_t* buffer, const size_t length);
virtual void Write(const uint8_t** buffers, const size_t* lengths,
size_t count) = 0;
protected:
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_CLIENT_H_

View File

@ -0,0 +1,46 @@
/**
******************************************************************************
* 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_KERNEL_DBG_CONTENT_SOURCE_H_
#define XENIA_KERNEL_DBG_CONTENT_SOURCE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/dbg/client.h>
namespace xe {
namespace dbg {
class ContentSource {
public:
enum Type {
kTypeIndexed,
};
ContentSource(Type type);
virtual ~ContentSource();
Type type();
virtual int DispatchRequest(Client* client,
const uint8_t* data, size_t length) = 0;
protected:
Type type_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_CONTENT_SOURCE_H_

View File

@ -0,0 +1,54 @@
/**
******************************************************************************
* 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_KERNEL_DBG_DEBUGGER_H_
#define XENIA_KERNEL_DBG_DEBUGGER_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <map>
namespace xe {
namespace dbg {
class Client;
class ContentSource;
class Listener;
class Debugger {
public:
Debugger(xe_pal_ref pal);
virtual ~Debugger();
void RegisterContentSource(std::string& name, ContentSource* content_source);
int Startup();
private:
int DispatchRequest(Client* client, const char* source_name,
const uint8_t* data, size_t length);
friend class Client;
private:
xe_pal_ref pal_;
auto_ptr<Listener> listener_;
std::map<char*, ContentSource*> content_sources_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_DEBUGGER_H_

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_KERNEL_DBG_INDEXED_CONTENT_SOURCE_H_
#define XENIA_KERNEL_DBG_INDEXED_CONTENT_SOURCE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/dbg/content_source.h>
namespace xe {
namespace dbg {
class Client;
class IndexedContentSource : public ContentSource {
public:
IndexedContentSource();
virtual ~IndexedContentSource();
int DispatchRequest(Client* client, const uint8_t* data, size_t length);
protected:
virtual int RequestIndex(Client* client, uint64_t req_id) = 0;
virtual int RequestRange(Client* client, uint64_t req_id,
uint64_t start_index, uint64_t end_index) = 0;
virtual int RequestEntry(Client* client, uint64_t req_id, uint64_t index) = 0;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_INDEXED_CONTENT_SOURCE_H_

View File

@ -15,7 +15,6 @@
#include <xenia/core.h>
#include <xenia/gpu.h>
#include <xenia/kernel.h>
int some_function(int x);
#include <xenia/dbg/debugger.h>
#endif // XENIA_H_

27
src/dbg/client.cc Normal file
View File

@ -0,0 +1,27 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include <xenia/dbg/client.h>
using namespace xe;
using namespace xe::dbg;
Client::Client() {
}
Client::~Client() {
}
void Client::Write(const uint8_t* buffer, const size_t length) {
const uint8_t* buffers[] = {buffer};
const size_t lengths[] = {length};
Write(buffers, lengths, 1);
}

27
src/dbg/content_source.cc Normal file
View File

@ -0,0 +1,27 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include <xenia/dbg/content_source.h>
using namespace xe;
using namespace xe::dbg;
ContentSource::ContentSource(Type type) :
type_(type) {
}
ContentSource::~ContentSource() {
}
ContentSource::Type ContentSource::type() {
return type_;
}

80
src/dbg/debugger.cc Normal file
View File

@ -0,0 +1,80 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include <xenia/dbg/debugger.h>
#include <gflags/gflags.h>
#include <xenia/dbg/content_source.h>
#include "dbg/ws_listener.h"
using namespace xe;
using namespace xe::dbg;
DEFINE_bool(wait_for_debugger, false,
"Whether to wait for the debugger to attach before launching.");
DEFINE_int32(remote_debug_port, 6200,
"Websocket port to listen for debugger connections on.");
Debugger::Debugger(xe_pal_ref pal) {
pal_ = xe_pal_retain(pal);
listener_ = auto_ptr<Listener>(new WsListener(
pal_, FLAGS_remote_debug_port));
}
Debugger::~Debugger() {
for (std::map<char*, ContentSource*>::iterator it = content_sources_.begin();
it != content_sources_.end(); ++it) {
xe_free(it->first);
delete it->second;
}
content_sources_.clear();
xe_pal_release(pal_);
}
void Debugger::RegisterContentSource(std::string& name,
ContentSource* content_source) {
content_sources_.insert(std::pair<char*, ContentSource*>(
xestrdupa(name.c_str()), content_source));
}
int Debugger::Startup() {
// Start listener.
// This may launch a thread and such.
if (listener_->Setup()) {
return 1;
}
// If desired, wait until the first client connects.
if (FLAGS_wait_for_debugger) {
XELOGI(XT("Waiting for debugger on port %d..."), FLAGS_remote_debug_port);
if (listener_->WaitForClient()) {
return 1;
}
XELOGI(XT("Debugger attached, continuing..."));
}
return 0;
}
int Debugger::DispatchRequest(Client* client, const char* source_name,
const uint8_t* data, size_t length) {
std::map<char*, ContentSource*>::iterator it =
content_sources_.find((char*)source_name);
if (it == content_sources_.end()) {
return 1;
}
return it->second->DispatchRequest(client, data, length);
}

View File

@ -0,0 +1,28 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include <xenia/dbg/indexed_content_source.h>
using namespace xe;
using namespace xe::dbg;
IndexedContentSource::IndexedContentSource() :
ContentSource(kTypeIndexed) {
}
IndexedContentSource::~IndexedContentSource() {
}
int IndexedContentSource::DispatchRequest(Client* client,
const uint8_t* data, size_t length) {
//
return 1;
}

23
src/dbg/listener.cc Normal file
View File

@ -0,0 +1,23 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include "dbg/listener.h"
using namespace xe;
using namespace xe::dbg;
Listener::Listener(xe_pal_ref pal) {
pal_ = xe_pal_retain(pal);
}
Listener::~Listener() {
xe_pal_release(pal_);
}

38
src/dbg/listener.h Normal file
View File

@ -0,0 +1,38 @@
/**
******************************************************************************
* 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_KERNEL_DBG_LISTENER_H_
#define XENIA_KERNEL_DBG_LISTENER_H_
#include <xenia/common.h>
#include <xenia/core.h>
namespace xe {
namespace dbg {
class Listener {
public:
Listener(xe_pal_ref pal);
virtual ~Listener();
virtual int Setup() = 0;
virtual int WaitForClient() = 0;
protected:
xe_pal_ref pal_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_LISTENER_H_

12
src/dbg/sources.gypi Normal file
View File

@ -0,0 +1,12 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'client.cc',
'content_source.cc',
'debugger.cc',
'indexed_content_source.cc',
'listener.cc',
'ws_client.cc',
'ws_listener.cc',
],
}

29
src/dbg/ws_client.cc Normal file
View File

@ -0,0 +1,29 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include "dbg/ws_client.h"
using namespace xe;
using namespace xe::dbg;
WsClient::WsClient(int socket_id) :
Client(),
socket_id_(socket_id) {
}
WsClient::~WsClient() {
close(socket_id_);
}
void WsClient::Write(const uint8_t** buffers, const size_t* lengths,
size_t count) {
//
}

40
src/dbg/ws_client.h Normal file
View File

@ -0,0 +1,40 @@
/**
******************************************************************************
* 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_KERNEL_DBG_WS_CLIENT_H_
#define XENIA_KERNEL_DBG_WS_CLIENT_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/dbg/client.h>
namespace xe {
namespace dbg {
class WsClient : public Client {
public:
WsClient(int socket_id);
virtual ~WsClient();
virtual void Write(const uint8_t** buffers, const size_t* lengths,
size_t count);
protected:
int socket_id_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_WS_CLIENT_H_

86
src/dbg/ws_listener.cc Normal file
View File

@ -0,0 +1,86 @@
/**
******************************************************************************
* 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. *
******************************************************************************
*/
#include "dbg/ws_listener.h"
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include "dbg/ws_client.h"
using namespace xe;
using namespace xe::dbg;
WsListener::WsListener(xe_pal_ref pal, uint32_t port) :
Listener(pal),
port_(port) {
}
WsListener::~WsListener() {
if (socket_id_) {
close(socket_id_);
}
}
int WsListener::Setup() {
socket_id_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socket_id_ < 1) {
return 1;
}
int opt_value;
opt_value = 1;
setsockopt(socket_id_, SOL_SOCKET, SO_KEEPALIVE,
&opt_value, sizeof(opt_value));
opt_value = 0;
setsockopt(socket_id_, IPPROTO_TCP, TCP_NODELAY,
&opt_value, sizeof(opt_value));
struct sockaddr_in socket_addr;
socket_addr.sin_family = AF_INET;
socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);
socket_addr.sin_port = htons(port_);
if (bind(socket_id_, (struct sockaddr*)&socket_addr,
sizeof(socket_addr)) < 0) {
return 1;
}
if (listen(socket_id_, 5) < 0) {
close(socket_id_);
return 1;
}
return 0;
}
int WsListener::WaitForClient() {
// Accept the first connection we get.
struct sockaddr_in client_addr;
socklen_t client_count = sizeof(client_addr);
int client_socket_id = accept(socket_id_, (struct sockaddr*)&client_addr,
&client_count);
if (client_socket_id < 0) {
return 1;
}
int client_ip = client_addr.sin_addr.s_addr;
char client_ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_ip, client_ip_str, XECOUNT(client_ip_str));
XELOGI(XT("Debugger connected from %s"), client_ip_str);
//WsClient* client = new WsClient(client_socket_id);
// TODO(benvanik): add to list for cleanup
return 0;
}

42
src/dbg/ws_listener.h Normal file
View File

@ -0,0 +1,42 @@
/**
******************************************************************************
* 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_KERNEL_DBG_WS_LISTENER_H_
#define XENIA_KERNEL_DBG_WS_LISTENER_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include "dbg/listener.h"
namespace xe {
namespace dbg {
class WsListener : public Listener {
public:
WsListener(xe_pal_ref pal, uint32_t port);
virtual ~WsListener();
virtual int Setup();
virtual int WaitForClient();
protected:
uint32_t port_;
int socket_id_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_WS_LISTENER_H_

View File

@ -14,6 +14,7 @@
using namespace xe;
using namespace xe::cpu;
using namespace xe::dbg;
using namespace xe::kernel;
@ -34,6 +35,7 @@ private:
xe_memory_ref memory_;
shared_ptr<Processor> processor_;
shared_ptr<Runtime> runtime_;
shared_ptr<Debugger> debugger_;
};
Run::Run() {
@ -50,6 +52,8 @@ int Run::Setup() {
pal_ = xe_pal_create(pal_options);
XEEXPECTNOTNULL(pal_);
debugger_ = shared_ptr<Debugger>(new Debugger(pal_));
xe_memory_options_t memory_options;
xe_zero_struct(&memory_options, sizeof(memory_options));
memory_ = xe_memory_create(pal_, memory_options);
@ -86,6 +90,13 @@ int Run::Launch(const xechar_t* path) {
return 1;
}
// Run the debugger.
// This may pause waiting for connections.
if (debugger_->Startup()) {
XELOGE(XT("Debugger failed to startup"));
return 1;
}
// Launch based on file type.
// This is a silly guess based on file extension.
// NOTE: the runtime launch routine will wait until the module exits.

View File

@ -34,6 +34,7 @@
'includes': [
'src/xenia/sources.gypi',
'src/core/sources.gypi',
'src/dbg/sources.gypi',
],
},