DWARF stuff...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.9 KiB

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)
{
int comp_unit;
struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
struct mi_sourcepoint *next_sp;
do {
// TODO: step until source line changes (for active file)
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc);
long instruction = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip, NULL);
next_sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
if (!next_sp) break;
} while (next_sp->line == sp->line);
print_sourcepoint(proc, comp_unit, next_sp);
}
static void
command_start(struct mi_process proc)
{
u64 main_address = proc.base_address + proc.main_address;
long saved_instruction = place_breakpoint_at(proc, main_address);
run_until_breakpoint_and_restore(proc, main_address, saved_instruction);
}
static void
command_next(struct mi_process proc)
{
int comp_unit;
struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
struct mi_sourcepoint *next_sp;
do {
// TODO: step until source line changes (for active file)
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc);
long instruction = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip, NULL);
if (is_call_instruction(instruction)) {
long base_address = regs.rbp;
// NOTE do single step, get return address from stack, place breakpoint there, continue
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0);
regs = get_process_registers(proc);
long return_address = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rsp, NULL);
// NOTE: disambiguate recursive calls
for (;;) {
long saved_instruction = place_breakpoint_at(proc, return_address);
run_until_breakpoint_and_restore(proc, return_address, saved_instruction);
regs = get_process_registers(proc);
long actual_base_address = regs.rbp;
if (base_address == actual_base_address) {
break;
} else {
// NOTE: step to the next instruction after the return address, so that we can add a breakpoint there
ptrace(PTRACE_SINGLESTEP, proc.pid, 0, 0);
waitpid(proc.pid, 0, 0);
}
}
}
// TODO: repXXX
//printf("%#lx\n", regs.rip - proc.base_address);
next_sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
if (!next_sp) break;
} while (next_sp->line == sp->line);
print_sourcepoint(proc, comp_unit, next_sp);
}
static void
command_list(struct mi_process proc)
{
int comp_unit;
struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address, &comp_unit);
print_sourcepoint(proc, comp_unit, 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
}