qi.c 7.7 KB

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