Commit 857fb252a1858ccded2e31ee98c6c0ab79c07999
Committed by
Linus Torvalds
1 parent
1d8393171b
Exists in
master
and in
7 other branches
h8300: use generic ptrace_resume code
Use the generic ptrace_resume code for PTRACE_SYSCALL, PTRACE_CONT, PTRACE_KILL and PTRACE_SINGLESTEP. This implies defining arch_has_single_step in <asm/ptrace.h> and implementing the user_enable_single_step and user_disable_single_step functions, which also causes the breakpoint information to be cleared on fork, which could be considered a bug fix. Also the TIF_SYSCALL_TRACE thread flag is now cleared on PTRACE_KILL which it previously wasn't which is consistent with all architectures using the modern ptrace code. Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Roland McGrath <roland@redhat.com> Cc: Yoshinori Sato <ysato@users.sourceforge.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 4 changed files with 13 additions and 51 deletions Side-by-side Diff
arch/h8300/include/asm/ptrace.h
... | ... | @@ -55,6 +55,8 @@ |
55 | 55 | /* Find the stack offset for a register, relative to thread.esp0. */ |
56 | 56 | #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) |
57 | 57 | |
58 | +#define arch_has_single_step() (1) | |
59 | + | |
58 | 60 | #define user_mode(regs) (!((regs)->ccr & PS_S)) |
59 | 61 | #define instruction_pointer(regs) ((regs)->pc) |
60 | 62 | #define profile_pc(regs) instruction_pointer(regs) |
arch/h8300/kernel/ptrace.c
... | ... | @@ -34,9 +34,12 @@ |
34 | 34 | /* cpu depend functions */ |
35 | 35 | extern long h8300_get_reg(struct task_struct *task, int regno); |
36 | 36 | extern int h8300_put_reg(struct task_struct *task, int regno, unsigned long data); |
37 | -extern void h8300_disable_trace(struct task_struct *child); | |
38 | -extern void h8300_enable_trace(struct task_struct *child); | |
39 | 37 | |
38 | + | |
39 | +void user_disable_single_step(struct task_struct *child) | |
40 | +{ | |
41 | +} | |
42 | + | |
40 | 43 | /* |
41 | 44 | * does not yet catch signals sent when the child dies. |
42 | 45 | * in exit.c or in signal.c. |
... | ... | @@ -44,7 +47,7 @@ |
44 | 47 | |
45 | 48 | void ptrace_disable(struct task_struct *child) |
46 | 49 | { |
47 | - h8300_disable_trace(child); | |
50 | + user_disable_single_step(child); | |
48 | 51 | } |
49 | 52 | |
50 | 53 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
... | ... | @@ -107,49 +110,6 @@ |
107 | 110 | } |
108 | 111 | ret = -EIO; |
109 | 112 | break ; |
110 | - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | |
111 | - case PTRACE_CONT: { /* restart after signal. */ | |
112 | - ret = -EIO; | |
113 | - if (!valid_signal(data)) | |
114 | - break ; | |
115 | - if (request == PTRACE_SYSCALL) | |
116 | - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | |
117 | - else | |
118 | - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | |
119 | - child->exit_code = data; | |
120 | - wake_up_process(child); | |
121 | - /* make sure the single step bit is not set. */ | |
122 | - h8300_disable_trace(child); | |
123 | - ret = 0; | |
124 | - } | |
125 | - | |
126 | -/* | |
127 | - * make the child exit. Best I can do is send it a sigkill. | |
128 | - * perhaps it should be put in the status that it wants to | |
129 | - * exit. | |
130 | - */ | |
131 | - case PTRACE_KILL: { | |
132 | - | |
133 | - ret = 0; | |
134 | - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | |
135 | - break; | |
136 | - child->exit_code = SIGKILL; | |
137 | - h8300_disable_trace(child); | |
138 | - wake_up_process(child); | |
139 | - break; | |
140 | - } | |
141 | - | |
142 | - case PTRACE_SINGLESTEP: { /* set the trap flag. */ | |
143 | - ret = -EIO; | |
144 | - if (!valid_signal(data)) | |
145 | - break; | |
146 | - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | |
147 | - child->exit_code = data; | |
148 | - h8300_enable_trace(child); | |
149 | - wake_up_process(child); | |
150 | - ret = 0; | |
151 | - break; | |
152 | - } | |
153 | 113 | |
154 | 114 | case PTRACE_GETREGS: { /* Get all gp regs from the child. */ |
155 | 115 | int i; |
arch/h8300/platform/h8300h/ptrace_h8300h.c
... | ... | @@ -60,7 +60,7 @@ |
60 | 60 | } |
61 | 61 | |
62 | 62 | /* disable singlestep */ |
63 | -void h8300_disable_trace(struct task_struct *child) | |
63 | +void user_disable_single_step(struct task_struct *child) | |
64 | 64 | { |
65 | 65 | if((long)child->thread.breakinfo.addr != -1L) { |
66 | 66 | *child->thread.breakinfo.addr = child->thread.breakinfo.inst; |
... | ... | @@ -264,7 +264,7 @@ |
264 | 264 | |
265 | 265 | /* Set breakpoint(s) to simulate a single step from the current PC. */ |
266 | 266 | |
267 | -void h8300_enable_trace(struct task_struct *child) | |
267 | +void user_enable_single_step(struct task_struct *child) | |
268 | 268 | { |
269 | 269 | unsigned short *nextpc; |
270 | 270 | nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC)); |
... | ... | @@ -276,7 +276,7 @@ |
276 | 276 | asmlinkage void trace_trap(unsigned long bp) |
277 | 277 | { |
278 | 278 | if ((unsigned long)current->thread.breakinfo.addr == bp) { |
279 | - h8300_disable_trace(current); | |
279 | + user_disable_single_step(current); | |
280 | 280 | force_sig(SIGTRAP,current); |
281 | 281 | } else |
282 | 282 | force_sig(SIGILL,current); |
arch/h8300/platform/h8s/ptrace_h8s.c
... | ... | @@ -65,13 +65,13 @@ |
65 | 65 | } |
66 | 66 | |
67 | 67 | /* disable singlestep */ |
68 | -void h8300_disable_trace(struct task_struct *child) | |
68 | +void user_disable_single_step(struct task_struct *child) | |
69 | 69 | { |
70 | 70 | *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE; |
71 | 71 | } |
72 | 72 | |
73 | 73 | /* enable singlestep */ |
74 | -void h8300_enable_trace(struct task_struct *child) | |
74 | +void user_enable_single_step(struct task_struct *child) | |
75 | 75 | { |
76 | 76 | *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE; |
77 | 77 | } |