39 std::string ipaddr, uint32_t udpport) {
50 std::cout <<
"[" << udpport <<
"]";
52 _bp_list =
new std::list<T>();
67 checksum += *buffer++;
76 _output_buffer[0] =
'$';
79 memcpy(&_output_buffer[1], data.c_str(), data.length());
82 _output_buffer[data.length() + 1] =
'#';
85 uint8_t checksum = this->Checksum(&_output_buffer[1], data.length());
86 snprintf(reinterpret_cast<char*>(&_output_buffer[data.length() + 2]),
87 sizeof(uint32_t),
"%02x", checksum);
90 _output_buffer[data.length() + 4] =
'\0';
93 std::cout <<
"\033[0;36m<--\033[0m" << _output_buffer << std::endl;
97 return _server->Send(_output_buffer, data.length() + 4);
100 template <
typename T>
103 std::cout <<
"\033[0;36m<-- ack\033[0m" << std::endl;
106 _output_buffer[0] =
'+';
107 return _server->Send(_output_buffer, 1);
110 template <
typename T>
112 _output_buffer[0] =
'-';
113 return _server->Send(_output_buffer, 1);
116 template <
typename T>
119 if (_state->bp == 0) {
120 for (
typename std::list<T>::iterator i = _bp_list->begin();
121 i != _bp_list->end(); ++i) {
122 if (_state->pc == *i) {
125 this->Respond(
"S05");
133 if (_state->bp == 1) {
140 }
else if (_state->pause == 0) {
141 if (_state->steps > 0) {
145 if (_state->steps == 0) {
147 this->Respond(
"S05");
155 template <
typename T>
158 int recv_bytes = _server->
Receive(_input_buffer);
161 if (recv_bytes > 0) {
163 _input_buffer[recv_bytes] =
'\0';
166 if (_input_buffer[0] ==
'+') {
168 std::cout <<
"\033[0;31m-->\033[0m" << _input_buffer << std::endl;
172 }
else if (_input_buffer[0] ==
'-') {
174 std::cout <<
"\033[0;31m-->\033[0m" << _input_buffer << std::endl;
179 }
else if (_input_buffer[0] ==
'$') {
181 std::cout <<
"\033[0;36m-->\033[0m" << _input_buffer << std::endl;
188 switch (_input_buffer[1]) {
189 case 'q':
return this->Handle_q(_input_buffer);
190 case 'g':
return this->Handle_g(_input_buffer);
191 case '?':
return this->Handle_Question(_input_buffer);
192 case 'c':
return this->Handle_c(_input_buffer);
193 case 'C':
return this->Handle_C(_input_buffer);
194 case 's':
return this->Handle_s(_input_buffer);
195 case 'H':
return this->Handle_H(_input_buffer);
196 case 'm':
return this->Handle_m(_input_buffer);
198 case 'p':
return this->Handle_p(_input_buffer);
199 case 'P':
return this->Handle_P(_input_buffer);
200 case 'v':
return this->Handle_v(_input_buffer);
201 case 'X':
return this->Handle_X(_input_buffer);
202 case 'z':
return this->Handle_z(_input_buffer);
203 case 'Z':
return this->Handle_Z(_input_buffer);
211 std::cout <<
"\033[0;31mwnr: unknown packet type: \033[0m" 212 << _input_buffer << std::endl;
216 return this->Respond(
"");
221 <<
"\033[0;31mwrn: dropped packet with unknown prefix:\033[0m" 222 << _input_buffer << std::endl;
230 template <
typename T>
232 if (memcmp(buffer,
"$X", 2) == 0) {
234 int addr =
strhti(&buffer[2], 10);
237 int i =
strfind(buffer,
',', 14);
238 int size =
strhti(&buffer[i+1], 10);
242 return this->Respond(
"OK");
248 uint8_t* raw =
reinterpret_cast<uint8_t*
>(&buffer[i+1]);
256 for (
int j = 0, i = 0; i < size; i++) {
257 if (raw[j] == 0x7d) {
258 raw[i] = (uint8_t)(raw[++j] ^ 0x20);
266 _memory->Write(addr, reinterpret_cast<MemoryType*>(raw), size);
267 return this->Respond(
"OK");
270 std::cout <<
"unhandled packet 'X'" << std::endl;
276 template <
typename T>
279 if (memcmp(buffer,
"$g", 2) == 0) {
285 hexstr(reinterpret_cast<char*>(reg_data),
289 return this->Respond(std::string(reg_data));
292 std::cout <<
"unhandled packet 'g'" << std::endl;
298 template <
typename T>
301 if (memcmp(buffer,
"$vCont", 5) == 0) {
306 }
else if (memcmp(buffer,
"$vKill", 5) == 0) {
311 }
else if (memcmp(buffer,
"$vMustReplyEmpty", 16) == 0) {
316 std::cout <<
"unhandled packet 'v'" << std::endl;
323 template <
typename T>
326 if (memcmp(buffer,
"$QStartNoAckMode", 15) == 0) {
329 std::cout <<
"unhandled packet 'Q'" << std::endl;
336 template <
typename T>
339 if (memcmp(buffer,
"$qC", 3) == 0) {
340 return this->Respond(
"QC1");
343 }
else if (memcmp(buffer,
"$qAttached", 7) == 0) {
344 return this->Respond(
"0");
348 }
else if (memcmp(buffer,
"$qOffsets", 6) == 0) {
349 return this->Respond(
"Text=0;Data=0;Bss=0");
352 }
else if (memcmp(buffer,
"$qSymbol", 6) == 0) {
353 return this->Respond(
"OK");
356 }
else if (memcmp(buffer,
"$qSupported", 11) == 0) {
357 return this->Respond(
"PacketSize=FFF");
360 }
else if (memcmp(buffer,
"$qfThreadInfo", 11) == 0) {
362 return this->Respond(
"m1");
365 }
else if (memcmp(buffer,
"$qsThreadInfo", 11) == 0) {
366 return this->Respond(
"l");
369 }
else if (memcmp(buffer,
"$qTStatus", 8) == 0) {
370 return this->Respond(
"T0");
374 std::cout <<
"unhandled qT packet, sent empty response" << std::endl;
375 return this->Respond(
"");
382 template <
typename T>
384 return this->Respond(
"S00");
388 template <
typename T>
390 if (memcmp(buffer,
"$C", 2) == 0) {
394 return this->Respond(
"OK");
396 std::cout <<
"unhandled 'c' packet, sent empty response" << std::endl;
397 return this->Respond(
"");
404 template <
typename T>
407 if (memcmp(buffer,
"$c", 2) == 0) {
411 return this->Respond(
"OK");
413 std::cout <<
"unhandled 'c' packet, sent empty response" << std::endl;
414 return this->Respond(
"");
421 template <
typename T>
423 if (memcmp(buffer,
"$s", 2) == 0) {
425 if (buffer[2] ==
'#') {
430 std::cout <<
"multiple step not implemented, sent empty response" 435 std::cout <<
"unhandled 's' packet, sent empty response" << std::endl;
443 template <
typename T>
445 return this->Respond(
"OK");
448 template <
typename T>
456 template <
typename T>
459 if (memcmp(buffer,
"$m", 2) == 0) {
460 uint32_t addr = 0, size = 0;
461 int end = 0, comma = 0;
465 end =
strfind(buffer,
'#', 100);
469 addr =
strhti(&buffer[2], end - 2);
472 comma =
strfind(buffer,
',', end);
475 size =
strhti(&buffer[comma+1], end);
479 if (addr < _memory->GetBase() || addr > _memory->GetLastAddr()) {
480 std::cout <<
"gdbcli requested data from outside memory space:" 482 return this->Respond(
"");
487 _memory->Read(addr, data, size);
490 char str_data[size * 2 + 8];
493 hexstr(reinterpret_cast<char*>(str_data),
494 reinterpret_cast<char*>(data), size / 2);
496 return this->Respond(std::string(reinterpret_cast<char*>(str_data)));
498 std::cout <<
"unhandled 'm' packet, sent empty response" << std::endl;
499 return this->Respond(
"");
504 template <
typename T>
510 template <
typename T>
513 if (memcmp(buffer,
"$p", 2) == 0) {
515 char digit[4] =
"\0\0\0";
518 if (buffer[2] >= 48 && buffer[2] <= 57) digit[0] = buffer[2];
519 if (buffer[3] >= 48 && buffer[3] <= 57) digit[1] = buffer[3];
522 unsigned int reg =
static_cast<int>(strtol(digit, NULL, 16));
526 char reg_data[
sizeof(T) * 2 + 1];
529 snprintf(reg_data,
sizeof(reg_data),
"%0X",
530 (
unsigned int)_state->regs[reg]);
532 this->Respond(std::string(reg_data));
535 std::cout <<
"unhandled 'p' packet, sent empty response" << std::endl;
536 return this->Respond(
"");
542 template <
typename T>
544 if (memcmp(buffer,
"$P", 2) == 0) {
546 int addr =
strhti(&buffer[2], 3);
549 int eqsymb =
strfind(buffer,
'=', 10);
552 int value =
strhti(&buffer[eqsymb+1], 10);
556 _state->regs[addr] = value;
557 return this->Respond(
"OK");
560 std::cout <<
"unhandled 'P' packet, sent empty response" << std::endl;
561 return this->Respond(
"");
569 template <
typename T>
571 if (memcmp(buffer,
"$Z", 2) == 0) {
573 int comma =
strfind(buffer,
',', 10);
576 T addr =
strhti(&buffer[comma + 1], 10);
579 bool has_addr_already =
false;
581 for (
typename std::list<T>::iterator i = _bp_list->begin();
582 i != _bp_list->end(); ++i) {
585 <<
"warn: there's a breakpoint in this address already" 587 has_addr_already =
true;
593 if (!has_addr_already) _bp_list->push_back(addr);
597 return this->Respond(
"OK");
600 std::cout <<
"unhandled 'Z' packet, sent empty response" << std::endl;
601 return this->Respond(
"");
608 template <
typename T>
610 if (memcmp(buffer,
"$z", 2) == 0) {
612 int comma =
strfind(buffer,
',', 10);
615 T addr =
strhti(&buffer[comma + 1], 10);
618 _bp_list->remove(addr);
622 return this->Respond(
"OK");
625 std::cout <<
"unhandled 'z' packet, sent empty response" << std::endl;
626 return this->Respond(
"");
This class implements an asynchonous udp server.
int strfind(char *buffer, char find, int limit)
String find.
int strhti(char *buffer, int length)
String-to-int.
#define RSP_EMPTY_RESPONSE
This class models a memory module.
uint32_t endswap(uint32_t value)
Endianess Swap.
#define NUMBER_OF_REGISTERS
Defines a generic state model for use within processor models.
void hexstr(char *output, char *input, uint32_t integers)
String to hex.