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, uvlong b, uvlong e, vlong 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 uvlong 49 stacktop(int pid) 50 { 51 char buf[64]; 52 int fd; 53 int n; 54 char *cp; 55 56 snprint(buf, sizeof(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 strtoull(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 uvlong n; 86 87 map = newmap(0, 4); 88 if (!map) 89 return 0; 90 if(kflag) 91 regs = "kregs"; 92 else 93 regs = "regs"; 94 if (mach->regsize) { 95 sprint(buf, "/proc/%d/%s", pid, regs); 96 fd = open(buf, ORDWR); 97 if(fd < 0) 98 fd = open(buf, OREAD); 99 if(fd < 0) { 100 free(map); 101 return 0; 102 } 103 setmap(map, fd, 0, mach->regsize, 0, "regs"); 104 } 105 if (mach->fpregsize) { 106 sprint(buf, "/proc/%d/fpregs", pid); 107 fd = open(buf, ORDWR); 108 if(fd < 0) 109 fd = open(buf, OREAD); 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 || fp->dataddr >= mach->utop) { 119 setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data"); 120 return map; 121 } 122 n = stacktop(pid); 123 if (n == 0) { 124 setmap(map, corefd, fp->dataddr, mach->utop, 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 loadmap(Map *map, int fd, Fhdr *fp) 153 { 154 map = newmap(map, 2); 155 if (map == 0) 156 return 0; 157 158 map->seg[0].b = fp->txtaddr; 159 map->seg[0].e = fp->txtaddr+fp->txtsz; 160 map->seg[0].f = fp->txtoff; 161 map->seg[0].fd = fd; 162 map->seg[0].inuse = 1; 163 map->seg[0].name = "text"; 164 map->seg[1].b = fp->dataddr; 165 map->seg[1].e = fp->dataddr+fp->datsz; 166 map->seg[1].f = fp->datoff; 167 map->seg[1].fd = fd; 168 map->seg[1].inuse = 1; 169 map->seg[1].name = "data"; 170 return map; 171 } 172 173 Map* 174 attachremt(int fd, Fhdr *f) 175 { 176 Map *m; 177 ulong txt; 178 179 m = newmap(0, 3); 180 if (m == 0) 181 return 0; 182 183 /* Space for mach structures */ 184 txt = f->txtaddr; 185 if(txt > 8*4096) 186 txt -= 8*4096; 187 188 setmap(m, fd, txt, f->txtaddr+f->txtsz, txt, "*text"); 189 /*setmap(m, fd, f->dataddr, 0xffffffff, f->dataddr, "*data");*/ /* pc heap is < KTZERO */ 190 setmap(m, fd, 4096, 0xffffffff, 4096, "*data"); 191 setmap(m, fd, 0x0, mach->regsize, 0, "kreg"); 192 193 return m; 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