From e2b28da32fd2778b1d569457898375ba93241144 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Sun, 21 Feb 2016 14:55:34 +0900 Subject: [PATCH] signal handler support gdb stepi command --- arch/x86/kernel/cpu.c | 2 ++ arch/x86/kernel/syscall.c | 23 +++++++++++++++++++++++ kernel/procfs.c | 3 +++ 3 files changed, 28 insertions(+) diff --git a/arch/x86/kernel/cpu.c b/arch/x86/kernel/cpu.c index d8528c97..058b3e90 100644 --- a/arch/x86/kernel/cpu.c +++ b/arch/x86/kernel/cpu.c @@ -893,6 +893,7 @@ void debug_handler(struct x86_user_context *regs) struct siginfo info; set_cputime(interrupt_from_user(regs)? 1: 2); +kprintf("debug_handler rip=%lx\n", regs->gpr.rip); #ifdef DEBUG_PRINT_CPU kprintf("debug exception (err: %lx, %lx:%lx)\n", regs->gpr.error, regs->gpr.cs, regs->gpr.rip); @@ -920,6 +921,7 @@ void int3_handler(struct x86_user_context *regs) struct siginfo info; set_cputime(interrupt_from_user(regs)? 1: 2); +kprintf("int3_handler rip=%lx\n", regs->gpr.rip); #ifdef DEBUG_PRINT_CPU kprintf("int3 exception (err: %lx, %lx:%lx)\n", regs->gpr.error, regs->gpr.cs, regs->gpr.rip); diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index b091e595..957f52dd 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -32,6 +32,8 @@ int write_process_vm(struct process_vm *vm, void *dst, const void *src, size_t s long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact); long syscall(int num, ihk_mc_user_context_t *ctx); extern void save_fp_regs(struct thread *proc); +void set_signal(int sig, void *regs0, siginfo_t *info); +void check_signal(unsigned long rc, void *regs0, int num); //#define DEBUG_PRINT_SC @@ -178,6 +180,17 @@ SYSCALL_DECLARE(rt_sigreturn) if(sigsp->restart){ return syscall(sigsp->num, (ihk_mc_user_context_t *)regs); } + if(regs->gpr.rflags & RFLAGS_TF){ + struct siginfo info; + + regs->gpr.rax = sigsp->sigrc; + memset(&info, '\0', sizeof info); + regs->gpr.rflags &= ~RFLAGS_TF; + info.si_code = TRAP_TRACE; + set_signal(SIGTRAP, regs, &info); + check_signal(0, regs, 0); + check_need_resched(); + } return sigsp->sigrc; } @@ -595,6 +608,16 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi thread->sigmask.__val[0] |= pending->sigmask.__val[0]; kfree(pending); ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate); + if(regs->gpr.rflags & RFLAGS_TF){ + struct siginfo info; + + memset(&info, '\0', sizeof info); + regs->gpr.rflags &= ~RFLAGS_TF; + info.si_code = TRAP_TRACE; + set_signal(SIGTRAP, regs, &info); + check_signal(0, regs, 0); + check_need_resched(); + } } else { int coredumped = 0; diff --git a/kernel/procfs.c b/kernel/procfs.c index 76107d0e..894268b6 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -261,6 +261,9 @@ process_procfs_request(unsigned long rarg) } #endif + if(readwrite == 0) + reason = PF_POPULATE | PF_USER; + while(left){ unsigned long pa; char *va;