int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, char *remcomInBuffer, char *remcomOutBuffer, struct pt_regs *regs) { unsigned long addr; char *ptr; undo_single_step(regs); switch (remcomInBuffer[0]) { case 's': case 'c': ptr = &remcomInBuffer[1]; if (kgdb_hex2long(&ptr, &addr)) regs->ret = addr; case 'D': case 'k': atomic_set(&kgdb_cpu_doing_single_step, -1); if (remcomInBuffer[0] == 's') { do_single_step(regs); atomic_set(&kgdb_cpu_doing_single_step, smp_processor_id()); } return 0; } return -1; }
/* * kgdb_arch_handle_exception - Handle architecture specific GDB packets. * @vector: The error vector of the exception that happened. * @signo: The signal number of the exception that happened. * @err_code: The error code of the exception that happened. * @remcom_in_buffer: The buffer of the packet we have read. * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. * @regs: The &struct pt_regs of the current process. * * This function MUST handle the 'c' and 's' command packets, * as well packets to set / remove a hardware breakpoint, if used. * If there are additional packets which the hardware needs to handle, * they are handled here. The code should return -1 if it wants to * process more packets, and a %0 or %1 if it wants to exit from the * kgdb callback. */ int kgdb_arch_handle_exception(int vector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, struct pt_regs *regs) { char *ptr; unsigned long address; /* Undo any stepping we may have done. */ undo_single_step(regs); switch (remcom_in_buffer[0]) { case 'c': case 's': case 'D': case 'k': /* * Try to read optional parameter, pc unchanged if no parm. * If this was a compiled-in breakpoint, we need to move * to the next instruction or we will just breakpoint * over and over again. */ ptr = &remcom_in_buffer[1]; if (kgdb_hex2long(&ptr, &address)) regs->pc = address; else if (*(unsigned long *)regs->pc == compiled_bpt) regs->pc += BREAK_INSTR_SIZE; if (remcom_in_buffer[0] == 's') { do_single_step(regs); kgdb_single_step = 1; atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id()); } else atomic_set(&kgdb_cpu_doing_single_step, -1); return 0; } return -1; /* this means that we do not want to exit from the handler */ }