1 /* 2 * file map routines 3 */ 4 #include <lib9.h> 5 #include <bio.h> 6 #include "mach.h" 7 8 Map * 9 newmap(Map *map, int n) 10 { 11 int size; 12 13 size = sizeof(Map)+(n-1)*sizeof(struct segment); 14 if (map == 0) 15 map = malloc(size); 16 else 17 map = realloc(map, size); 18 if (map == 0) { 19 werrstr("out of memory: %r"); 20 return 0; 21 } 22 memset(map, 0, size); 23 map->nsegs = n; 24 return map; 25 } 26 27 int 28 setmap(Map *map, int fd, ulong b, ulong e, ulong f, char *name) 29 { 30 int i; 31 32 if (map == 0) 33 return 0; 34 for (i = 0; i < map->nsegs; i++) 35 if (!map->seg[i].inuse) 36 break; 37 if (i >= map->nsegs) 38 return 0; 39 map->seg[i].b = b; 40 map->seg[i].e = e; 41 map->seg[i].f = f; 42 map->seg[i].inuse = 1; 43 map->seg[i].name = name; 44 map->seg[i].fd = fd; 45 return 1; 46 } 47 48 static ulong 49 stacktop(int pid) 50 { 51 char buf[64]; 52 int fd; 53 int n; 54 char *cp; 55 56 sprint(buf, "/proc/%d/segment", pid); 57 fd = open(buf, 0); 58 if (fd < 0) 59 return 0; 60 n = read(fd, buf, sizeof(buf)-1); 61 close(fd); 62 buf[n] = 0; 63 if (strncmp(buf, "Stack", 5)) 64 return 0; 65 for (cp = buf+5; *cp && *cp == ' '; cp++) 66 ; 67 if (!*cp) 68 return 0; 69 cp = strchr(cp, ' '); 70 if (!cp) 71 return 0; 72 while (*cp && *cp == ' ') 73 cp++; 74 if (!*cp) 75 return 0; 76 return strtoul(cp, 0, 16); 77 } 78 79 Map* 80 attachproc(int pid, int kflag, int corefd, Fhdr *fp) 81 { 82 char buf[64], *regs; 83 int fd; 84 Map *map; 85 ulong n; 86 int mode; 87 88 map = newmap(0, 4); 89 if (!map) 90 return 0; 91 if(kflag) { 92 regs = "kregs"; 93 mode = OREAD; 94 } else { 95 regs = "regs"; 96 mode = ORDWR; 97 } 98 if (mach->regsize) { 99 sprint(buf, "/proc/%d/%s", pid, regs); 100 fd = open(buf, mode); 101 if(fd < 0) { 102 free(map); 103 return 0; 104 } 105 setmap(map, fd, 0, mach->regsize, 0, "regs"); 106 } 107 if (mach->fpregsize) { 108 sprint(buf, "/proc/%d/fpregs", pid); 109 fd = open(buf, mode); 110 if(fd < 0) { 111 close(map->seg[0].fd); 112 free(map); 113 return 0; 114 } 115 setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs"); 116 } 117 setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text"); 118 if(kflag || (ulong) fp->dataddr >= 0x7fffffff) { 119 setmap(map, corefd, fp->dataddr, 0xffffffff, fp->dataddr, "data"); 120 return map; 121 } 122 n = stacktop(pid); 123 if (n == 0) { 124 setmap(map, corefd, fp->dataddr, 0x7fffffff, fp->dataddr, "data"); 125 return map; 126 } 127 setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data"); 128 return map; 129 } 130 131 int 132 findseg(Map *map, char *name) 133 { 134 int i; 135 136 if (!map) 137 return -1; 138 for (i = 0; i < map->nsegs; i++) 139 if (map->seg[i].inuse && !strcmp(map->seg[i].name, name)) 140 return i; 141 return -1; 142 } 143 144 void 145 unusemap(Map *map, int i) 146 { 147 if (map != 0 && 0 <= i && i < map->nsegs) 148 map->seg[i].inuse = 0; 149 } 150 151 Map* 152 attachremt(int fd, Fhdr *f) 153 { 154 Map *m; 155 ulong txt; 156 157 m = newmap(0, 3); 158 if (m == 0) 159 return 0; 160 161 /* Space for mach structures */ 162 txt = f->txtaddr; 163 if(txt > 8*4096) 164 txt -= 8*4096; 165 166 setmap(m, fd, txt, f->txtaddr+f->txtsz, txt, "*text"); 167 /*setmap(m, fd, f->dataddr, 0xffffffff, f->dataddr, "*data");*/ /* pc heap is < KTZERO */ 168 setmap(m, fd, 4096, 0xffffffff, 4096, "*data"); 169 setmap(m, fd, 0x0, mach->regsize, 0, "kreg"); 170 171 return m; 172 } 173 174 Map* 175 loadmap(Map *map, int fd, Fhdr *fp) 176 { 177 map = newmap(map, 2); 178 if (map == 0) 179 return 0; 180 181 map->seg[0].b = fp->txtaddr; 182 map->seg[0].e = fp->txtaddr+fp->txtsz; 183 map->seg[0].f = fp->txtoff; 184 map->seg[0].fd = fd; 185 map->seg[0].inuse = 1; 186 map->seg[0].name = "text"; 187 map->seg[1].b = fp->dataddr; 188 map->seg[1].e = fp->dataddr+fp->datsz; 189 map->seg[1].f = fp->datoff; 190 map->seg[1].fd = fd; 191 map->seg[1].inuse = 1; 192 map->seg[1].name = "data"; 193 return map; 194 } 195 196 void 197 setmapio(Map *map, int i, Rsegio get, Rsegio put) 198 { 199 if (map != 0 && 0 <= i && i < map->nsegs) { 200 map->seg[i].mget = get; 201 map->seg[i].mput = put; 202 } 203 } 204