2 * arch/s390/kernel/ptrace.c
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
8 * Based on PowerPC version
9 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
11 * Derived from "arch/m68k/kernel/ptrace.c"
12 * Copyright (C) 1994 by Hamish Macdonald
13 * Taken from linux/kernel/ptrace.c and modified for M680x0.
14 * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
16 * Modified by Cort Dougan (cort@cs.nmt.edu)
19 * This file is subject to the terms and conditions of the GNU General
20 * Public License. See the file README.legal in the main directory of
21 * this archive for more details.
25 #include <linux/config.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
29 #include <linux/smp.h>
30 #include <linux/smp_lock.h>
31 #include <linux/errno.h>
32 #include <linux/ptrace.h>
33 #include <linux/user.h>
35 #include <asm/segment.h>
37 #include <asm/pgtable.h>
38 #include <asm/pgalloc.h>
39 #include <asm/system.h>
40 #include <asm/uaccess.h>
41 #ifdef CONFIG_S390_SUPPORT
44 #define parent_31bit 0
48 void FixPerRegisters(struct task_struct *task)
50 struct pt_regs *regs = __KSTK_PTREGS(task);
52 (per_struct *)&task->thread.per_info;
54 per_info->control_regs.bits.em_instruction_fetch =
55 per_info->single_step | per_info->instruction_fetch;
57 if (per_info->single_step) {
58 per_info->control_regs.bits.starting_addr=0;
59 #ifdef CONFIG_S390_SUPPORT
60 if (current->thread.flags & S390_FLAG_31BIT) {
61 per_info->control_regs.bits.ending_addr=0x7fffffffUL;
66 per_info->control_regs.bits.ending_addr=-1L;
69 per_info->control_regs.bits.starting_addr=
70 per_info->starting_addr;
71 per_info->control_regs.bits.ending_addr=
72 per_info->ending_addr;
74 /* if any of the control reg tracing bits are on
75 we switch on per in the psw */
76 if (per_info->control_regs.words.cr[0] & PER_EM_MASK)
77 regs->psw.mask |= PSW_PER_MASK;
79 regs->psw.mask &= ~PSW_PER_MASK;
80 if (per_info->control_regs.bits.storage_alt_space_ctl)
81 task->thread.user_seg |= USER_STD_MASK;
83 task->thread.user_seg &= ~USER_STD_MASK;
86 void set_single_step(struct task_struct *task)
88 per_struct *per_info= (per_struct *) &task->thread.per_info;
90 per_info->single_step = 1; /* Single step */
91 FixPerRegisters (task);
94 void clear_single_step(struct task_struct *task)
96 per_struct *per_info= (per_struct *) &task->thread.per_info;
98 per_info->single_step = 0;
99 FixPerRegisters (task);
102 int ptrace_usercopy(addr_t realuseraddr, addr_t copyaddr, int len,
103 int tofromuser, int writeuser, unsigned long mask)
105 unsigned long *realuserptr, *copyptr;
106 unsigned long tempuser;
110 realuserptr = (unsigned long *) realuseraddr;
111 copyptr = (unsigned long *) copyaddr;
113 if (writeuser && realuserptr == NULL)
117 tempuser = *realuserptr;
120 realuserptr = &tempuser;
125 retval = copy_from_user(realuserptr, copyptr, len);
127 if (realuserptr == NULL)
128 retval = clear_user(copyptr, len);
130 retval = copy_to_user(copyptr,realuserptr,len);
132 retval = retval ? -EFAULT : 0;
135 memcpy(realuserptr, copyptr, len);
137 memcpy(copyptr, realuserptr, len);
139 if (mask != -1L && writeuser)
140 *realuserptr = (*realuserptr & mask) | (tempuser & ~mask);
144 #ifdef CONFIG_S390_SUPPORT
149 } per_cr_words32 __attribute__((packed));
153 __u16 perc_atmid; /* 0x096 */
154 __u32 address; /* 0x098 */
155 __u8 access_id; /* 0x0a1 */
156 } per_lowcore_words32 __attribute__((packed));
161 per_cr_words32 words;
162 } control_regs __attribute__((packed));
164 * Use these flags instead of setting em_instruction_fetch
165 * directly they are used so that single stepping can be
166 * switched on & off while not affecting other tracing
168 unsigned single_step : 1;
169 unsigned instruction_fetch : 1;
172 * These addresses are copied into cr10 & cr11 if single
173 * stepping is switched off
178 per_lowcore_words32 words;
180 } per_struct32 __attribute__((packed));
182 struct user_regs_struct32
188 s390_fp_regs fp_regs;
190 * These per registers are in here so that gdb can modify them
191 * itself as there is no "official" ptrace interface for hardware
192 * watchpoints. This is the way intel does it.
194 per_struct32 per_info;
195 u32 ieee_instruction_pointer;
196 /* Used to give failing instruction back to user for ieee exceptions */
200 /* We start with the registers, to mimic the way that "memory" is returned
201 from the ptrace(3,...) function. */
202 struct user_regs_struct32 regs; /* Where the registers are actually stored */
203 /* The rest of this junk is to help gdb figure out what goes where */
204 u32 u_tsize; /* Text segment size (pages). */
205 u32 u_dsize; /* Data segment size (pages). */
206 u32 u_ssize; /* Stack segment size (pages). */
207 u32 start_code; /* Starting virtual address of text. */
208 u32 start_stack; /* Starting virtual address of stack area.
209 This is actually the bottom of the stack,
210 the top of the stack is always found in the
212 s32 signal; /* Signal that caused the core dump. */
213 u32 u_ar0; /* Used by gdb to help find the values for */
215 u32 magic; /* To uniquely identify a core file */
216 char u_comm[32]; /* User command that was responsible */
220 #define PT32_PSWMASK 0x0
221 #define PT32_PSWADDR 0x04
222 #define PT32_GPR0 0x08
223 #define PT32_GPR15 0x44
224 #define PT32_ACR0 0x48
225 #define PT32_ACR15 0x84
226 #define PT32_ORIGGPR2 0x88
227 #define PT32_FPC 0x90
228 #define PT32_FPR0_HI 0x98
229 #define PT32_FPR15_LO 0x114
230 #define PT32_CR_9 0x118
231 #define PT32_CR_11 0x120
232 #define PT32_IEEE_IP 0x13C
233 #define PT32_LASTOFF PT32_IEEE_IP
234 #define PT32_ENDREGS 0x140-1
235 #define U32OFFSETOF(member) offsetof(struct user32,regs.member)
236 #define U64OFFSETOF(member) offsetof(struct user,regs.member)
237 #define U6432DIFF(member) (U64OFFSETOF(member) - U32OFFSETOF(member))
238 #define PT_SINGLE_STEP (PT_CR_11+8)
239 #define PT32_SINGLE_STEP (PT32_CR_11+4)
241 #endif /* CONFIG_S390_SUPPORT */
243 int copy_user(struct task_struct *task,saddr_t useraddr, addr_t copyaddr,
244 int len, int tofromuser, int writingtouser)
246 int copylen=0,copymax;
250 #ifdef CONFIG_S390_SUPPORT
251 int parent_31bit=current->thread.flags & S390_FLAG_31BIT;
254 enduseraddr=useraddr+len;
255 if ((useraddr<0||useraddr&3||enduseraddr&3)||
256 #ifdef CONFIG_S390_SUPPORT
257 (parent_31bit && enduseraddr > sizeof(struct user32)) ||
259 enduseraddr > sizeof(struct user))
262 #ifdef CONFIG_S390_SUPPORT
265 if(useraddr != PT32_PSWMASK)
267 if (useraddr == PT32_PSWADDR)
268 useraddr = PT_PSWADDR+4;
269 else if(useraddr <= PT32_GPR15)
270 useraddr = ((useraddr-PT32_GPR0)*2) + PT_GPR0+4;
271 else if(useraddr <= PT32_ACR15)
272 useraddr += PT_ACR0-PT32_ACR0;
273 else if(useraddr == PT32_ORIGGPR2)
274 useraddr = PT_ORIGGPR2+4;
275 else if(useraddr <= PT32_FPR15_LO)
276 useraddr += PT_FPR0-PT32_FPR0_HI;
277 else if(useraddr <= PT32_CR_11)
278 useraddr = ((useraddr-PT32_CR_9)*2) + PT_CR_9+4;
279 else if(useraddr == PT32_SINGLE_STEP)
280 useraddr = PT_SINGLE_STEP;
281 else if(useraddr <= U32OFFSETOF(per_info.ending_addr))
282 useraddr = (((useraddr-U32OFFSETOF(per_info.starting_addr)))*2) +
283 U64OFFSETOF(per_info.starting_addr)+4;
284 else if( useraddr == U32OFFSETOF(per_info.lowcore.words.perc_atmid))
285 useraddr = U64OFFSETOF(per_info.lowcore.words.perc_atmid);
286 else if( useraddr == U32OFFSETOF(per_info.lowcore.words.address))
287 useraddr = U64OFFSETOF(per_info.lowcore.words.address)+4;
288 else if(useraddr == U32OFFSETOF(per_info.lowcore.words.access_id))
289 useraddr = U64OFFSETOF(per_info.lowcore.words.access_id);
290 else if(useraddr == PT32_IEEE_IP)
291 useraddr = PT_IEEE_IP+4;
294 #endif /* CONFIG_S390_SUPPORT */
298 #ifdef CONFIG_S390_SUPPORT
304 realuseraddr=((addr_t) __KSTK_PTREGS(task)) + useraddr;
305 if(useraddr<(PT_PSWMASK+8))
309 copymax=PT_PSWMASK+4;
310 #ifdef CONFIG_S390_SUPPORT
316 copymax=PT_PSWMASK+8;
319 mask=PSW_MASK_DEBUGCHANGE;
321 else if(useraddr<(PT_PSWADDR+8))
323 copymax=PT_PSWADDR+8;
324 mask=PSW_ADDR_DEBUGCHANGE;
325 #ifdef CONFIG_S390_SUPPORT
333 #ifdef CONFIG_S390_SUPPORT
334 if(parent_31bit && useraddr <= PT_GPR15+4)
337 if(useraddr<PT_GPR15+4)
345 else if(useraddr<(PT_FPR15+sizeof(freg_t)))
347 copymax=(PT_FPR15+sizeof(freg_t));
348 realuseraddr=(addr_t)&(((u8 *)&task->thread.fp_regs)[useraddr-PT_FPC]);
350 else if(useraddr<sizeof(struct user_regs_struct))
352 #ifdef CONFIG_S390_SUPPORT
353 if( parent_31bit && useraddr <= PT_IEEE_IP+4)
358 case U64OFFSETOF(per_info.ending_addr)+4:
359 case U64OFFSETOF(per_info.lowcore.words.address)+4:
363 case U64OFFSETOF(per_info.lowcore.words.perc_atmid):
364 /* We copy 2 bytes in excess for the atmid member this also gets around */
365 /* alignment for this member in 32 bit */
377 copymax=sizeof(struct user_regs_struct);
379 realuseraddr=(addr_t)&(((u8 *)&task->thread.per_info)[useraddr-PT_CR_9]);
383 copymax=sizeof(struct user);
384 realuseraddr=(addr_t)NULL;
386 copylen=copymax-useraddr;
387 copylen=(copylen>len ? len:copylen);
388 if(ptrace_usercopy(realuseraddr,copyaddr,copylen,tofromuser,writingtouser,mask))
393 #if CONFIG_S390_SUPPORT
398 FixPerRegisters(task);
403 * Called by kernel/ptrace.c when detaching..
405 * Make sure single step bits etc are not set.
407 void ptrace_disable(struct task_struct *child)
409 /* make sure the single step bit is not set. */
410 clear_single_step(child);
421 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
423 struct task_struct *child;
426 #ifdef CONFIG_S390_SUPPORT
428 int sizeof_parent_long;
431 #define sizeof_parent_long 8
432 #define dataptr (u8 *)&data
435 if (request == PTRACE_TRACEME)
437 /* are we already being traced? */
438 if (current->ptrace & PT_PTRACED)
440 /* set the ptrace bit in the process flags. */
441 current->ptrace |= PT_PTRACED;
446 read_lock(&tasklist_lock);
447 child = find_task_by_pid(pid);
449 get_task_struct(child);
450 read_unlock(&tasklist_lock);
454 if (pid == 1) /* you may not mess with init */
456 if (request == PTRACE_ATTACH)
458 ret = ptrace_attach(child);
462 // printk("child=%lX child->flags=%lX",child,child->flags);
463 /* I added child!=current line so we can get the */
464 /* ieee_instruction_pointer from the user structure DJB */
467 if (!(child->ptrace & PT_PTRACED))
469 if (child->state != TASK_STOPPED)
471 if (request != PTRACE_KILL)
474 if (child->p_pptr != current)
477 #ifdef CONFIG_S390_SUPPORT
478 parent_31bit=(current->thread.flags & S390_FLAG_31BIT);
479 sizeof_parent_long=(parent_31bit ? 4:8);
480 dataptr=&(((u8 *)&data)[parent_31bit ? 4:0]);
484 /* If I and D space are separate, these will need to be fixed. */
485 case PTRACE_PEEKTEXT: /* read word at location addr. */
486 case PTRACE_PEEKDATA:
489 copied = access_process_vm(child, addr, tmp, sizeof_parent_long, 0);
491 if (copied != sizeof_parent_long)
493 ret = copy_to_user((void *)data,tmp,sizeof_parent_long);
494 ret = ret ? -EFAULT : 0;
498 /* read the word at location addr in the USER area. */
500 ret=copy_user(child,addr,data,sizeof_parent_long,1,0);
503 /* If I and D space are separate, this will have to be fixed. */
504 case PTRACE_POKETEXT: /* write the word at location addr. */
505 case PTRACE_POKEDATA:
507 if (access_process_vm(child, addr,dataptr, sizeof_parent_long, 1) == sizeof_parent_long)
512 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
513 ret=copy_user(child,addr,(addr_t)dataptr,sizeof_parent_long,0,1);
516 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
517 case PTRACE_CONT: /* restart after signal. */
519 if ((unsigned long) data >= _NSIG)
521 if (request == PTRACE_SYSCALL)
522 child->ptrace |= PT_TRACESYS;
524 child->ptrace &= ~PT_TRACESYS;
525 child->exit_code = data;
526 /* make sure the single step bit is not set. */
527 clear_single_step(child);
528 wake_up_process(child);
533 * make the child exit. Best I can do is send it a sigkill.
534 * perhaps it should be put in the status that it wants to
539 if (child->state == TASK_ZOMBIE) /* already dead */
541 child->exit_code = SIGKILL;
542 clear_single_step(child);
543 wake_up_process(child);
544 /* make sure the single step bit is not set. */
547 case PTRACE_SINGLESTEP: /* set the trap flag. */
549 if ((unsigned long) data >= _NSIG)
551 child->ptrace &= ~PT_TRACESYS;
552 child->exit_code = data;
553 set_single_step(child);
554 /* give it a chance to run. */
555 wake_up_process(child);
559 case PTRACE_DETACH: /* detach a process that was attached. */
560 ret = ptrace_detach(child, data);
563 case PTRACE_PEEKUSR_AREA:
564 case PTRACE_POKEUSR_AREA:
567 ptrace_area_emu31 parea;
568 if(copy_from_user(&parea,(void *)addr,sizeof(parea))==0)
569 ret=copy_user(child,parea.kernel_addr,parea.process_addr,
570 parea.len,1,(request==PTRACE_POKEUSR_AREA));
576 if(copy_from_user(&parea,(void *)addr,sizeof(parea))==0)
577 ret=copy_user(child,parea.kernel_addr,parea.process_addr,
578 parea.len,1,(request==PTRACE_POKEUSR_AREA));
587 free_task_struct(child);
595 asmlinkage void syscall_trace(void)
598 if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
599 != (PT_PTRACED|PT_TRACESYS))
601 current->exit_code = SIGTRAP;
602 set_current_state(TASK_STOPPED);
603 notify_parent(current, SIGCHLD);
606 * this isn't the same as continuing with a signal, but it will do
607 * for normal use. strace only continues with a signal if the
608 * stopping signal is not SIGTRAP. -brl
610 if (current->exit_code) {
611 send_sig(current->exit_code, current, 1);
612 current->exit_code = 0;