Initialize debugger with the VM instance
This commit is contained in:
parent
79177d17e5
commit
c7ff2c784c
3 changed files with 71 additions and 68 deletions
119
src/debug.cpp
119
src/debug.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
|
|
||||||
GDBStub::GDBStub(int port) : server_fd(-1), client_fd(-1), running(false) {
|
GDBStub::GDBStub(VM &vm, int port)
|
||||||
|
: server_fd(-1), client_fd(-1), running(false), vm(vm) {
|
||||||
server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (server_fd == -1) {
|
if (server_fd == -1) {
|
||||||
throw std::runtime_error("Failed to create socket.");
|
throw std::runtime_error("Failed to create socket.");
|
||||||
|
@ -11,7 +12,8 @@ GDBStub::GDBStub(int port) : server_fd(-1), client_fd(-1), running(false) {
|
||||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
server_addr.sin_port = htons(port);
|
server_addr.sin_port = htons(port);
|
||||||
|
|
||||||
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
|
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) ==
|
||||||
|
-1) {
|
||||||
throw std::runtime_error("Failed to bind socket.");
|
throw std::runtime_error("Failed to bind socket.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +21,8 @@ GDBStub::GDBStub(int port) : server_fd(-1), client_fd(-1), running(false) {
|
||||||
throw std::runtime_error("Failed to listen on socket.");
|
throw std::runtime_error("Failed to listen on socket.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Waiting for GDB connection on port " << port << "..." << std::endl;
|
std::cout << "Waiting for GDB connection on port " << port << "..."
|
||||||
|
<< std::endl;
|
||||||
client_fd = accept(server_fd, nullptr, nullptr);
|
client_fd = accept(server_fd, nullptr, nullptr);
|
||||||
if (client_fd == -1) {
|
if (client_fd == -1) {
|
||||||
throw std::runtime_error("Failed to accept connection.");
|
throw std::runtime_error("Failed to accept connection.");
|
||||||
|
@ -49,9 +52,7 @@ void GDBStub::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDBStub::stop() {
|
void GDBStub::stop() { running = false; }
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GDBStub::send_ack() {
|
void GDBStub::send_ack() {
|
||||||
if (send(client_fd, "+", 1, 0) == -1) {
|
if (send(client_fd, "+", 1, 0) == -1) {
|
||||||
|
@ -78,7 +79,8 @@ void GDBStub::send_packet(const std::string &packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
response << '$' << packet << '#' << std::hex << std::setfill('0') << std::setw(2) << (checksum & 0xFF);
|
response << '$' << packet << '#' << std::hex << std::setfill('0')
|
||||||
|
<< std::setw(2) << (checksum & 0xFF);
|
||||||
|
|
||||||
const std::string response_str = response.str();
|
const std::string response_str = response.str();
|
||||||
if (send(client_fd, response_str.c_str(), response_str.size(), 0) == -1) {
|
if (send(client_fd, response_str.c_str(), response_str.size(), 0) == -1) {
|
||||||
|
@ -121,68 +123,69 @@ std::string GDBStub::receive_packet() {
|
||||||
|
|
||||||
void GDBStub::handle_packet(const std::string &packet) {
|
void GDBStub::handle_packet(const std::string &packet) {
|
||||||
switch (packet[0]) {
|
switch (packet[0]) {
|
||||||
case '?':
|
case '?':
|
||||||
send_packet("S05"); // TODO: real stop reason
|
send_packet("S05"); // TODO: real stop reason
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g': // Read all registers
|
case 'g': // Read all registers
|
||||||
send_packet(read_registers());
|
send_packet(read_registers());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p': {
|
case 'p': {
|
||||||
// Getting specific register
|
// Getting specific register
|
||||||
int regnum = std::stoi(packet.substr(1), nullptr, 16);
|
int regnum = std::stoi(packet.substr(1), nullptr, 16);
|
||||||
|
|
||||||
uint32_t reg_value = 0;
|
uint32_t reg_value = 0;
|
||||||
|
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
response << std::hex << std::setfill('0') << std::setw(8) << reg_value;
|
response << std::hex << std::setfill('0') << std::setw(8) << reg_value;
|
||||||
|
|
||||||
send_packet(response.str());
|
send_packet(response.str());
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 'G':
|
|
||||||
send_packet("OK"); // TODO: write registers
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm': {
|
|
||||||
size_t addr, length;
|
|
||||||
if (parse_memory_request(packet, addr, length)) {
|
|
||||||
send_packet(read_memory(addr, length));
|
|
||||||
} else {
|
|
||||||
send_packet("E01"); // Error
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'M':
|
case 'G':
|
||||||
send_packet("OK"); // TODO: write memory
|
send_packet("OK"); // TODO: write registers
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'm': {
|
||||||
send_packet("S05"); // TODO: continue execution
|
size_t addr, length;
|
||||||
break;
|
if (parse_memory_request(packet, addr, length)) {
|
||||||
|
send_packet(read_memory(addr, length));
|
||||||
case 's':
|
} else {
|
||||||
send_packet("S05"); // TODO: step execution
|
send_packet("E01"); // Error
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
case 'q':
|
|
||||||
if (packet.find("qSupported") == 0) {
|
|
||||||
send_packet("PacketSize=4096"); // Example capability
|
|
||||||
} else {
|
|
||||||
send_packet(""); // Empty response
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
case 'M':
|
||||||
send_packet(""); // Unsupported packet
|
send_packet("OK"); // TODO: write memory
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
send_packet("S05"); // TODO: continue execution
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
send_packet("S05"); // TODO: step execution
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
if (packet.find("qSupported") == 0) {
|
||||||
|
send_packet("PacketSize=4096"); // Example capability
|
||||||
|
} else {
|
||||||
|
send_packet(""); // Empty response
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
send_packet(""); // Unsupported packet
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDBStub::parse_memory_request(const std::string &packet, size_t &addr, size_t &length) {
|
bool GDBStub::parse_memory_request(const std::string &packet, size_t &addr,
|
||||||
|
size_t &length) {
|
||||||
size_t comma_pos = packet.find(',');
|
size_t comma_pos = packet.find(',');
|
||||||
if (comma_pos == std::string::npos) {
|
if (comma_pos == std::string::npos) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -200,7 +203,7 @@ bool GDBStub::parse_memory_request(const std::string &packet, size_t &addr, size
|
||||||
std::string GDBStub::read_registers() {
|
std::string GDBStub::read_registers() {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
out << std::string(8, '0'); // TODO: stub
|
out << std::string(8, '0'); // TODO: stub
|
||||||
}
|
}
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
@ -208,7 +211,7 @@ std::string GDBStub::read_registers() {
|
||||||
std::string GDBStub::read_memory(size_t addr, size_t length) {
|
std::string GDBStub::read_memory(size_t addr, size_t length) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
for (size_t i = 0; i < length; ++i) {
|
for (size_t i = 0; i < length; ++i) {
|
||||||
out << "00"; // TODO: stub
|
out << "00"; // TODO: stub
|
||||||
}
|
}
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class GDBStub {
|
class GDBStub {
|
||||||
public:
|
public:
|
||||||
GDBStub(int port);
|
GDBStub(VM &vm, int port);
|
||||||
~GDBStub();
|
~GDBStub();
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
@ -47,4 +47,6 @@ class GDBStub {
|
||||||
std::string read_registers();
|
std::string read_registers();
|
||||||
|
|
||||||
std::string read_memory(size_t addr, size_t length);
|
std::string read_memory(size_t addr, size_t length);
|
||||||
|
|
||||||
|
VM &vm;
|
||||||
};
|
};
|
||||||
|
|
16
src/rve.cpp
16
src/rve.cpp
|
@ -1,16 +1,14 @@
|
||||||
#include "vm.hpp"
|
|
||||||
#include "debug.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "debug.hpp"
|
||||||
|
#include "vm.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const size_t MEMORY_SIZE = 128*1024;
|
const size_t MEMORY_SIZE = 128 * 1024;
|
||||||
|
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
std::string program_filename = "";
|
std::string program_filename = "";
|
||||||
|
@ -39,7 +37,7 @@ int main(int argc, char* argv[]) {
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
try {
|
try {
|
||||||
vm.eval();
|
vm.eval();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << "Emulator error: " << e.what() << std::endl;
|
std::cerr << "Emulator error: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +48,7 @@ int main(int argc, char* argv[]) {
|
||||||
} else {
|
} else {
|
||||||
// to debug, do: "set debug remote 1" in gdb
|
// to debug, do: "set debug remote 1" in gdb
|
||||||
// and then "target remote :1234"
|
// and then "target remote :1234"
|
||||||
GDBStub stub(1234);
|
GDBStub stub(vm, 1234);
|
||||||
stub.run();
|
stub.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue