static int parasite_execute_by_pid(unsigned int cmd, struct parasite_ctl *ctl, pid_t pid) { int ret; user_regs_struct_t regs_orig, regs; if (ctl->pid.real == pid) regs = ctl->regs_orig; else { if (ptrace(PTRACE_GETREGS, pid, NULL, ®s_orig)) { pr_perror("Can't obtain registers (pid: %d)", pid); return -1; } regs = regs_orig; } *ctl->addr_cmd = cmd; parasite_setup_regs(ctl->parasite_ip, ®s); ret = __parasite_execute(ctl, pid, ®s); if (ret == 0) ret = (int)REG_RES(regs); if (ret) pr_err("Parasite exited with %d\n", ret); if (ctl->pid.real != pid) if (ptrace(PTRACE_SETREGS, pid, NULL, ®s_orig)) { pr_perror("Can't restore registers (pid: %d)", pid); return -1; } return ret; }
int compel_run_in_thread(struct parasite_thread_ctl *tctl, unsigned int cmd) { int pid = tctl->tid; struct parasite_ctl *ctl = tctl->ctl; struct thread_ctx *octx = &tctl->th; void *stack = ctl->r_thread_stack; user_regs_struct_t regs = octx->regs; int ret; *ctl->addr_cmd = cmd; ret = parasite_run(pid, PTRACE_CONT, ctl->parasite_ip, stack, ®s, octx); if (ret == 0) ret = parasite_trap(ctl, pid, ®s, octx); if (ret == 0) ret = (int)REG_RES(regs); if (ret) pr_err("Parasite exited with %d\n", ret); return ret; }