diff options
Diffstat (limited to 'arch/tile')
-rw-r--r-- | arch/tile/include/asm/ptrace.h | 3 | ||||
-rw-r--r-- | arch/tile/kernel/process.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/single_step.c | 21 |
3 files changed, 26 insertions, 2 deletions
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index ac6d343129d3..6be2246e015c 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h @@ -141,6 +141,9 @@ struct single_step_state { /* Single-step the instruction at regs->pc */ extern void single_step_once(struct pt_regs *regs); +/* Clean up after execve(). */ +extern void single_step_execve(void); + struct task_struct; extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index e90eb53173b0..5db8b5b63cea 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -574,6 +574,8 @@ SYSCALL_DEFINE4(execve, const char __user *, path, goto out; error = do_execve(filename, argv, envp, regs); putname(filename); + if (error == 0) + single_step_execve(); out: return error; } @@ -593,6 +595,8 @@ long compat_sys_execve(const char __user *path, goto out; error = compat_do_execve(filename, argv, envp, regs); putname(filename); + if (error == 0) + single_step_execve(); out: return error; } diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index 1eb3b39e36c7..84a729e06ec4 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c @@ -56,7 +56,7 @@ enum mem_op { MEMOP_STORE_POSTINCR }; -static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, int32_t offset) +static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset) { tile_bundle_bits result; @@ -254,6 +254,18 @@ P("\n"); return bundle; } +/* + * Called after execve() has started the new image. This allows us + * to reset the info state. Note that the the mmap'ed memory, if there + * was any, has already been unmapped by the exec. + */ +void single_step_execve(void) +{ + struct thread_info *ti = current_thread_info(); + kfree(ti->step_state); + ti->step_state = NULL; +} + /** * single_step_once() - entry point when single stepping has been triggered. * @regs: The machine register state @@ -373,7 +385,7 @@ void single_step_once(struct pt_regs *regs) /* branches */ case BRANCH_OPCODE_X1: { - int32_t offset = signExtend17(get_BrOff_X1(bundle)); + s32 offset = signExtend17(get_BrOff_X1(bundle)); /* * For branches, we use a rewriting trick to let the @@ -731,4 +743,9 @@ void single_step_once(struct pt_regs *regs) __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL); } +void single_step_execve(void) +{ + /* Nothing */ +} + #endif /* !__tilegx__ */ |