2 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
7 #define __FRAME_OFFSETS
8 #include <asm/ptrace.h>
9 #include <linux/sched.h>
10 #include <linux/errno.h>
12 #include <asm/uaccess.h>
20 #define SC_SS(r) (not_ss)
21 #define SC_DS(r) (not_ds)
22 #define SC_ES(r) (not_es)
24 /* determines which flags the user has access to. */
25 /* 1 = access 0 = no access */
26 #define FLAG_MASK 0x44dd5UL
28 int putreg(struct task_struct
*child
, int regno
, unsigned long value
)
33 /* Some code in the 64bit emulation may not be 64bit clean.
34 Don't take any chances. */
35 if (test_tsk_thread_flag(child
, TIF_IA32
))
45 if (value
&& (value
& 3) != 3)
52 if (!((value
>> 48) == 0 || (value
>> 48) == 0xffff))
58 tmp
= PT_REGS_EFLAGS(&child
->thread
.regs
) & ~FLAG_MASK
;
63 PT_REGS_SET(&child
->thread
.regs
, regno
, value
);
67 int poke_user(struct task_struct
*child
, long addr
, long data
)
69 if ((addr
& 3) || addr
< 0)
72 if (addr
< MAX_REG_OFFSET
)
73 return putreg(child
, addr
, data
);
74 else if((addr
>= offsetof(struct user
, u_debugreg
[0])) &&
75 (addr
<= offsetof(struct user
, u_debugreg
[7]))){
76 addr
-= offsetof(struct user
, u_debugreg
[0]);
78 if((addr
== 4) || (addr
== 5)) return -EIO
;
79 child
->thread
.arch
.debugregs
[addr
] = data
;
85 unsigned long getreg(struct task_struct
*child
, int regno
)
87 unsigned long retval
= ~0UL;
98 retval
&= PT_REG(&child
->thread
.regs
, regno
);
100 if (test_tsk_thread_flag(child
, TIF_IA32
))
101 retval
&= 0xffffffff;
107 int peek_user(struct task_struct
*child
, long addr
, long data
)
109 /* read the word at location addr in the USER area. */
112 if ((addr
& 3) || addr
< 0)
115 tmp
= 0; /* Default return condition */
116 if(addr
< MAX_REG_OFFSET
){
117 tmp
= getreg(child
, addr
);
119 else if((addr
>= offsetof(struct user
, u_debugreg
[0])) &&
120 (addr
<= offsetof(struct user
, u_debugreg
[7]))){
121 addr
-= offsetof(struct user
, u_debugreg
[0]);
123 tmp
= child
->thread
.arch
.debugregs
[addr
];
125 return put_user(tmp
, (unsigned long *) data
);
128 void arch_switch(void)
131 printk("arch_switch\n");
135 /* XXX Mostly copied from sys-i386 */
136 int is_syscall(unsigned long addr
)
138 unsigned short instr
;
141 n
= copy_from_user(&instr
, (void __user
*) addr
, sizeof(instr
));
143 /* access_process_vm() grants access to vsyscall and stub,
144 * while copy_from_user doesn't. Maybe access_process_vm is
145 * slow, but that doesn't matter, since it will be called only
146 * in case of singlestepping, if copy_from_user failed.
148 n
= access_process_vm(current
, addr
, &instr
, sizeof(instr
), 0);
149 if(n
!= sizeof(instr
)) {
150 printk("is_syscall : failed to read instruction from "
156 return(instr
== 0x050f);
159 int dump_fpu(struct pt_regs
*regs
, elf_fpregset_t
*fpu
)
165 int get_fpregs(unsigned long buf
, struct task_struct
*child
)
171 int set_fpregs(unsigned long buf
, struct task_struct
*child
)
177 int get_fpxregs(unsigned long buf
, struct task_struct
*tsk
)
179 panic("get_fpxregs");
183 int set_fpxregs(unsigned long buf
, struct task_struct
*tsk
)
185 panic("set_fxpregs");
190 * Overrides for Emacs so that we follow Linus's tabbing style.
191 * Emacs will notice this stuff at the end of the file and automatically
192 * adjust the settings for this buffer only. This must remain at the end
194 * ---------------------------------------------------------------------------
196 * c-file-style: "linux"