2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
11 #include <asm/unistd.h>
18 #include "ptrace_user.h"
19 #include "user_util.h"
20 #include "kern_util.h"
22 #include "registers.h"
23 #include "uml-config.h"
24 #include "sysdep/ptrace.h"
25 #include "sysdep/stub.h"
28 extern unsigned long syscall_stub
, __syscall_stub_start
;
30 extern void wait_stub_done(int pid
, int sig
, char * fname
);
32 static long run_syscall_stub(struct mm_id
* mm_idp
, int syscall
,
35 int n
, pid
= mm_idp
->u
.pid
;
36 unsigned long regs
[MAX_REG_NR
];
38 get_safe_registers(regs
);
39 regs
[REGS_IP_INDEX
] = UML_CONFIG_STUB_CODE
+
40 ((unsigned long) &syscall_stub
-
41 (unsigned long) &__syscall_stub_start
);
42 /* XXX Don't have a define for starting a syscall */
43 regs
[REGS_SYSCALL_NR
] = syscall
;
44 regs
[REGS_SYSCALL_ARG1
] = args
[0];
45 regs
[REGS_SYSCALL_ARG2
] = args
[1];
46 regs
[REGS_SYSCALL_ARG3
] = args
[2];
47 regs
[REGS_SYSCALL_ARG4
] = args
[3];
48 regs
[REGS_SYSCALL_ARG5
] = args
[4];
49 regs
[REGS_SYSCALL_ARG6
] = args
[5];
50 n
= ptrace_setregs(pid
, regs
);
52 printk("run_syscall_stub : PTRACE_SETREGS failed, "
57 wait_stub_done(pid
, 0, "run_syscall_stub");
59 return(*((unsigned long *) mm_idp
->stack
));
62 int map(struct mm_id
*mm_idp
, unsigned long virt
, unsigned long len
,
63 int r
, int w
, int x
, int phys_fd
, unsigned long long offset
)
67 prot
= (r
? PROT_READ
: 0) | (w
? PROT_WRITE
: 0) |
71 struct proc_mm_op map
;
72 int fd
= mm_idp
->u
.mm_fd
;
73 map
= ((struct proc_mm_op
) { .op
= MM_MMAP
,
84 n
= os_write_file(fd
, &map
, sizeof(map
));
86 printk("map : /proc/mm map failed, err = %d\n", -n
);
90 unsigned long args
[] = { virt
, len
, prot
,
91 MAP_SHARED
| MAP_FIXED
, phys_fd
,
92 MMAP_OFFSET(offset
) };
94 res
= run_syscall_stub(mm_idp
, STUB_MMAP_NR
, args
);
95 if((void *) res
== MAP_FAILED
)
96 printk("mmap stub failed, errno = %d\n", res
);
102 int unmap(struct mm_id
*mm_idp
, void *addr
, unsigned long len
)
107 struct proc_mm_op unmap
;
108 int fd
= mm_idp
->u
.mm_fd
;
109 unmap
= ((struct proc_mm_op
) { .op
= MM_MUNMAP
,
113 (unsigned long) addr
,
115 n
= os_write_file(fd
, &unmap
, sizeof(unmap
));
116 if(n
!= sizeof(unmap
)) {
125 unsigned long args
[] = { (unsigned long) addr
, len
, 0, 0, 0,
128 res
= run_syscall_stub(mm_idp
, __NR_munmap
, args
);
130 printk("munmap stub failed, errno = %d\n", res
);
136 int protect(struct mm_id
*mm_idp
, unsigned long addr
, unsigned long len
,
139 struct proc_mm_op protect
;
142 prot
= (r
? PROT_READ
: 0) | (w
? PROT_WRITE
: 0) |
146 int fd
= mm_idp
->u
.mm_fd
;
147 protect
= ((struct proc_mm_op
) { .op
= MM_MPROTECT
,
151 (unsigned long) addr
,
153 .prot
= prot
} } } );
155 n
= os_write_file(fd
, &protect
, sizeof(protect
));
156 if(n
!= sizeof(protect
))
157 panic("protect failed, err = %d", -n
);
161 unsigned long args
[] = { addr
, len
, prot
, 0, 0, 0 };
163 res
= run_syscall_stub(mm_idp
, __NR_mprotect
, args
);
165 panic("mprotect stub failed, errno = %d\n", res
);
171 void before_mem_skas(unsigned long unused
)