Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <sys/mman.h>
6 #include <sys/stat.h>
7 #include <sys/ptrace.h>
8 #include <ctype.h>
9 #include <signal.h>
10 #include <wait.h>
11 #include <errno.h>
12 #include <stdarg.h>
13 #include <sched.h>
14 #include <termios.h>
15 #include "proc_arch.h"
16 #include "user_util.h"
17 #include "kern_util.h"
18 #include "user.h"
19
20 int open_maps(void)
21 {
22 int fd;
23 char proc_map[sizeof("/proc/#####/maps")];
24
25 sprintf(proc_map, "/proc/%d/maps", getpid());
26 fd = open(proc_map, O_RDONLY, 0);
27 if(fd < 0){
28 perror("open_maps");
29 exit(1);
30 }
31 return(fd);
32 }
33
34 static char *read_one_map(int fd, char *buf, int fixed, int var)
35 {
36 int i, res;
37 char *ptr, c;
38
39 res = read(fd, buf, fixed);
40 if(res == 0) return(NULL);
41 else if(res < fixed){
42 perror("Reading fixed portion of map");
43 exit(1);
44 }
45 ptr = &buf[fixed];
46 for(i=0;i<var;i++){
47 res = read(fd, ptr, 1);
48 if(res < 1){
49 perror("Reading fixed portion of map");
50 exit(1);
51 }
52 if(*ptr == ' '){
53 *ptr = '\0';
54 break;
55 }
56 else if(*ptr == '\n'){
57 *ptr = '\0';
58 return(buf);
59 }
60 ptr++;
61 }
62 do {
63 res = read(fd, &c, 1);
64 if(res < 1){
65 perror("Reading variable portion of map");
66 exit(1);
67 }
68 } while(c != '\n');
69 return(buf);
70 }
71
72 #define MAP_FIXED_LEN (LONG_LEN + 1 + LONG_LEN + 1 + PERM_LEN + 1 + \
73 LONG_LEN + 1 + DEV_LEN + 1 + DEV_LEN + 1)
74 #define MAP_VAR_LEN (LONG_DEC_LEN)
75
76 int read_map(int fd, unsigned long *start_out, unsigned long *end_out,
77 char *r_out, char *w_out, char *x_out, char *p_out,
78 unsigned long *offset_out, unsigned long *major_out,
79 unsigned long *minor_out, unsigned int *inode_out)
80 {
81 unsigned int inode;
82 unsigned long start, end, major, minor, offset;
83 char map_buf[MAP_FIXED_LEN + MAP_VAR_LEN], r, w, x, p;
84
85 if(read_one_map(fd, map_buf, MAP_FIXED_LEN, MAP_VAR_LEN) == NULL)
86 return(0);
87 if(sscanf(map_buf, "%lx-%lx %c%c%c%c %lx %lx:%lx %d", &start, &end, &r, &w,
88 &x, &p, &offset, &major, &minor, &inode) != 10){
89 perror("Scanning a map line");
90 exit(1);
91 }
92 if(start_out != NULL) *start_out = start;
93 if(end_out != NULL) *end_out = end;
94 if(r_out != NULL) *r_out = r;
95 if(w_out != NULL) *w_out = w;
96 if(x_out != NULL) *x_out = x;
97 if(p_out != NULL) *p_out = p;
98 if(offset_out != NULL) *offset_out = offset;
99 if(major_out != NULL) *major_out = major;
100 if(minor_out != NULL) *minor_out = minor;
101 if(inode_out != NULL) *inode_out = inode;
102 return(1);
103 }
104
105 void close_maps(int fd)
106 {
107 close(fd);
108 }
109
110 static int create_vm_file(unsigned long len)
111 {
112 int fd;
113 char zero;
114
115 if((fd = open("vm_file", O_RDWR | O_CREAT | O_EXCL, 0777)) < 0){
116 perror("open");
117 exit(1);
118 }
119 if(unlink("vm_file") < 0){
120 perror("unlink");
121 exit(1);
122 }
123 if(lseek(fd, len, SEEK_SET) < 0){
124 perror("lseek");
125 exit(1);
126 }
127 zero = 0;
128 if(write(fd, &zero, 1) != 1){
129 perror("write");
130 exit(1);
131 }
132 return(fd);
133 }
134
135 void remap_data(char *perms)
136 {
137 void *addr;
138 unsigned long start, end, size;
139 int fd, data, prot;
140 char r, w, x;
141
142 fd = open_maps();
143 while(read_map(fd, &start, &end, &r, &w, &x, NULL, NULL, NULL, NULL,
144 NULL) != 0){
145 if((r == perms[0]) && (w == perms[1]) && (x == perms[2])){
146 prot = 0;
147 if(perms[0] == 'r') prot |= PROT_READ;
148 if(perms[1] == 'w') prot |= PROT_WRITE;
149 if(perms[2] == 'x') prot |= PROT_EXEC;
150 size = end - start;
151 data = create_vm_file(size);
152 if((addr = mmap(NULL, size, PROT_WRITE, MAP_SHARED, data, 0)) < 0){
153 perror("mapping new data segment");
154 exit(1);
155 }
156 memcpy(addr, (void *) start, size);
157 if(munmap((void *) start, size) < 0){
158 perror("unmapping old data segment");
159 exit(1);
160 }
161 if(mmap((void *) start, size, prot, MAP_SHARED | MAP_FIXED,
162 data, 0) != (void *) start){
163 perror("mapping new data segment");
164 exit(1);
165 }
166 if(munmap(addr, size) < 0){
167 perror("unmapping new data segment");
168 exit(1);
169 }
170 close_maps(fd);
171 return;
172 }
173 }
174 fprintf(stderr, "remap_data couldn't find data segment\n");
175 exit(1);
176 }
177
178 unsigned long get_brk(void)
179 {
180 return((unsigned long) sbrk(0));
181 }
182
183 int file_size(char *file)
184 {
185 struct stat buf;
186
187 if(stat(file, &buf) == -1){
188 perror("stat");
189 exit(1);
190 }
191 return(buf.st_size);
192 }
193
194 void stop(void)
195 {
196 while(1) sleep(1000000);
197 }
198
199 int linux_wait(int pid, int *status, int flags)
200 {
201 return(waitpid(pid, status, flags));
202 }
203
204 int linux_getpid(void)
205 {
206 return(getpid());
207 }
208
209 void stack_protections(unsigned long address, int len)
210 {
211 mprotect((void *) address, len, PROT_READ | PROT_WRITE | PROT_EXEC);
212 }
213
214 unsigned long setup_memory(unsigned long total_size,
215 unsigned long physmem_size, int *fd_out,
216 int *inode_out)
217 {
218 void *mem;
219 struct stat buf;
220
221 mem = mmap((void *) 0x50000000, total_size, PROT_NONE,
222 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
223 if(mem < 0){
224 perror("Mapping all of memory");
225 exit(1);
226 }
227 munmap(mem, total_size);
228 *fd_out = create_vm_file(physmem_size);
229 if(mmap(mem, physmem_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
230 *fd_out, 0) != mem){
231 perror("Mapping physical memory");
232 exit(1);
233 }
234 if(fstat(*fd_out, &buf) < 0){
235 perror("Stat-ing phymem_fd");
236 exit(1);
237 }
238 *inode_out = buf.st_ino;
239 return((unsigned long) mem);
240 }
241
242 void map(unsigned long virt, unsigned long phys, unsigned long len, int r,
243 int w, int x)
244 {
245 int prot;
246
247 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | (x ? PROT_EXEC : 0);
248 if((phys < physmem) || (phys > high_physmem))
249 panic("map : physmem out of range");
250 phys -= physmem;
251 if(mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, physmem_fd,
252 phys) != (void *) virt){
253 perror("Mapping a page");
254 exit(1);
255 }
256 }
257
258 void unmap(unsigned long address, unsigned long len)
259 {
260 if(munmap((void *) address, len) < 0){
261 printk("munmap of 0x%x(%d) failed - errno = %d\n", address, len, errno);
262 }
263 }
264
265 void protect(unsigned long addr, unsigned long len, int r, int w, int x)
266 {
267 int prot;
268
269 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | (x ? PROT_EXEC : 0);
270 if(mprotect((void *) addr, len, prot) == -1){
271 perror("Protecting a page");
272 panic("protect failed");
273 }
274 }
275
276 void wait_for_stop(int pid, int sig)
277 {
278 int status, ret;
279
280 if(((ret = linux_wait(pid, &status, WUNTRACED)) < 0) ||
281 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
282 if(ret < 0) printk("wait failed, errno = %d\n", errno);
283 else if(WIFEXITED(status))
284 printk("process exited with status %d\n", WEXITSTATUS(status));
285 else if(WIFSIGNALED(status))
286 printk("process exited with signal %d\n", WTERMSIG(status));
287 else printk("process stopped with signal %d\n", WSTOPSIG(status));
288 panic("wait_for_stop failed to wait for %d to stop with %d\n", pid, sig);
289 }
290 }
291
292 static int aux_pids[16];
293 static int aux_pid_index = 0;
294 static int main_pid;
295
296 void register_pid(int pid, int is_main)
297 {
298 if(is_main) main_pid = pid;
299 else {
300 if(aux_pid_index == sizeof(aux_pids)/sizeof(aux_pids[0]))
301 panic("Too many auxiliary pids");
302 lock_pid();
303 aux_pids[aux_pid_index++] = pid;
304 unlock_pid();
305 }
306 }
307
308 int get_main_pid(void)
309 {
310 return(main_pid);
311 }
312
313 int kill_aux_pids(void)
314 {
315 int i;
316
317 for(i=0;i<aux_pid_index;i++) kill_pid(aux_pids[i]);
318 aux_pid_index = 0;
319 return(main_pid);
320 }
321
322 static int mem_blocked = 0;
323
324 void block_shlib_mem(void)
325 {
326 if(mem_blocked) return;
327 mem_blocked = 1;
328 if(mmap((void *) 0x40000000, 0x20000000, PROT_NONE ,
329 MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1,
330 0) != (void *) 0x40000000){
331 printf("mmap failed in linux_main\n");
332 exit(1);
333 }
334 }
335
336 void unblock_shlib_mem(void)
337 {
338 mem_blocked = 0;
339 munmap((void *) 0x40000000, 0x20000000);
340 }
341
342 int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
343 {
344 int pid;
345
346 pid = clone(fn, sp, flags, arg);
347 wait_for_stop(pid, SIGSTOP);
348 return(pid);
349 }
350
351 int getmaster(char *line)
352 {
353 struct termios tt;
354 struct stat stb;
355 char *pty, *bank, *cp;
356 int master;
357
358 pty = &line[strlen("/dev/ptyp")];
359 for (bank = "pqrs"; *bank; bank++) {
360 line[strlen("/dev/pty")] = *bank;
361 *pty = '';
362 if (stat(line, &stb) < 0)
363 break;
364 for (cp = "0123456789abcdef"; *cp; cp++) {
365 *pty = *cp;
366 master = open(line, O_RDWR);
367 if (master >= 0) {
368 char *tp = &line[strlen("/dev/")];
369 int ok;
370
371 /* verify slave side is usable */
372 *tp = 't';
373 ok = access(line, R_OK|W_OK) == 0;
374 *tp = 'p';
375 if (ok) {
376 tcgetattr(master, &tt);
377 cfmakeraw(&tt);
378 tcsetattr(master, TCSADRAIN, &tt);
379 return(master);
380 }
381 (void) close(master);
382 }
383 }
384 }
385 panic("Out of pty's in getmaster");
386 return(-1);
387 }
388
389
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.