vi.c 8.7 KB

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