Home | History | Annotate | Download | only in gdbstub

Lines Matching refs:stub

22  * GDB stub for remote debugging
77 void (*parse) (struct gdbstub * stub, char ch);
215 static void gdbstub_state_new(struct gdbstub *stub, char ch);
216 static void gdbstub_state_data(struct gdbstub *stub, char ch);
217 static void gdbstub_state_cksum1(struct gdbstub *stub, char ch);
218 static void gdbstub_state_cksum2(struct gdbstub *stub, char ch);
219 static void gdbstub_state_wait_ack(struct gdbstub *stub, char ch);
312 static void gdbstub_tx_packet(struct gdbstub *stub)
314 uint8_t cksum = gdbstub_cksum(stub->payload, stub->len);
315 stub->buf[0] = '$';
316 stub->buf[stub->len + 1] = '#';
317 stub->buf[stub->len + 2] = gdbstub_to_hex_digit(cksum >> 4);
318 stub->buf[stub->len + 3] = gdbstub_to_hex_digit(cksum);
319 serial_write(stub->buf, stub->len + 4);
320 stub->parse = gdbstub_state_wait_ack;
324 static void gdbstub_send_ok(struct gdbstub *stub)
326 stub->payload[0] = 'O';
327 stub->payload[1] = 'K';
328 stub->len = 2;
329 gdbstub_tx_packet(stub);
332 static void gdbstub_send_num_packet(struct gdbstub *stub, char reply, int num)
334 stub->payload[0] = reply;
335 stub->payload[1] = gdbstub_to_hex_digit((char)num >> 4);
336 stub->payload[2] = gdbstub_to_hex_digit((char)num);
337 stub->len = 3;
338 gdbstub_tx_packet(stub);
342 static int gdbstub_get_packet_args(struct gdbstub *stub, unsigned long *args,
349 for (i = 1; i < stub->len && argc < nargs; i++) {
350 ch = stub->payload[i];
366 return ((i == stub->len || ch == ':') && argc == nargs);
369 static void gdbstub_send_errno(struct gdbstub *stub, int errno)
371 gdbstub_send_num_packet(stub, 'E', errno);
374 static void gdbstub_report_signal(struct gdbstub *stub)
376 gdbstub_send_num_packet(stub, 'S', stub->signo);
379 static void gdbstub_read_regs(struct gdbstub *stub)
381 gdbstub_to_hex_buf(stub->payload, (char *)stub->regs, GDBMACH_SIZEOF_REGS);
382 stub->len = GDBMACH_SIZEOF_REGS * 2;
383 gdbstub_tx_packet(stub);
386 static void gdbstub_write_regs(struct gdbstub *stub)
388 if (stub->len != 1 + GDBMACH_SIZEOF_REGS * 2) {
389 gdbstub_send_errno(stub, POSIX_EINVAL);
392 gdbstub_from_hex_buf((char *)stub->regs, &stub->payload[1],
394 gdbstub_send_ok(stub);
397 static void gdbstub_read_mem(struct gdbstub *stub)
401 (stub, args, sizeof args / sizeof args[0], NULL)) {
402 gdbstub_send_errno(stub, POSIX_EINVAL);
406 gdbstub_to_hex_buf(stub->payload, (char *)args[0], args[1]);
407 stub->len = args[1] * 2;
408 gdbstub_tx_packet(stub);
411 static void gdbstub_write_mem(struct gdbstub *stub)
416 (stub, args, sizeof args / sizeof args[0], &colon) || colon >= stub->len
417 || stub->payload[colon] != ':' || (stub->len - colon - 1) % 2 != 0) {
418 gdbstub_send_errno(stub, POSIX_EINVAL);
421 gdbstub_from_hex_buf((char *)args[0], &stub->payload[colon + 1],
422 (stub->len - colon - 1) / 2);
423 gdbstub_send_ok(stub);
426 static void gdbstub_continue(struct gdbstub *stub, int single_step)
429 if (stub->len > 1
430 && gdbstub_get_packet_args(stub, (unsigned long *)&pc, 1, NULL)) {
431 gdbmach_set_pc(stub->regs, pc);
433 gdbmach_set_single_step(stub->regs, single_step);
434 stub->exit_handler = 1;
438 static void gdbstub_breakpoint(struct gdbstub *stub)
441 int enable = stub->payload[0] == 'Z' ? 1 : 0;
443 (stub, args, sizeof args / sizeof args[0], NULL)) {
444 gdbstub_send_errno(stub, POSIX_EINVAL);
448 gdbstub_send_ok(stub);
451 stub->len = 0;
452 gdbstub_tx_packet(stub);
456 static void gdbstub_rx_packet(struct gdbstub *stub)
458 switch (stub->payload[0]) {
460 gdbstub_report_signal(stub);
463 gdbstub_read_regs(stub);
466 gdbstub_write_regs(stub);
469 gdbstub_read_mem(stub);
472 gdbstub_write_mem(stub);
478 gdbstub_continue(stub, stub->payload[0] == 's');
479 if (stub->payload[0] == 'D') {
480 gdbstub_send_ok(stub);
485 gdbstub_breakpoint(stub);
488 stub->len = 0;
489 gdbstub_tx_packet(stub);
495 static void gdbstub_state_new(struct gdbstub *stub, char ch)
498 stub->len = 0;
499 stub->parse = gdbstub_state_data;
503 static void gdbstub_state_data(struct gdbstub *stub, char ch)
506 stub->parse = gdbstub_state_cksum1;
508 stub->len = 0; /* retry new packet */
511 if (stub->len < SIZEOF_PAYLOAD) {
512 stub->payload[stub->len++] = ch;
517 static void gdbstub_state_cksum1(struct gdbstub *stub, char ch)
519 stub->cksum1 = gdbstub_from_hex_digit(ch) << 4;
520 stub->parse = gdbstub_state_cksum2;
523 static void gdbstub_state_cksum2(struct gdbstub *stub, char ch)
528 stub->parse = gdbstub_state_new;
529 their_cksum = stub->cksum1 + gdbstub_from_hex_digit(ch);
530 our_cksum = gdbstub_cksum(stub->payload, stub->len);
534 if (stub->len > 0) {
535 gdbstub_rx_packet(stub);
542 static void gdbstub_state_wait_ack(struct gdbstub *stub, char ch)
545 stub->parse = gdbstub_state_new;
549 gdbstub_tx_packet(stub);
555 struct gdbstub stub;
559 stub.parse = gdbstub_state_new;
560 stub.payload = &stub.buf[1];
561 stub.signo = signo;
562 stub.regs = regs;
563 stub.exit_handler = 0;
564 gdbstub_report_signal(&stub);
565 while (!stub.exit_handler)
566 stub.parse(&stub, serial_getc());