📄 gdb-stub.c
字号:
for (loop = 1; loop <= 27; loop++) ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop), ptr, 4, 0); temp = (unsigned long) __frame; ptr = mem2hex(&temp, ptr, 4, 0); ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0); ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);#ifdef CONFIG_MMU ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);#else temp = (unsigned long) __debug_frame; ptr = mem2hex(&temp, ptr, 4, 0);#endif for (loop = 32; loop <= 63; loop++) ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop), ptr, 4, 0); /* deal with FR0-FR63 */ for (loop = 0; loop <= 63; loop++) ptr = mem2hex((unsigned long *)&__break_user_context + __FPMEDIA_FR(loop), ptr, 4, 0); /* deal with special registers */ ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0); ptr = mem2hex(&__debug_frame->psr, ptr, 4, 0); ptr = mem2hex(&__debug_frame->ccr, ptr, 4, 0); ptr = mem2hex(&__debug_frame->cccr, ptr, 4, 0); ptr = mem2hex(&zero, ptr, 4, 0); ptr = mem2hex(&zero, ptr, 4, 0); ptr = mem2hex(&zero, ptr, 4, 0); ptr = mem2hex(&__debug_frame->tbr, ptr, 4, 0); ptr = mem2hex(&__debug_regs->brr , ptr, 4, 0); asm volatile("movsg dbar0,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg dbar1,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg dbar2,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg dbar3,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg scr0,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg scr1,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg scr2,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); asm volatile("movsg scr3,%0" : "=r"(dbar)); ptr = mem2hex(&dbar, ptr, 4, 0); ptr = mem2hex(&__debug_frame->lr, ptr, 4, 0); ptr = mem2hex(&__debug_frame->lcr, ptr, 4, 0); ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0); ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0); for (loop = 0; loop <= 7; loop++) ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0); ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0); for (loop = 0; loop <= 1; loop++) ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0); ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0); ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0); ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0); ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0); break; /* set the values of the CPU registers */ case 'G': ptr = &input_buffer[1]; /* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */ ptr = hex2mem(ptr, &temp, 4); for (loop = 1; loop <= 27; loop++) ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop), 4); ptr = hex2mem(ptr, &temp, 4); __frame = (struct pt_regs *) temp; ptr = hex2mem(ptr, &__debug_frame->gr29, 4); ptr = hex2mem(ptr, &__debug_frame->gr30, 4);#ifdef CONFIG_MMU ptr = hex2mem(ptr, &__debug_frame->gr31, 4);#else ptr = hex2mem(ptr, &temp, 4);#endif for (loop = 32; loop <= 63; loop++) ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop), 4); /* deal with FR0-FR63 */ for (loop = 0; loop <= 63; loop++) ptr = mem2hex((unsigned long *)&__break_user_context + __FPMEDIA_FR(loop), ptr, 4, 0); /* deal with special registers */ ptr = hex2mem(ptr, &__debug_frame->pc, 4); ptr = hex2mem(ptr, &__debug_frame->psr, 4); ptr = hex2mem(ptr, &__debug_frame->ccr, 4); ptr = hex2mem(ptr, &__debug_frame->cccr,4); for (loop = 132; loop <= 140; loop++) ptr = hex2mem(ptr, &temp, 4); ptr = hex2mem(ptr, &temp, 4); asm volatile("movgs %0,scr0" :: "r"(temp)); ptr = hex2mem(ptr, &temp, 4); asm volatile("movgs %0,scr1" :: "r"(temp)); ptr = hex2mem(ptr, &temp, 4); asm volatile("movgs %0,scr2" :: "r"(temp)); ptr = hex2mem(ptr, &temp, 4); asm volatile("movgs %0,scr3" :: "r"(temp)); ptr = hex2mem(ptr, &__debug_frame->lr, 4); ptr = hex2mem(ptr, &__debug_frame->lcr, 4); ptr = hex2mem(ptr, &__debug_frame->iacc0, 8); ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4); for (loop = 0; loop <= 7; loop++) ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4); ptr = hex2mem(ptr, &__break_user_context.f.accg, 8); for (loop = 0; loop <= 1; loop++) ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4); ptr = hex2mem(ptr, &__debug_frame->gner0, 4); ptr = hex2mem(ptr, &__debug_frame->gner1, 4); ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4); ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4); gdbstub_strcpy(output_buffer,"OK"); break; /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ case 'm': ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length) ) { if (mem2hex((char *)addr, output_buffer, length, 1)) break; gdbstub_strcpy (output_buffer, "E03"); } else { gdbstub_strcpy(output_buffer,"E01"); } break; /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ case 'M': ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length) && *ptr++ == ':' ) { if (hex2mem(ptr, (char *)addr, length)) { gdbstub_strcpy(output_buffer, "OK"); } else { gdbstub_strcpy(output_buffer, "E03"); } } else gdbstub_strcpy(output_buffer, "E02"); flush_cache = 1; break; /* PNN,=RRRRRRRR: Write value R to reg N return OK */ case 'P': ptr = &input_buffer[1]; if (!hexToInt(&ptr, &addr) || *ptr++ != '=' || !hexToInt(&ptr, &temp) ) { gdbstub_strcpy(output_buffer, "E01"); break; } temp2 = 1; switch (addr) { case GDB_REG_GR(0): break; case GDB_REG_GR(1) ... GDB_REG_GR(63): __break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp; break; case GDB_REG_FR(0) ... GDB_REG_FR(63): __break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp; break; case GDB_REG_PC: __break_user_context.i.pc = temp; break; case GDB_REG_PSR: __break_user_context.i.psr = temp; break; case GDB_REG_CCR: __break_user_context.i.ccr = temp; break; case GDB_REG_CCCR: __break_user_context.i.cccr = temp; break; case GDB_REG_BRR: __debug_regs->brr = temp; break; case GDB_REG_LR: __break_user_context.i.lr = temp; break; case GDB_REG_LCR: __break_user_context.i.lcr = temp; break; case GDB_REG_FSR0: __break_user_context.f.fsr[0] = temp; break; case GDB_REG_ACC(0) ... GDB_REG_ACC(7): __break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp; break; case GDB_REG_ACCG(0): *(uint32_t *) &__break_user_context.f.accg[0] = temp; break; case GDB_REG_ACCG(4): *(uint32_t *) &__break_user_context.f.accg[4] = temp; break; case GDB_REG_MSR(0) ... GDB_REG_MSR(1): __break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp; break; case GDB_REG_GNER(0) ... GDB_REG_GNER(1): __break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp; break; case GDB_REG_FNER(0) ... GDB_REG_FNER(1): __break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp; break; default: temp2 = 0; break; } if (temp2) { gdbstub_strcpy(output_buffer, "OK"); } else { gdbstub_strcpy(output_buffer, "E02"); } break; /* cAA..AA Continue at address AA..AA(optional) */ case 'c': /* try to read optional parameter, pc unchanged if no parm */ ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr)) __debug_frame->pc = addr; goto done; /* kill the program */ case 'k' : goto done; /* just continue */ /* reset the whole machine (FIXME: system dependent) */ case 'r': break; /* step to next instruction */ case 's': __debug_regs->dcr |= DCR_SE; goto done; /* set baud rate (bBB) */ case 'b': ptr = &input_buffer[1]; if (!hexToInt(&ptr, &temp)) { gdbstub_strcpy(output_buffer,"B01"); break; } if (temp) { /* ack before changing speed */ gdbstub_send_packet("OK"); gdbstub_set_baud(temp); } break; /* set breakpoint */ case 'Z': ptr = &input_buffer[1]; if (!hexToInt(&ptr,&temp) || *ptr++ != ',' || !hexToInt(&ptr,&addr) || *ptr++ != ',' || !hexToInt(&ptr,&length) ) { gdbstub_strcpy(output_buffer,"E01"); break; } if (temp >= 5) { gdbstub_strcpy(output_buffer,"E03"); break; } if (gdbstub_set_breakpoint(temp, addr, length) < 0) { gdbstub_strcpy(output_buffer,"E03"); break; } if (temp == 0) flush_cache = 1; /* soft bkpt by modified memory */ gdbstub_strcpy(output_buffer,"OK"); break; /* clear breakpoint */ case 'z': ptr = &input_buffer[1]; if (!hexToInt(&ptr,&temp) || *ptr++ != ',' || !hexToInt(&ptr,&addr) || *ptr++ != ',' || !hexToInt(&ptr,&length) ) { gdbstub_strcpy(output_buffer,"E01"); break; } if (temp >= 5) { gdbstub_strcpy(output_buffer,"E03"); break; } if (gdbstub_clear_breakpoint(temp, addr, length) < 0) { gdbstub_strcpy(output_buffer,"E03"); break; } if (temp == 0) flush_cache = 1; /* soft bkpt by modified memory */ gdbstub_strcpy(output_buffer,"OK"); break; default: gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer); break; } /* reply to the request */ LEDS(0x5009); gdbstub_send_packet(output_buffer); } done: restore_user_regs(&__break_user_context); //gdbstub_dump_debugregs(); //gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc); /* need to flush the instruction cache before resuming, as we may have * deposited a breakpoint, and the icache probably has no way of * knowing that a data ref to some location may have changed something * that is in the instruction cache. NB: We flush both caches, just to * be sure... */ /* note: flushing the icache will clobber EAR0 on the FR451 */ if (flush_cache) gdbstub_purge_cache(); LEDS(0x5666);} /* end gdbstub() *//*****************************************************************************//* * initialise the GDB stub */void __init gdbstub_init(void){#ifdef CONFIG_GDBSTUB_IMMEDIATE unsigned char ch; int ret;#endif gdbstub_printk("%s", gdbstub_banner); gdbstub_printk("DCR: %x\n", __debug_regs->dcr); gdbstub_io_init(); /* try to talk to GDB (or anyone insane enough to want to type GDB protocol by hand) */ gdbstub_proto("### GDB Tx ACK\n"); gdbstub_tx_char('+'); /* 'hello world' */#ifdef CONFIG_GDBSTUB_IMMEDIATE gdbstub_printk("GDB Stub waiting for packet\n"); /* * In case GDB is started before us, ack any packets * (presumably "$?#xx") sitting there. */ do { gdbstub_rx_char(&ch, 0); } while (ch != '$'); do { gdbstub_rx_char(&ch, 0); } while (ch != '#'); do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat first csum byte */ do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat second csum byte */ gdbstub_proto("### GDB Tx NAK\n"); gdbstub_tx_char('-'); /* nak it */#else gdbstub_printk("GDB Stub set\n");#endif#if 0 /* send banner */ ptr = output_buffer; *ptr++ = 'O'; ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0); gdbstub_send_packet(output_buffer);#endif#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE) register_console(&gdbstub_console);#endif} /* end gdbstub_init() *//*****************************************************************************//* * register the console at a more appropriate time */#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)static int __init gdbstub_postinit(void){ printk("registering console\n"); register_console(&gdbstub_console); return 0;} /* end gdbstub_postinit() */__initcall(gdbstub_postinit);#endif/*****************************************************************************//* * send an exit message to GDB */void gdbstub_exit(int status){ unsigned char checksum; int count; unsigned char ch; sprintf(output_buffer,"W%02x",status&0xff); gdbstub_tx_char('$'); checksum = 0; count = 0; while ((ch = output_buffer[count]) != 0) { gdbstub_tx_char(ch); checksum += ch; count += 1; } gdbstub_tx_char('#'); gdbstub_tx_char(hexchars[checksum >> 4]); gdbstub_tx_char(hexchars[checksum & 0xf]); /* make sure the output is flushed, or else RedBoot might clobber it */ gdbstub_tx_char('-'); gdbstub_tx_flush();} /* end gdbstub_exit() *//*****************************************************************************//* * GDB wants to call malloc() and free() to allocate memory for calling kernel * functions directly from its command line */static void *malloc(size_t size) __attribute__((unused));static void *malloc(size_t size){ return kmalloc(size, GFP_ATOMIC);}static void free(void *p) __attribute__((unused));static void free(void *p){ kfree(p);}static uint32_t ___get_HSR0(void) __attribute__((unused));static uint32_t ___get_HSR0(void){ return __get_HSR(0);}static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));static uint32_t ___set_HSR0(uint32_t x){ __set_HSR(0, x); return __get_HSR(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -