[S390] single-step cleanup
Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
ea29ee16e6
commit
0ac30be461
@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task)
|
|||||||
per_info->control_regs.bits.storage_alt_space_ctl = 0;
|
per_info->control_regs.bits.storage_alt_space_ctl = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_single_step(struct task_struct *task)
|
void user_enable_single_step(struct task_struct *task)
|
||||||
{
|
{
|
||||||
task->thread.per_info.single_step = 1;
|
task->thread.per_info.single_step = 1;
|
||||||
FixPerRegisters(task);
|
FixPerRegisters(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_single_step(struct task_struct *task)
|
void user_disable_single_step(struct task_struct *task)
|
||||||
{
|
{
|
||||||
task->thread.per_info.single_step = 0;
|
task->thread.per_info.single_step = 0;
|
||||||
FixPerRegisters(task);
|
FixPerRegisters(task);
|
||||||
@@ -107,7 +107,7 @@ void
|
|||||||
ptrace_disable(struct task_struct *child)
|
ptrace_disable(struct task_struct *child)
|
||||||
{
|
{
|
||||||
/* make sure the single step bit is not set. */
|
/* make sure the single step bit is not set. */
|
||||||
clear_single_step(child);
|
user_disable_single_step(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||||
child->exit_code = data;
|
child->exit_code = data;
|
||||||
/* make sure the single step bit is not set. */
|
/* make sure the single step bit is not set. */
|
||||||
clear_single_step(child);
|
user_disable_single_step(child);
|
||||||
wake_up_process(child);
|
wake_up_process(child);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
return 0;
|
return 0;
|
||||||
child->exit_code = SIGKILL;
|
child->exit_code = SIGKILL;
|
||||||
/* make sure the single step bit is not set. */
|
/* make sure the single step bit is not set. */
|
||||||
clear_single_step(child);
|
user_disable_single_step(child);
|
||||||
wake_up_process(child);
|
wake_up_process(child);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||||
child->exit_code = data;
|
child->exit_code = data;
|
||||||
if (data)
|
user_enable_single_step(child);
|
||||||
set_tsk_thread_flag(child, TIF_SINGLE_STEP);
|
|
||||||
else
|
|
||||||
set_single_step(child);
|
|
||||||
/* give it a chance to run. */
|
/* give it a chance to run. */
|
||||||
wake_up_process(child);
|
wake_up_process(child);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs)
|
|||||||
|
|
||||||
if (signr > 0) {
|
if (signr > 0) {
|
||||||
/* Whee! Actually deliver the signal. */
|
/* Whee! Actually deliver the signal. */
|
||||||
|
int ret;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
if (test_thread_flag(TIF_31BIT)) {
|
if (test_thread_flag(TIF_31BIT)) {
|
||||||
extern int handle_signal32(unsigned long sig,
|
extern int handle_signal32(unsigned long sig,
|
||||||
@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs)
|
|||||||
siginfo_t *info,
|
siginfo_t *info,
|
||||||
sigset_t *oldset,
|
sigset_t *oldset,
|
||||||
struct pt_regs *regs);
|
struct pt_regs *regs);
|
||||||
if (handle_signal32(
|
ret = handle_signal32(signr, &ka, &info, oldset, regs);
|
||||||
signr, &ka, &info, oldset, regs) == 0) {
|
|
||||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
|
||||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
|
ret = handle_signal(signr, &ka, &info, oldset, regs);
|
||||||
|
if (!ret) {
|
||||||
/*
|
/*
|
||||||
* A signal was successfully delivered; the saved
|
* A signal was successfully delivered; the saved
|
||||||
* sigmask will have been stored in the signal frame,
|
* sigmask will have been stored in the signal frame,
|
||||||
@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs)
|
|||||||
*/
|
*/
|
||||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we would have taken a single-step trap
|
||||||
|
* for a normal instruction, act like we took
|
||||||
|
* one for the handler setup.
|
||||||
|
*/
|
||||||
|
if (current->thread.per_info.single_step)
|
||||||
|
set_thread_flag(TIF_SINGLE_STEP);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -465,6 +465,14 @@ struct user_regs_struct
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#define __ARCH_SYS_PTRACE 1
|
#define __ARCH_SYS_PTRACE 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are defined as per linux/ptrace.h, which see.
|
||||||
|
*/
|
||||||
|
#define arch_has_single_step() (1)
|
||||||
|
struct task_struct;
|
||||||
|
extern void user_enable_single_step(struct task_struct *);
|
||||||
|
extern void user_disable_single_step(struct task_struct *);
|
||||||
|
|
||||||
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
|
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
|
||||||
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
|
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
|
||||||
#define regs_return_value(regs)((regs)->gprs[2])
|
#define regs_return_value(regs)((regs)->gprs[2])
|
||||||
|
Reference in New Issue
Block a user