~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/arch/um/kernel/user_util.c

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.