static void command_regs(struct mi_process proc) { struct mi_registers regs = get_process_registers(proc); printf("rax = %#018lx rcx = %#018lx\n" "rbp = %#018lx rbx = %#018lx\n" "rdx = %#018lx rsi = %#018lx\n" "rdi = %#018lx rip = %#018lx\n" "rsp = %#018lx\n", regs.rax, regs.rcx, regs.rbp, regs.rbx, regs.rdx, regs.rsi, regs.rdi, regs.rip, regs.rsp); } static void command_step(struct mi_process proc) { ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0); waitpid(proc.pid, 0, 0); #if 1 print_current_instruction(proc); struct mi_registers regs = get_process_registers(proc); struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); print_sourcepoint(proc, sp); #endif } static void command_start(struct mi_process proc) { u64 main_address = proc.base_address + proc.main_address; long saved_instruction = ptrace(PTRACE_PEEKDATA, proc.pid, main_address, NULL); long int3_byte = 0x000000000000cc; long int3_word = (saved_instruction & 0xFFFFFFFFFFFFFF00) | int3_byte; /* write 0xcc */ ptrace(PTRACE_POKEDATA, proc.pid, main_address, int3_word); /* wait till child hits the interrupt */ ptrace(PTRACE_CONT, proc.pid, 0, 0); waitpid(proc.pid, 0, 0); /* restore original instrucion */ ptrace(PTRACE_POKEDATA, proc.pid, main_address, saved_instruction); /* step back to original instruction */ struct mi_registers regs = get_process_registers(proc); regs.rip -= 1; set_process_registers(proc, regs); } static void command_next(struct mi_process proc) { struct mi_registers regs = get_process_registers(proc); struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); struct mi_sourcepoint *next_sp; do { ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0); waitpid(proc.pid, 0, 0); regs = get_process_registers(proc); //printf("%#lx\n", regs.rip - proc.base_address); next_sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); // TODO: skip call, repXXX, etc if (!next_sp) break; } while (next_sp->line == sp->line); print_sourcepoint(proc, next_sp); } static void command_list(struct mi_process proc) { struct mi_registers regs = get_process_registers(proc); struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); print_sourcepoint(proc, sp); } static void command_cont(struct mi_process proc) { ptrace(PTRACE_CONT, proc.pid, 0, 0); } static void command_stop(struct mi_process proc) { kill(proc.pid, SIGINT); // TODO }