📄 sh-lite.patch
字号:
-- case USER_BREAK_VEC:- case TRAP_VEC:- sigval = SIGTRAP;- break;-- default:- sigval = SIGBUS; /* "software generated" */- break;- }-- return (sigval);-}--/* Make a local copy of the registers passed into the handler (bletch) */-static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,- int *gdb_regs)-{- gdb_regs[R0] = regs->regs[R0];- gdb_regs[R1] = regs->regs[R1];- gdb_regs[R2] = regs->regs[R2];- gdb_regs[R3] = regs->regs[R3];- gdb_regs[R4] = regs->regs[R4];- gdb_regs[R5] = regs->regs[R5];- gdb_regs[R6] = regs->regs[R6];- gdb_regs[R7] = regs->regs[R7];- gdb_regs[R8] = regs->regs[R8];- gdb_regs[R9] = regs->regs[R9];- gdb_regs[R10] = regs->regs[R10];- gdb_regs[R11] = regs->regs[R11];- gdb_regs[R12] = regs->regs[R12];- gdb_regs[R13] = regs->regs[R13];- gdb_regs[R14] = regs->regs[R14];- gdb_regs[R15] = regs->regs[R15];- gdb_regs[PC] = regs->pc;- gdb_regs[PR] = regs->pr;- gdb_regs[GBR] = regs->gbr;- gdb_regs[MACH] = regs->mach;- gdb_regs[MACL] = regs->macl;- gdb_regs[SR] = regs->sr;- gdb_regs[VBR] = regs->vbr;-}--/* Copy local gdb registers back to kgdb regs, for later copy to kernel */-static void gdb_regs_to_kgdb_regs(const int *gdb_regs,- struct kgdb_regs *regs)-{- regs->regs[R0] = gdb_regs[R0];- regs->regs[R1] = gdb_regs[R1];- regs->regs[R2] = gdb_regs[R2];- regs->regs[R3] = gdb_regs[R3];- regs->regs[R4] = gdb_regs[R4];- regs->regs[R5] = gdb_regs[R5];- regs->regs[R6] = gdb_regs[R6];- regs->regs[R7] = gdb_regs[R7];- regs->regs[R8] = gdb_regs[R8];- regs->regs[R9] = gdb_regs[R9];- regs->regs[R10] = gdb_regs[R10];- regs->regs[R11] = gdb_regs[R11];- regs->regs[R12] = gdb_regs[R12];- regs->regs[R13] = gdb_regs[R13];- regs->regs[R14] = gdb_regs[R14];- regs->regs[R15] = gdb_regs[R15];- regs->pc = gdb_regs[PC];- regs->pr = gdb_regs[PR];- regs->gbr = gdb_regs[GBR];- regs->mach = gdb_regs[MACH];- regs->macl = gdb_regs[MACL];- regs->sr = gdb_regs[SR];- regs->vbr = gdb_regs[VBR];-}--#ifdef CONFIG_KGDB_THREAD-/* Make a local copy of registers from the specified thread */-asmlinkage void ret_from_fork(void);-static void thread_regs_to_gdb_regs(const struct task_struct *thread,- int *gdb_regs)-{- int regno;- int *tregs;-- /* Initialize to zero */- for (regno = 0; regno < MAXREG; regno++)- gdb_regs[regno] = 0;-- /* Just making sure... */- if (thread == NULL)- return;-- /* A new fork has pt_regs on the stack from a fork() call */- if (thread->thread.pc == (unsigned long)ret_from_fork) {-- int vbr_val;- struct pt_regs *kregs;- kregs = (struct pt_regs*)thread->thread.sp;-- gdb_regs[R0] = kregs->regs[R0];- gdb_regs[R1] = kregs->regs[R1];- gdb_regs[R2] = kregs->regs[R2];- gdb_regs[R3] = kregs->regs[R3];- gdb_regs[R4] = kregs->regs[R4];- gdb_regs[R5] = kregs->regs[R5];- gdb_regs[R6] = kregs->regs[R6];- gdb_regs[R7] = kregs->regs[R7];- gdb_regs[R8] = kregs->regs[R8];- gdb_regs[R9] = kregs->regs[R9];- gdb_regs[R10] = kregs->regs[R10];- gdb_regs[R11] = kregs->regs[R11];- gdb_regs[R12] = kregs->regs[R12];- gdb_regs[R13] = kregs->regs[R13];- gdb_regs[R14] = kregs->regs[R14];- gdb_regs[R15] = kregs->regs[R15];- gdb_regs[PC] = kregs->pc;- gdb_regs[PR] = kregs->pr;- gdb_regs[GBR] = kregs->gbr;- gdb_regs[MACH] = kregs->mach;- gdb_regs[MACL] = kregs->macl;- gdb_regs[SR] = kregs->sr;-- asm("stc vbr, %0":"=r"(vbr_val));- gdb_regs[VBR] = vbr_val;- return;- }-- /* Otherwise, we have only some registers from switch_to() */- tregs = (int *)thread->thread.sp;- gdb_regs[R15] = (int)tregs;- gdb_regs[R14] = *tregs++;- gdb_regs[R13] = *tregs++;- gdb_regs[R12] = *tregs++;- gdb_regs[R11] = *tregs++;- gdb_regs[R10] = *tregs++;- gdb_regs[R9] = *tregs++;- gdb_regs[R8] = *tregs++;- gdb_regs[PR] = *tregs++;- gdb_regs[GBR] = *tregs++;- gdb_regs[PC] = thread->thread.pc;-}-#endif /* CONFIG_KGDB_THREAD */--/* Calculate the new address for after a step */-static short *get_step_address(void)-{- short op = *(short *) trap_registers.pc;- long addr;-- /* BT */- if (OPCODE_BT(op)) {- if (trap_registers.sr & SR_T_BIT_MASK)- addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);- else- addr = trap_registers.pc + 2;- }-- /* BTS */- else if (OPCODE_BTS(op)) {- if (trap_registers.sr & SR_T_BIT_MASK)- addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);- else- addr = trap_registers.pc + 4; /* Not in delay slot */- }-- /* BF */- else if (OPCODE_BF(op)) {- if (!(trap_registers.sr & SR_T_BIT_MASK))- addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);- else- addr = trap_registers.pc + 2;- }-- /* BFS */- else if (OPCODE_BFS(op)) {- if (!(trap_registers.sr & SR_T_BIT_MASK))- addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);- else- addr = trap_registers.pc + 4; /* Not in delay slot */- }-- /* BRA */- else if (OPCODE_BRA(op))- addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);-- /* BRAF */- else if (OPCODE_BRAF(op))- addr = trap_registers.pc + 4- + trap_registers.regs[OPCODE_BRAF_REG(op)];-- /* BSR */- else if (OPCODE_BSR(op))- addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);-- /* BSRF */- else if (OPCODE_BSRF(op))- addr = trap_registers.pc + 4- + trap_registers.regs[OPCODE_BSRF_REG(op)];-- /* JMP */- else if (OPCODE_JMP(op))- addr = trap_registers.regs[OPCODE_JMP_REG(op)];-- /* JSR */- else if (OPCODE_JSR(op))- addr = trap_registers.regs[OPCODE_JSR_REG(op)];-- /* RTS */- else if (OPCODE_RTS(op))- addr = trap_registers.pr;-- /* RTE */- else if (OPCODE_RTE(op))- addr = trap_registers.regs[15];-- /* Other */- else- addr = trap_registers.pc + 2;-- kgdb_flush_icache_range(addr, addr + 2);- return (short *) addr;-}--/* Set up a single-step. Replace the instruction immediately after the - current instruction (i.e. next in the expected flow of control) with a- trap instruction, so that returning will cause only a single instruction- to be executed. Note that this model is slightly broken for instructions- with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch- and the instruction in the delay slot will be executed. */-static void do_single_step(void)-{- unsigned short *addr = 0;-- /* Determine where the target instruction will send us to */- addr = get_step_address();- stepped_address = (int)addr;-- /* Replace it */- stepped_opcode = *(short *)addr;- *addr = STEP_OPCODE;-- /* Flush and return */- kgdb_flush_icache_range((long) addr, (long) addr + 2);- return;-}--/* Undo a single step */-static void undo_single_step(void)-{- /* If we have stepped, put back the old instruction */- /* Use stepped_address in case we stopped elsewhere */- if (stepped_opcode != 0) {- *(short*)stepped_address = stepped_opcode;- kgdb_flush_icache_range(stepped_address, stepped_address + 2);- }- stepped_opcode = 0;-}--/* Send a signal message */-static void send_signal_msg(const int signum)-{-#ifndef CONFIG_KGDB_THREAD- out_buffer[0] = 'S';- out_buffer[1] = highhex(signum);- out_buffer[2] = lowhex(signum);- out_buffer[3] = 0;- put_packet(out_buffer);-#else /* CONFIG_KGDB_THREAD */- int threadid;- threadref thref;- char *out = out_buffer;- const char *tstring = "thread";-- *out++ = 'T';- *out++ = highhex(signum);- *out++ = lowhex(signum);-- while (*tstring) {- *out++ = *tstring++;- }- *out++ = ':';-- threadid = trapped_thread->pid;- if (threadid == 0) threadid = PID_MAX;- int_to_threadref(&thref, threadid);- pack_threadid(out, &thref);- out += BUF_THREAD_ID_SIZE;- *out++ = ';';-- *out = 0;- put_packet(out_buffer);-#endif /* CONFIG_KGDB_THREAD */-}--/* Reply that all was well */-static void send_ok_msg(void)-{- strcpy(out_buffer, "OK");- put_packet(out_buffer);-}--/* Reply that an error occurred */-static void send_err_msg(void)-{- strcpy(out_buffer, "E01");- put_packet(out_buffer);-}--/* Empty message indicates unrecognised command */-static void send_empty_msg(void)-{- put_packet("");-}--/* Read memory due to 'm' message */-static void read_mem_msg(void)-{- char *ptr;- int addr;- int length;-- /* Jmp, disable bus error handler */- if (setjmp(rem_com_env) == 0) {-- kgdb_nofault = 1;-- /* Walk through, have m<addr>,<length> */- ptr = &in_buffer[1];- if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))- if (hex_to_int(&ptr, &length)) {- ptr = 0;- if (length * 2 > OUTBUFMAX)- length = OUTBUFMAX / 2;- mem_to_hex((char *) addr, out_buffer, length);- }- if (ptr)- send_err_msg();- else- put_packet(out_buffer);- } else- send_err_msg();-- /* Restore bus error handler */- kgdb_nofault = 0;-}--/* Write memory due to 'M' or 'X' message */-static void write_mem_msg(int binary)-{- char *ptr;- int addr;- int length;-- if (setjmp(rem_com_env) == 0) {-- kgdb_nofault = 1;-- /* Walk through, have M<addr>,<length>:<data> */- ptr = &in_buffer[1];- if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))- if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {- if (binary)- ebin_to_mem(ptr, (char*)addr, length);- else- hex_to_mem(ptr, (char*)addr, length);- kgdb_flush_icache_range(addr, addr + length);- ptr = 0;- send_ok_msg();- }- if (ptr)- send_err_msg();- } else- send_err_msg();-- /* Restore bus error handler */- kgdb_nofault = 0;-}--/* Continue message */-static void continue_msg(void)-{- /* Try to read optional parameter, PC unchanged if none */- char *ptr = &in_buffer[1];- int addr;-- if (hex_to_int(&ptr, &addr))- trap_registers.pc = addr;-}--/* Continue message with signal */-static void continue_with_sig_msg(void)-{- int signal;- char *ptr = &in_buffer[1];- int addr;-- /* Report limitation */- kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");-- /* Signal */- hex_to_int(&ptr, &signal);- if (*ptr == ';')- ptr++;-- /* Optional address */- if (hex_to_int(&ptr, &addr))- trap_registers.pc = addr;-}--/* Step message */-static void step_msg(void)-{- continue_msg();- do_single_step();-}--/* Step message with signal */-static void step_with_sig_msg(void)-{- continue_with_sig_msg();- do_single_step();-}--/* Send register contents */-static void send_regs_msg(void)-{-#ifdef CONFIG_KGDB_THREAD- if (!current_thread)- kgdb_regs_to_gdb_regs(&trap_registers, registers);- else- thread_regs_to_gdb_regs(current_thread, registers);-#else- kgdb_regs_to_gdb_regs(&trap_registers, registers);-#endif-- mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);- put_packet(out_buffer);-}--/* Set register contents - currently can't set other thread's registers */-static void set_regs_msg(void)-{-#ifdef CONFIG_KGDB_THREAD- if (!current_thread) {-#endif- kgdb_regs_to_gdb_regs(&trap_registers, registers);- hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);- gdb_regs_to_kgdb_regs(registers, &trap_registers);- send_ok_msg();-#ifdef CONFIG_KGDB_THREAD- } else- send_err_msg();-#endif-}---#ifdef CONFIG_KGDB_THREAD--/* Set the status for a thread */-void set_thread_msg(void)-{- int threadid;- struct task_struct *thread = NULL;- char *ptr;-- switch (in_buffer[1]) {-- /* To select which thread for gG etc messages, i.e. supported */- case 'g':-- ptr = &in_buffer[2];- hex_to_int(&ptr, &threadid);- thread = get_thread(threadid);-- /* If we haven't found it */- if (!thread) {- send_err_msg();- break;- }-- /* Set current_thread (or not) */- if (thread == trapped_thread)- current_thread = NULL;- else- current_thread = thread;- send_ok_msg();- break;-- /* To select which thread for cCsS messages, i.e. unsupported */- case 'c':- send_ok_msg();- break;-- default:- send_empty_msg();- break;- }-}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -