2022-05-14 22:43:08 +01:00
|
|
|
#include "ReadMemoryMap.hpp"
|
|
|
|
|
|
|
|
|
|
#include "src/DebugServer/Gdb/ResponsePackets/ResponsePacket.hpp"
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
#include "src/Services/StringService.hpp"
|
2022-05-14 22:43:08 +01:00
|
|
|
#include "src/Exceptions/Exception.hpp"
|
|
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace DebugServer::Gdb::AvrGdb::CommandPackets
|
2022-05-14 22:43:08 +01:00
|
|
|
{
|
2022-12-26 21:27:19 +00:00
|
|
|
using Services::TargetControllerService;
|
2022-05-14 22:43:08 +01:00
|
|
|
|
|
|
|
|
using ResponsePackets::ResponsePacket;
|
|
|
|
|
|
|
|
|
|
using Exceptions::Exception;
|
|
|
|
|
|
2024-10-25 22:22:25 +01:00
|
|
|
ReadMemoryMap::ReadMemoryMap(const RawPacket& rawPacket)
|
2024-10-26 16:19:05 +01:00
|
|
|
: Gdb::CommandPackets::CommandPacket(rawPacket)
|
2022-05-14 22:43:08 +01:00
|
|
|
{
|
2024-07-23 21:14:22 +01:00
|
|
|
using Services::StringService;
|
|
|
|
|
|
2022-05-14 22:43:08 +01:00
|
|
|
if (this->data.size() < 26) {
|
2024-07-23 21:14:22 +01:00
|
|
|
throw Exception{"Invalid packet length"};
|
2022-05-14 22:43:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The read memory map ('qXfer:memory-map:read::...') packet consists of two segments, an offset and a length.
|
|
|
|
|
* These are separated by a comma character.
|
|
|
|
|
*/
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto command = std::string{this->data.begin() + 23, this->data.end()};
|
2022-05-14 22:43:08 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto delimiterPos = command.find_first_of(',');
|
|
|
|
|
if (delimiterPos == std::string::npos) {
|
|
|
|
|
throw Exception{"Invalid packet"};
|
2022-05-14 22:43:08 +01:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
this->offset = StringService::toUint32(command.substr(0, delimiterPos), 16);
|
|
|
|
|
this->length = StringService::toUint32(command.substr(delimiterPos + 1), 16);
|
2022-05-14 22:43:08 +01:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
void ReadMemoryMap::handle(
|
2024-10-25 22:22:25 +01:00
|
|
|
DebugSession& debugSession,
|
|
|
|
|
const AvrGdbTargetDescriptor& gdbTargetDescriptor,
|
2024-07-23 21:14:22 +01:00
|
|
|
const Targets::TargetDescriptor& targetDescriptor,
|
2024-12-14 16:17:02 +00:00
|
|
|
const Targets::TargetState& targetState,
|
2024-07-23 21:14:22 +01:00
|
|
|
TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
2023-05-07 20:17:33 +01:00
|
|
|
Logger::info("Handling ReadMemoryMap packet");
|
2022-05-14 22:43:08 +01:00
|
|
|
|
2022-12-08 21:18:04 +00:00
|
|
|
/*
|
|
|
|
|
* We include register and EEPROM memory in our RAM section. This allows GDB to access registers and EEPROM
|
|
|
|
|
* data via memory read/write packets.
|
|
|
|
|
*/
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto ramSectionEndAddress = gdbTargetDescriptor.translateTargetMemoryAddress(
|
2024-10-25 22:22:25 +01:00
|
|
|
gdbTargetDescriptor.eepromMemorySegmentDescriptor.addressRange.endAddress,
|
|
|
|
|
gdbTargetDescriptor.eepromAddressSpaceDescriptor,
|
|
|
|
|
gdbTargetDescriptor.eepromMemorySegmentDescriptor
|
2024-07-23 21:14:22 +01:00
|
|
|
);
|
2024-10-25 22:22:25 +01:00
|
|
|
const auto ramSectionStartAddress = AvrGdbTargetDescriptor::SRAM_ADDRESS_MASK;
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto ramSectionSize = ramSectionEndAddress - ramSectionStartAddress + 1;
|
2022-05-14 22:43:08 +01:00
|
|
|
|
|
|
|
|
const auto memoryMap =
|
2024-07-23 21:14:22 +01:00
|
|
|
std::string{"<memory-map>"}
|
|
|
|
|
+ "<memory type=\"ram\" start=\"" + std::to_string(ramSectionStartAddress) + "\" length=\"" + std::to_string(ramSectionSize) + "\"/>"
|
2024-10-25 22:22:25 +01:00
|
|
|
+ "<memory type=\"flash\" start=\"0\" length=\"" + std::to_string(gdbTargetDescriptor.programMemorySegmentDescriptor.size()) + "\">"
|
|
|
|
|
+ "<property name=\"blocksize\">" + std::to_string(gdbTargetDescriptor.programMemorySegmentDescriptor.pageSize.value()) + "</property>"
|
2022-05-14 22:43:08 +01:00
|
|
|
+ "</memory>"
|
|
|
|
|
+ "</memory-map>";
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
auto responseData = std::vector<unsigned char>{'l'};
|
|
|
|
|
|
2022-05-14 22:43:08 +01:00
|
|
|
if (this->offset < memoryMap.size() && this->length > 0) {
|
2024-07-23 21:14:22 +01:00
|
|
|
responseData.insert(
|
|
|
|
|
responseData.end(),
|
2022-05-14 22:43:08 +01:00
|
|
|
memoryMap.begin() + this->offset,
|
2024-07-23 21:14:22 +01:00
|
|
|
memoryMap.begin() + this->offset + std::min(
|
|
|
|
|
static_cast<long>(this->length),
|
|
|
|
|
static_cast<long>(memoryMap.size() - this->offset)
|
2022-05-14 22:43:08 +01:00
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
debugSession.connection.writePacket(ResponsePacket{responseData});
|
2022-05-14 22:43:08 +01:00
|
|
|
}
|
|
|
|
|
}
|