Implement reporting current file path to GDB

This commit is contained in:
Konstantin Nazarov 2024-12-10 17:49:19 +00:00
parent 0c8d1bf257
commit 9707f1a7bf
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
5 changed files with 29 additions and 6 deletions

View file

@ -55,7 +55,6 @@ The program would load, and stop at first instruction. It will then prompt you t
Then run `riscv32-none-elf-gdb`, and in the gdb prompt, type: Then run `riscv32-none-elf-gdb`, and in the gdb prompt, type:
``` ```
file ../example/example
target remote :1234 target remote :1234
``` ```

View file

@ -196,7 +196,24 @@ void GDBStub::handle_packet(const std::string &packet) {
case 'q': case 'q':
if (packet.find("qSupported") == 0) { if (packet.find("qSupported") == 0) {
send_packet("PacketSize=4096"); // Example capability send_packet("PacketSize=4096;qXfer:exec-file:read+");
} else if (packet.find("qXfer:exec-file:read:") == 0) {
size_t start = packet.find("::") + 2;
size_t end = packet.find(",", start);
size_t offset =
std::stoul(packet.substr(start, end - start), nullptr, 16);
size_t length = std::stoul(packet.substr(end + 1), nullptr, 16);
std::string exec_file_path = vm.get_file_path();
std::string response;
if (offset < exec_file_path.size()) {
size_t read_length = std::min(length, exec_file_path.size() - offset);
response = "m" + exec_file_path.substr(offset, read_length);
} else {
response = "l"; // No more data
}
send_packet(response);
} else { } else {
send_packet(""); // Empty response send_packet(""); // Empty response
} }

View file

@ -1,6 +1,7 @@
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <filesystem>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -18,7 +19,7 @@ int main(int argc, char *argv[]) {
if (std::string(argv[i]) == "--debug") if (std::string(argv[i]) == "--debug")
debug = true; debug = true;
else else
program_filename = argv[i]; program_filename = std::filesystem::absolute(argv[i]);
} }
if (program_filename == "") { if (program_filename == "") {
std::cerr << "Expected filename of program to execute" << std::endl; std::cerr << "Expected filename of program to execute" << std::endl;
@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
memory.resize(MEMORY_SIZE, 0); memory.resize(MEMORY_SIZE, 0);
VM vm(memory); VM vm(memory, program_filename);
if (!debug) { if (!debug) {
try { try {

View file

@ -12,7 +12,8 @@ inline int32_t sign_extend(int32_t value, int bits) {
return (value ^ mask) - mask; return (value ^ mask) - mask;
} }
VM::VM(std::vector<uint8_t> memory) : memory_(memory) {} VM::VM(const std::vector<uint8_t>& memory, const std::string& file_path)
: memory_(memory), file_path(file_path) {}
std::vector<uint8_t> VM::read_memory(size_t start, size_t size) { std::vector<uint8_t> VM::read_memory(size_t start, size_t size) {
if (start + size > memory_.size()) { if (start + size > memory_.size()) {
@ -38,6 +39,8 @@ uint32_t VM::read_register(size_t regnum) {
return registers[regnum]; return registers[regnum];
} }
const std::string& VM::get_file_path() { return file_path; }
void VM::step() { void VM::step() {
size_t memory_size = memory_.size(); size_t memory_size = memory_.size();
uint8_t* memory = &memory_[0]; uint8_t* memory = &memory_[0];

View file

@ -11,7 +11,7 @@ const int NUM_REGISTERS = 32; // Standard RISC-V has 32 registers
class VM { class VM {
public: public:
VM(std::vector<uint8_t> memory); VM(const std::vector<uint8_t> &memory, const std::string &file_path);
void step(); void step();
void eval(); void eval();
@ -22,9 +22,12 @@ class VM {
uint32_t read_register(size_t regnum); uint32_t read_register(size_t regnum);
const std::string &get_file_path();
private: private:
std::vector<uint8_t> memory_; std::vector<uint8_t> memory_;
uint32_t registers[NUM_REGISTERS] = {0}; uint32_t registers[NUM_REGISTERS] = {0};
uint32_t pc = 0; uint32_t pc = 0;
std::string file_path;
}; };