1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define Extern 6 #include "power.h" 7 8 char *file = "q.out"; 9 int datasize; 10 ulong textbase; 11 Biobuf bp, bi; 12 Fhdr fhdr; 13 ulong bits[32]; 14 15 void 16 main(int argc, char **argv) 17 { 18 int pid, i; 19 20 argc--; 21 argv++; 22 23 bioout = &bp; 24 bin = &bi; 25 Binit(bioout, 1, OWRITE); 26 Binit(bin, 0, OREAD); 27 28 if(argc) { 29 pid = atoi(argv[0]); 30 if(pid != 0) { 31 procinit(pid); 32 cmd(); 33 } 34 file = argv[0]; 35 } 36 argc--; 37 argv++; 38 39 text = open(file, OREAD); 40 if(text < 0) 41 fatal(1, "open text '%s'", file); 42 43 Bprint(bioout, "qi\n"); 44 inithdr(text); 45 initstk(argc, argv); 46 47 for(i=0; i<32; i++) 48 bits[i] = 1L << (31-i); 49 50 fpreginit(); 51 cmd(); 52 } 53 54 void 55 initmap(void) 56 { 57 58 ulong t, d, b, bssend; 59 Segment *s; 60 61 t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1); 62 d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1); 63 bssend = t + fhdr.datsz + fhdr.bsssz; 64 b = (bssend + (BY2PG-1)) & ~(BY2PG-1); 65 66 s = &memory.seg[Text]; 67 s->type = Text; 68 s->base = fhdr.txtaddr - fhdr.hdrsz; 69 s->end = t; 70 s->fileoff = fhdr.txtoff - fhdr.hdrsz; 71 s->fileend = s->fileoff + fhdr.txtsz; 72 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 73 74 iprofsize = (s->end-s->base)/PROFGRAN; 75 iprof = emalloc(iprofsize*sizeof(long)); 76 textbase = s->base; 77 78 s = &memory.seg[Data]; 79 s->type = Data; 80 s->base = t; 81 s->end = t+(d-t); 82 s->fileoff = fhdr.datoff; 83 s->fileend = s->fileoff + fhdr.datsz; 84 datasize = fhdr.datsz; 85 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 86 87 s = &memory.seg[Bss]; 88 s->type = Bss; 89 s->base = d; 90 s->end = d+(b-d); 91 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 92 93 s = &memory.seg[Stack]; 94 s->type = Stack; 95 s->base = STACKTOP-STACKSIZE; 96 s->end = STACKTOP; 97 s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 98 99 reg.pc = fhdr.entry; 100 } 101 102 void 103 inithdr(int fd) 104 { 105 Symbol s; 106 107 extern Machdata powermach; 108 109 seek(fd, 0, 0); 110 if (!crackhdr(fd, &fhdr)) 111 fatal(0, "read text header"); 112 113 if(fhdr.type != FPOWER) 114 fatal(0, "bad magic number"); 115 116 if(syminit(fd, &fhdr) < 0) 117 fatal(0, "%r\n"); 118 symmap = loadmap(symmap, fd, &fhdr); 119 if (mach->sbreg && lookup(0, mach->sbreg, &s)) 120 mach->sb = s.value; 121 machdata = &powermach; 122 } 123 124 ulong 125 greg(int f, ulong off) 126 { 127 int n; 128 ulong l; 129 uchar wd[BY2WD]; 130 131 seek(f, off, 0); 132 n = read(f, wd, BY2WD); 133 if(n != BY2WD) 134 fatal(1, "read register"); 135 136 l = wd[0]<<24; 137 l |= wd[1]<<16; 138 l |= wd[2]<<8; 139 l |= wd[3]; 140 return l; 141 } 142 143 ulong 144 roff[] = { 145 REGOFF(r0), 146 REGOFF(r1), REGOFF(r2), REGOFF(r3), 147 REGOFF(r4), REGOFF(r5), REGOFF(r6), 148 REGOFF(r7), REGOFF(r8), REGOFF(r9), 149 REGOFF(r10), REGOFF(r11), REGOFF(r12), 150 REGOFF(r13), REGOFF(r14), REGOFF(r15), 151 REGOFF(r16), REGOFF(r17), REGOFF(r18), 152 REGOFF(r19), REGOFF(r20), REGOFF(r21), 153 REGOFF(r22), REGOFF(r23), REGOFF(r24), 154 REGOFF(r25), REGOFF(r26), REGOFF(r27), 155 REGOFF(r28), REGOFF(r29), REGOFF(r30), 156 REGOFF(r31), 157 }; 158 159 void 160 seginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend) 161 { 162 int n; 163 164 while(vastart < vaend) { 165 seek(fd, vastart, 0); 166 s->table[idx] = emalloc(BY2PG); 167 n = read(fd, s->table[idx], BY2PG); 168 if(n != BY2PG) 169 fatal(1, "data read"); 170 vastart += BY2PG; 171 idx++; 172 } 173 } 174 175 void 176 procinit(int pid) 177 { 178 char *p; 179 Segment *s; 180 int n, m, sg, i; 181 ulong vastart, vaend; 182 char mfile[128], tfile[128], sfile[1024]; 183 184 sprint(mfile, "/proc/%d/mem", pid); 185 sprint(tfile, "/proc/%d/text", pid); 186 sprint(sfile, "/proc/%d/segment", pid); 187 188 text = open(tfile, OREAD); 189 if(text < 0) 190 fatal(1, "open text %s", tfile); 191 inithdr(text); 192 193 sg = open(sfile, OREAD); 194 if(sg < 0) 195 fatal(1, "open text %s", sfile); 196 197 n = read(sg, sfile, sizeof(sfile)); 198 if(n >= sizeof(sfile)) 199 fatal(0, "segment file buffer too small"); 200 close(sg); 201 202 m = open(mfile, OREAD); 203 if(m < 0) 204 fatal(1, "open %s", mfile); 205 206 initmap(); 207 208 p = strstr(sfile, "Data"); 209 if(p == 0) 210 fatal(0, "no data"); 211 212 vastart = strtoul(p+9, 0, 16); 213 vaend = strtoul(p+18, 0, 16); 214 s = &memory.seg[Data]; 215 if(s->base != vastart || s->end != vaend) { 216 s->base = vastart; 217 s->end = vaend; 218 free(s->table); 219 s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 220 } 221 seginit(m, s, 0, vastart, vaend); 222 223 p = strstr(sfile, "Bss"); 224 if(p == 0) 225 fatal(0, "no bss"); 226 227 vastart = strtoul(p+9, 0, 16); 228 vaend = strtoul(p+18, 0, 16); 229 s = &memory.seg[Bss]; 230 if(s->base != vastart || s->end != vaend) { 231 s->base = vastart; 232 s->end = vaend; 233 free(s->table); 234 s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*)); 235 } 236 seginit(m, s, 0, vastart, vaend); 237 238 reg.pc = greg(m, REGOFF(pc)); 239 reg.r[1] = greg(m, REGOFF(sp)); 240 reg.r[2] = greg(m, REGOFF(r2)); 241 reg.r[30] = greg(m, REGOFF(r30)); 242 reg.r[31] = greg(m, REGOFF(r31)); 243 244 for(i = 0; i < 32; i++) 245 reg.r[i] = greg(m, roff[i-1]); 246 247 s = &memory.seg[Stack]; 248 vastart = reg.r[1] & ~(BY2PG-1); 249 seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP); 250 close(m); 251 Bprint(bioout, "qi\n"); 252 } 253 254 void 255 reset(void) 256 { 257 int i, l, m; 258 Segment *s; 259 Breakpoint *b; 260 261 memset(®, 0, sizeof(Registers)); 262 fpreginit(); 263 for(i = 0; i > Nseg; i++) { 264 s = &memory.seg[i]; 265 l = ((s->end-s->base)/BY2PG)*sizeof(uchar*); 266 for(m = 0; m < l; m++) 267 if(s->table[m]) 268 free(s->table[m]); 269 free(s->table); 270 } 271 free(iprof); 272 memset(&memory, 0, sizeof(memory)); 273 274 for(b = bplist; b; b = b->next) 275 b->done = b->count; 276 } 277 278 void 279 initstk(int argc, char *argv[]) 280 { 281 ulong size, sp, ap; 282 int i; 283 char *p; 284 285 initmap(); 286 sp = STACKTOP - 4; 287 288 /* Build exec stack */ 289 size = strlen(file)+1+BY2WD+BY2WD+(BY2WD*2); 290 for(i = 0; i < argc; i++) 291 size += strlen(argv[i])+BY2WD+1; 292 293 sp -= size; 294 sp &= ~7; 295 reg.r[1] = sp; 296 reg.r[3] = STACKTOP-4; /* Plan 9 profiling clock */ 297 298 /* Push argc */ 299 putmem_w(sp, argc+1); 300 sp += BY2WD; 301 302 /* Compute sizeof(argv) and push argv[0] */ 303 ap = sp+((argc+1)*BY2WD)+BY2WD; 304 putmem_w(sp, ap); 305 sp += BY2WD; 306 307 /* Build argv[0] string into stack */ 308 for(p = file; *p; p++) 309 putmem_b(ap++, *p); 310 311 putmem_b(ap++, '\0'); 312 313 /* Loop through pushing the arguments */ 314 for(i = 0; i < argc; i++) { 315 putmem_w(sp, ap); 316 sp += BY2WD; 317 for(p = argv[i]; *p; p++) 318 putmem_b(ap++, *p); 319 putmem_b(ap++, '\0'); 320 } 321 /* Null terminate argv */ 322 putmem_w(sp, 0); 323 324 } 325 326 void 327 fatal(int syserr, char *fmt, ...) 328 { 329 char buf[ERRMAX], *s; 330 va_list ap; 331 332 va_start(ap, fmt); 333 vseprint(buf, buf+sizeof(buf), fmt, ap); 334 va_end(ap); 335 s = "qi: %s\n"; 336 if(syserr) 337 s = "qi: %s: %r\n"; 338 fprint(2, s, buf); 339 exits(buf); 340 } 341 342 void 343 itrace(char *fmt, ...) 344 { 345 char buf[128]; 346 va_list ap; 347 348 va_start(ap, fmt); 349 vseprint(buf, buf+sizeof(buf), fmt, ap); 350 va_end(ap); 351 Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf); 352 Bflush(bioout); 353 } 354 355 void 356 dumpreg(void) 357 { 358 int i; 359 360 Bprint(bioout, "PC #%-8lux SP #%-8lux CR #%-8lux LR #%-8lux CTR #%-8lux XER #%-8lux\n", 361 reg.pc, reg.r[1], reg.cr, reg.lr, reg.ctr, reg.xer); 362 363 for(i = 0; i < 32; i++) { 364 if((i%4) == 0 && i != 0) 365 Bprint(bioout, "\n"); 366 Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]); 367 } 368 Bprint(bioout, "\n"); 369 } 370 371 void 372 dumpfreg(void) 373 { 374 dumpdreg(); 375 } 376 377 void 378 dumpdreg(void) 379 { 380 int i; 381 char buf[64]; 382 FPdbleword d; 383 384 i = 0; 385 while(i < 32) { 386 d.x = reg.fd[i]; 387 ieeedftos(buf, sizeof(buf), d.hi, d.lo); 388 Bprint(bioout, "F%-2d %s\t", i, buf); 389 i++; 390 d.x = reg.fd[i]; 391 ieeedftos(buf, sizeof(buf), d.hi, d.lo); 392 Bprint(bioout, "\tF%-2d %s\n", i, buf); 393 i++; 394 } 395 } 396 397 void * 398 emalloc(ulong size) 399 { 400 void *a; 401 402 a = malloc(size); 403 if(a == 0) 404 fatal(0, "no memory"); 405 406 memset(a, 0, size); 407 return a; 408 } 409 410 void * 411 erealloc(void *a, ulong oldsize, ulong size) 412 { 413 void *n; 414 415 n = malloc(size); 416 if(n == 0) 417 fatal(0, "no memory"); 418 memset(n, 0, size); 419 if(size > oldsize) 420 size = oldsize; 421 memmove(n, a, size); 422 return n; 423 } 424