ki.c 8.2 KB

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