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