1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
| struct mmap_region { void *addr; uint len; int prot; int flags; int valid; char *faulted_pages; };
struct { void *addr; uint len; int prot; int flags; int valid; char *faulted_pages; } mmap_regions[16]; void *sigsegv_handler;
#define MAX_MMAP_REGIONS 16
int sys_mmap(void) { void *addr; uint length; int prot, flags, fd; uint offset; if(argptr(0, (char**)&addr, sizeof(addr)) < 0) return -1; if(argint(1, (int*)&length) < 0) return -1; if(argint(2, &prot) < 0) return -1; if(argint(3, &flags) < 0) return -1; if(argint(4, &fd) < 0) return -1; if(argint(5, (int*)&offset) < 0) return -1; struct proc *p = myproc(); if(!(flags & 0x20)) { cprintf("mmap: only MAP_ANONYMOUS supported\n"); return -1; } for(int i = 0; i < MAX_MMAP_REGIONS; i++) { if(p->mmap_regions[i].valid == 0) { if(addr == 0) { addr = (void*)PGROUNDUP(p->sz); } addr = (void*)PGROUNDDOWN((uint)addr); p->mmap_regions[i].addr = addr; p->mmap_regions[i].len = length; p->mmap_regions[i].prot = prot; p->mmap_regions[i].flags = flags; p->mmap_regions[i].valid = 1; p->mmap_regions[i].faulted_pages = 0; uint end = (uint)addr + length; if(end > p->sz) { p->sz = end; } cprintf("mmap: region %d at 0x%x, size=%d\n", i, addr, length); return (int)addr; } } cprintf("mmap: too many regions\n"); return -1; }
int sys_munmap(void) { void *addr; uint length; if(argptr(0, (char**)&addr, sizeof(addr)) < 0) return -1; if(argint(1, (int*)&length) < 0) return -1; struct proc *p = myproc(); for(int i = 0; i < MAX_MMAP_REGIONS; i++) { if(p->mmap_regions[i].valid && p->mmap_regions[i].addr == addr) { if(p->mmap_regions[i].faulted_pages != 0) { kfree(p->mmap_regions[i].faulted_pages); } p->mmap_regions[i].valid = 0; cprintf("munmap: region %d at 0x%x unmapped\n", i, addr); return 0; } } cprintf("munmap: region not found at 0x%x\n", addr); return -1; }
int sys_sigaction(void) { int signum; void *handler; void *oldact; if(argint(0, &signum) < 0) return -1; if(argptr(1, (char**)&handler, sizeof(handler)) < 0) return -1; if(argptr(2, (char**)&oldact, sizeof(oldact)) < 0) return -1; struct proc *p = myproc(); if(signum == 11) { if(handler != 0) { p->sigsegv_handler = handler; } if(oldact != 0) { *(void**)oldact = p->sigsegv_handler; } } return 0; }
|