4 * GDB stub implemented on top of the Romain framework
6 * (c) 2011-2013 Björn Döbel <doebel@os.inf.tu-dresden.de>,
7 * economic rights: Technische Universität Dresden (Germany)
8 * This file is part of TUD:OS and distributed under the terms of the
9 * GNU General Public License 2.
10 * Please see the COPYING-GPL-2 file for details.
14 #include <l4/sys/thread>
15 #include <l4/util/util.h>
18 #include "../app_loading"
20 #include "lwip/inet.h"
22 #define GDB_BYTE_FORMAT(reg) ntohl((unsigned int)(reg))
23 #define SAVED_VCPU_REGS _saved_vcpu.r()
25 #define MSG() DEBUGf(Romain::Log::Gdb)
28 * put a reply into the packet buffer
30 #define REPLY_PACKET(fmt, ...) \
32 snprintf(_outbuf, sizeof(_outbuf), \
33 "$"fmt, ##__VA_ARGS__); \
34 append_checksum(_outbuf+1); \
35 MSG() << "\033[36;1m'" << _outbuf << "'\033[0m"; \
39 * For any command not supported by the stub, an empty response (`$#00')
40 * should be returned. That way it is possible to extend the protocol.
41 * A newer GDB can tell if a packet is supported based on that response.
43 #define UNSUPPORTED() REPLY_PACKET("")
45 #define REPLY_OK REPLY_PACKET("OK");
47 extern struct netif ankh_netif;
49 void Romain::GDBServerObserver::status() const { }
52 * GDB stub thread. Simply waits for commands to come in from the net and
53 * handles them. This handling requires synchronization with the other threads,
54 * which is done through internal signalling.
56 static void *gdb_stub_thread(void* data)
58 INFO() << "GDB Stub thread running.";
60 Romain::GDBServerObserver *stub = (Romain::GDBServerObserver*)data;
62 stub->connection()->setup_and_wait();
63 stub->notify_connect();
66 memset(stub->buffer(), 0, stub->maxbuffer());
67 int num_bytes = stub->connection()->wait_for_cmd(stub->buffer(), stub->maxbuffer());
70 stub->connection()->setup_and_wait();
74 while (stub->handle_cmd() > 0)
82 Romain::GDBServerObserver::GDBServerObserver(Connection* con)
86 _await_ack(true), // GDB sends an ACK first!
94 memset(_inbuf, 0, sizeof(_inbuf));
95 memset(_outbuf, 0, sizeof(_outbuf));
96 memset(_last_cmd, 0, sizeof(_last_cmd));
97 memset(&_saved_vcpu, 0, sizeof(_saved_vcpu));
99 r = sem_init(&_app_wait_signal, 0, 0);
100 _check(r != 0, "sem_init");
101 r = sem_init(&_gdb_wait_signal, 0, 0);
102 _check(r != 0, "sem_init");
104 r = pthread_create(&_thread, 0, gdb_stub_thread, this);
105 _check(r != 0, "pthread_create()");
109 Romain::GDBServerObserver::~GDBServerObserver()
115 * Startup notification. We know that the first thread has been started and thus
116 * obtain an IP through DHCP and wait for a remote GDB to connect.
118 void Romain::GDBServerObserver::startup_notify(Romain::App_instance *,
119 Romain::App_thread *,
120 Romain::Thread_group *,
121 Romain::App_model *a)
125 while (!_connected) {
126 INFO() << "waiting for GDB to connect...";
127 sem_wait(&_app_wait_signal);
135 Romain::Observer::ObserverReturnVal
136 Romain::GDBServerObserver::notify(Romain::App_instance *,
137 Romain::App_thread *t,
138 Romain::Thread_group *,
142 MSG() << "want halt: " << _want_halt
143 << " trap: " << t->vcpu()->r()->trapno
144 << " pending: 0x" << std::hex << t->get_pending_trap();
148 * Only handle traps 1 & 3. But we use _any_ trap notification
149 * to force the target thread into the debugger, e.g., in the
150 * case of an interrupt.
152 if (!t->events_pending() &&
153 (t->vcpu()->r()->trapno != 1) &&
154 (t->vcpu()->r()->trapno != 3)) {
156 t->set_pending_trap(3);
158 return Romain::Observer::Ignored;
167 //MSG() << "received HLT from GDB. Waiting for command.";
168 notify_and_wait(&_gdb_wait_signal, &_app_wait_signal);
172 return Romain::Observer::Continue;
177 * Verify a GDB packet checksum, which by its definition is
178 * a sum of all text characters in the packet modulo 256.
180 bool Romain::GDBServerObserver::checksum_cmd(char const * const ptr, char const **end)
185 for ( ; *c != '#'; sum += *c++)
189 return (sum & 0xff) == (unsigned)strtol(c+1, 0, 16);
194 * Append checksum to a GDB packet.
196 void Romain::GDBServerObserver::append_checksum(char *p)
201 snprintf(p, 4, "#%02x", csum & 0xFF);
205 bool Romain::GDBServerObserver::next_cmd()
207 /* New content in packet buf? */
213 if (_bufptr - _last_cmd > 1024) { // XXX
219 case NoCmd: // end of read buffer
225 enter_kdebug("interrupt");
233 MSG() << "Got ACK while not expecting one!";
235 //enter_kdebug("ACK");
240 // the last cmd is still in _last_cmd, so just
245 _bufptr++; // skip the $ sign
249 ERROR() << "invalid packet start: " << *_bufptr;
250 enter_kdebug("error");
255 if (!checksum_cmd(_bufptr, &eoc)) {
256 ERROR() << "Wrong checksum.";
257 enter_kdebug("csum");
260 _check(eoc - _bufptr <= 0, "cmd with 0 or negative size");
262 memset(_last_cmd, 0, sizeof(_last_cmd));
263 memcpy(_last_cmd, _bufptr, eoc - _bufptr);
265 // set bufptr to _after_ the current cmd. this is where
266 // we start searching for the next cmd then
267 _bufptr = const_cast<char*>(eoc) + 3; // # + 2 bytes checksum == 3
270 _check(_con->senddata("+", 2) != 2, "send ack");
278 * GDB command dispatcher.
280 int Romain::GDBServerObserver::handle_cmd()
285 MSG() << "Need to handle cmd "
286 << "\033[35m" << _last_cmd << "\033[0m";
288 char *cmd = _last_cmd;
291 case 'g': gdb_get_registers(cmd+1); break;
292 case 'p': gdb_read_register(cmd+1); break;
293 case 'P': gdb_write_register(cmd+1); break;
295 case 'm': gdb_dump_mem(cmd+1); break;
296 case 'M': gdb_write_mem(cmd+1, false); break;
297 case 'H': gdb_select_thread(cmd+1); break;
298 case 'k': disconnect(); return -1;
299 case 'q': gdb_query(cmd+1); break;
300 case 'Q': gdb_settings(cmd+1); break;
302 case 'S': gdb_step(cmd+1, true); break;
303 case 's': gdb_step(cmd+1, false); break;
304 case 'C': gdb_continue(cmd+1, true); break;
305 case 'c': gdb_continue(cmd+1, false); break;
308 if (strcmp(cmd, "vCont?") == 0)
312 case 'X': gdb_write_mem(cmd+1, true); break;
313 case 'Z': gdb_breakpoint(cmd+1); break;
316 * Queries the last stop reason. Initially, we return TARGET_SIGNAL_DEFAULT - 0x90
319 case '?': REPLY_PACKET("S90"); break;
322 INFO() << "Unhandled GDB command: " << cmd;
323 enter_kdebug("Unhandled cmd");
327 _await_ack = _ack_mode;
328 int err = _con->senddata(_outbuf, strlen(_outbuf));
329 _check(err <= 0, "send reply");
336 * Handle GDB settings modification.
338 * We only support StartNoAckMode so far.
340 void Romain::GDBServerObserver::gdb_settings(char const * const cmd)
342 //MSG() << "Q: " << cmd;
344 if (strcmp(cmd, "StartNoAckMode") == 0) {
349 MSG() << "Unsupported Q cmd: " << cmd;
356 * Handle remote query.
358 * Currently only returns supported features.
360 void Romain::GDBServerObserver::gdb_query(char const * const cmd)
362 //MSG() << "CMD: " << cmd;
364 if (strncmp(cmd, "Supported", (size_t)9) == 0) // feature query
365 REPLY_PACKET("PacketSize=%d;QStartNoAckMode+;", sizeof(_outbuf));
366 else if (strncmp(cmd, "Symbol::", 8) == 0) {
370 MSG() << "Unsupported query cmd: " << cmd;
377 * `H c thread-id' : Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
378 * c depends on the operation to be performed: it should be `c' for step and continue
379 * operations, `g' for other operations. The thread designator thread-id has the format
380 * and interpretation described in thread-id syntax.
384 * `E NN' for an error
386 void Romain::GDBServerObserver::gdb_select_thread(char const * const cmd)
389 //MSG() << "CMD: " << cmd;
393 if (atoi(cmd+1) > 0) {
394 ERROR() << "g cmd for thread" << atoi(cmd+1);
399 else if (*cmd == 'c') {
400 if (atoi(cmd+1) > 0) {
401 ERROR() << "c cmd for thread" << atoi(cmd+1);
407 ERROR() << "Unsupported H cmd: " << cmd;
416 * `g' Read general registers.
420 * `XX...' Each byte of register data is described by two hex digits. The bytes
421 * with the register are transmitted in target byte order. The size of
422 * each register and their position within the `g' packet are determined
423 * by the gdb internal gdbarch functions DEPRECATED_REGISTER_RAW_SIZE and
424 * gdbarch_register_name. The specification of several standard `g'
425 * packets is specified below.
427 * `E NN' for an error.
429 void Romain::GDBServerObserver::gdb_get_registers(char const * const)
431 REPLY_PACKET("%08x%08x%08x%08x%08x%08x%08x%08x"
432 "%08x%08x%08x%08x%08x%08x%08x%08x",
433 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->ax), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->cx),
434 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->dx), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->bx),
435 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->sp), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->bp),
436 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->si), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->di),
437 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->ip), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->flags),
438 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->dummy1), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->ss),
439 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->ds), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->es),
440 GDB_BYTE_FORMAT(SAVED_VCPU_REGS->fs), GDB_BYTE_FORMAT(SAVED_VCPU_REGS->gs));
444 * `m addr,length' Read length bytes of memory starting at address addr. Note that addr
445 * may not be aligned to any particular boundary. The stub need not use
446 * any particular size or alignment when gathering data from memory for
447 * the response; even if addr is word-aligned and length is a multiple of
448 * the word size, the stub is free to use byte accesses, or not. For this
449 * reason, this packet may not be suitable for accessing memory-mapped I/O
453 * `XX…' Memory contents; each byte is transmitted as a two-digit hexadecimal number. The
454 * reply may contain fewer bytes than requested if the server was able to read only
455 * part of the region of memory.
459 void Romain::GDBServerObserver::gdb_dump_mem(char const * const cmd)
463 if (sscanf(cmd, "%x,%x", &addr, &len) != 2) {
464 ERROR() << "Incorrectly matching memory read cmd: " << cmd;
468 // XXX: so far we only support the gdb stub for the first running
469 // instance XXX multi-instance support?
470 l4_addr_t local_addr = _app_model->rm()->remote_to_local(addr, 0);
471 if (local_addr == ~0UL) // nothing mapped?
476 * Validate buffer length. The memory dump may cross a page boundary
477 * and the next page might not be attached at all. To avoid unhandled
478 * page faults here, we check the end address and if it does not resolve
479 * successfully, we cut the length until the end of the first page.
481 * This assumes that GDB will never try to dump more than a page or even
482 * regions with pages unmapped in between.
484 if (l4_trunc_page(local_addr) != l4_trunc_page(local_addr + len)) {
485 // XXX: so far we only support the gdb stub for the first running
486 // instance XXX multi-instance support?
487 l4_addr_t end_addr = _app_model->rm()->remote_to_local(local_addr + len, 0);
488 if (end_addr == ~0UL) {
489 len = l4_round_page(local_addr) - local_addr;
493 //MSG() << "local @ " << (void*)local_addr;
495 // we print 2 characters at a time - representing one byte in hex; as long
496 // as the length field tells us
497 for (unsigned i = 0; i < len; ++i) {
498 char *start = &_outbuf[1];
500 //MSG() << (void*)start << " <-> " << std::hex << (int)*(unsigned char*)(local_addr + i);
501 snprintf(start, 3, "%02x", *(unsigned char*)(local_addr + i));
503 append_checksum(_outbuf+1);
504 MSG() << "\033[36;1m'" << _outbuf << "'\033[0m";
509 void Romain::GDBServerObserver::gdb_continue(const char* cmd, bool withSignal)
512 * For the signal case, we simply assume for now that we are continuing
513 * from the last signal, in which case the command behaves the same as with
514 * no signal specified. Later, we should verify this.
516 if (withSignal || (strlen(cmd) == 0)) {
517 // disable single-stepping just in case it was enabled
519 SAVED_VCPU_REGS->flags &= ~(1 << 8);
520 notify_and_wait(&_app_wait_signal, &_gdb_wait_signal);
522 signal_return(/*_notifyThread*/);
524 ERROR() << "continue from address? " << cmd;
530 void Romain::GDBServerObserver::gdb_step(const char* cmd, bool withSignal)
533 if ((!withSignal && (strlen(cmd) == 0)) ||
534 ( withSignal && (strcmp(cmd, "90") == 0))) {
536 SAVED_VCPU_REGS->flags |= (1 << 8);
538 notify_and_wait(&_app_wait_signal, &_gdb_wait_signal);
539 signal_return(/*_notifyThread*/);
541 printf("step: '%s'\n", cmd);
542 ERROR() << "step from address not implemented!";
548 void Romain::GDBServerObserver::gdb_breakpoint(char const* cmd)
551 // XXX Handle breakpoints
556 void Romain::GDBServerObserver::gdb_write_mem(char const* cmd, bool binaryData)
559 if (sscanf(cmd, "%x,%x", &addr, &len) != 2) {
560 ERROR() << "Invalid memory write cmd: " << cmd;
564 if (!len) { // nothing to do
569 // XXX: so far we only support the gdb stub for the first running
570 // instance XXX multi-instance support?
571 l4_addr_t local_addr = _app_model->rm()->remote_to_local(addr, 0);
572 MSG() << "local: " << std::hex << (void*)local_addr;
573 if (local_addr == ~0UL) {// nothing mapped?
576 unsigned char const* data_start;
577 unsigned char const* data_end;
578 unsigned char const *c = (unsigned char const*)cmd;
580 MSG() << "local value: " << std::hex << *(unsigned char*)local_addr;
581 // find first data byte
586 // find last data byte
587 // (note: dispatcher already removed the # before)
593 MSG() << "data start @ " << (void*)data_start
594 << " data end @ " << (void*)data_end
595 << " cmd @ " << (void*)cmd;
600 for (c = data_start; c <= data_end; ++c) {
605 if ((unsigned)(data_end - data_start + 1) > len) {
606 ERROR() << "Packet says it contains more data than it really does?";
610 MSG() << "memcpy(" << (void*)local_addr << ", "
611 << (void*)data_start << ", " << len << ");";
612 memcpy((char*)local_addr, data_start, len);
614 enter_kdebug("M write");
622 void Romain::GDBServerObserver::gdb_read_register(char const* cmd)
625 enter_kdebug("read_register");
631 * Write register n... with value r.... The register number n is in
632 * hexadecimal, and r... contains two hex digits for each byte in the register
633 * (target byte order).
638 * `E NN' for an error
640 void Romain::GDBServerObserver::gdb_write_register(char const *cmd)
642 unsigned regno, value;
643 MSG() << "write register: " << cmd;
644 sscanf(cmd, "%x=%x", ®no, &value);
645 MSG() << std::hex << value << " " << ntohl(value);
648 #define REGCASE(r) case Romain::r: SAVED_VCPU_REGS->r = ntohl(value); break
650 REGCASE(ax); REGCASE(bx); REGCASE(cx); REGCASE(dx);
651 REGCASE(sp); REGCASE(ip); REGCASE(flags);
652 REGCASE(ss); REGCASE(ds); REGCASE(es); REGCASE(fs);
657 MSG() << "Unhandled reg number: " << regno;
665 void Romain::GDBServerObserver::signal_return(Romain::App_thread *t) {
666 if (!t) t = _notifyThread;
668 if (t->unhandled_pf()) {
669 REPLY_PACKET("S0B"); // SEGV
671 REPLY_PACKET("S05"); // Breakpoint trap