#include "ReadMemoryMap.hpp" #include "src/DebugServer/Gdb/ResponsePackets/ResponsePacket.hpp" #include "src/Services/StringService.hpp" #include "src/Exceptions/Exception.hpp" namespace DebugServer::Gdb::AvrGdb::CommandPackets { using Services::TargetControllerService; using ResponsePackets::ResponsePacket; using Exceptions::Exception; ReadMemoryMap::ReadMemoryMap(const RawPacket& rawPacket) : Gdb::CommandPackets::CommandPacket(rawPacket) { using Services::StringService; if (this->data.size() < 26) { throw Exception{"Invalid packet length"}; } /* * 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. */ const auto command = std::string{this->data.begin() + 23, this->data.end()}; const auto delimiterPos = command.find_first_of(','); if (delimiterPos == std::string::npos) { throw Exception{"Invalid packet"}; } this->offset = StringService::toUint32(command.substr(0, delimiterPos), 16); this->length = StringService::toUint32(command.substr(delimiterPos + 1), 16); } void ReadMemoryMap::handle( DebugSession& debugSession, const AvrGdbTargetDescriptor& gdbTargetDescriptor, const Targets::TargetDescriptor& targetDescriptor, TargetControllerService& targetControllerService ) { Logger::info("Handling ReadMemoryMap packet"); /* * We include register and EEPROM memory in our RAM section. This allows GDB to access registers and EEPROM * data via memory read/write packets. */ const auto ramSectionEndAddress = gdbTargetDescriptor.translateTargetMemoryAddress( gdbTargetDescriptor.eepromMemorySegmentDescriptor.addressRange.endAddress, gdbTargetDescriptor.eepromAddressSpaceDescriptor, gdbTargetDescriptor.eepromMemorySegmentDescriptor ); const auto ramSectionStartAddress = AvrGdbTargetDescriptor::SRAM_ADDRESS_MASK; const auto ramSectionSize = ramSectionEndAddress - ramSectionStartAddress + 1; const auto memoryMap = std::string{""} + "" + "" + "" + std::to_string(gdbTargetDescriptor.programMemorySegmentDescriptor.pageSize.value()) + "" + "" + ""; auto responseData = std::vector{'l'}; if (this->offset < memoryMap.size() && this->length > 0) { responseData.insert( responseData.end(), memoryMap.begin() + this->offset, memoryMap.begin() + this->offset + std::min( static_cast(this->length), static_cast(memoryMap.size() - this->offset) ) ); } debugSession.connection.writePacket(ResponsePacket{responseData}); } }