summaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-x86_64/ptrace.c')
-rw-r--r--arch/um/sys-x86_64/ptrace.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 74eee5c7c6d..147bbf05cbc 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -8,6 +8,7 @@
#include <asm/ptrace.h>
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/mm.h>
#include <asm/uaccess.h>
#include <asm/elf.h>
@@ -136,9 +137,28 @@ void arch_switch(void)
*/
}
+/* XXX Mostly copied from sys-i386 */
int is_syscall(unsigned long addr)
{
- panic("is_syscall");
+ unsigned short instr;
+ int n;
+
+ n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
+ if(n){
+ /* access_process_vm() grants access to vsyscall and stub,
+ * while copy_from_user doesn't. Maybe access_process_vm is
+ * slow, but that doesn't matter, since it will be called only
+ * in case of singlestepping, if copy_from_user failed.
+ */
+ n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
+ if(n != sizeof(instr)) {
+ printk("is_syscall : failed to read instruction from "
+ "0x%lx\n", addr);
+ return(1);
+ }
+ }
+ /* sysenter */
+ return(instr == 0x050f);
}
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )