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