fix PTRACE_PEEKUSER, PTRACE_POKEUSER, PTRACE_GETREGS.

support PTRACE_SETREGS.
  In struct process, add 'unsigned long *ptrace_debugreg', instead of 'struct user *userp'.
  debug registers are read/written from/to ptrace_debugreg, save/restore in schedule().
  most general registers are proc->uctx.
  fs_base is proc->thread.tlsblock_base.
  gs_base,ds,es,fs,gs and orig_rax are uncompleted.
  other members in 'struct user' are ignored, same as Linux implementation.

refs #257
refs #373
refs #263
This commit is contained in:
Susumu Komae
2015-01-29 14:08:38 +09:00
committed by postpeta
parent 9c35935671
commit c3ade864d9
5 changed files with 296 additions and 98 deletions

View File

@ -43,6 +43,11 @@
#endif
extern long do_arch_prctl(unsigned long code, unsigned long address);
extern long alloc_debugreg(struct process *proc);
extern void save_debugreg(unsigned long *debugreg);
extern void restore_debugreg(unsigned long *debugreg);
extern void clear_debugreg(void);
extern void clear_single_step(struct process *proc);
static void insert_vm_range_list(struct process_vm *vm,
struct vm_range *newrange);
static int copy_user_ranges(struct process *proc, struct process *org);
@ -378,6 +383,13 @@ int ptrace_traceme(void){
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
if (proc->ptrace_debugreg == NULL) {
error = alloc_debugreg(proc);
}
clear_single_step(proc);
/* TODO: other flags may reset */
out:
dkprintf("ptrace_traceme,returning,error=%d\n", error);
return error;
@ -1803,6 +1815,9 @@ void destroy_process(struct process *proc)
list_del(&pending->list);
kfree(pending);
}
if (proc->ptrace_debugreg) {
kfree(proc->ptrace_debugreg);
}
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
}
@ -2043,6 +2058,16 @@ redo:
ihk_mc_get_processor_id(),
prev ? prev->ftn->tid : 0, next ? next->ftn->tid : 0);
if (prev && prev->ptrace_debugreg) {
save_debugreg(prev->ptrace_debugreg);
if (next->ptrace_debugreg == NULL) {
clear_debugreg();
}
}
if (next->ptrace_debugreg) {
restore_debugreg(next->ptrace_debugreg);
}
ihk_mc_load_page_table(next->vm->page_table);
dkprintf("[%d] schedule: tlsblock_base: 0x%lX\n",