obj.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402
  1. #define EXTERN
  2. #include "l.h"
  3. #include <ar.h>
  4. #ifndef DEFAULT
  5. #define DEFAULT '9'
  6. #endif
  7. char *noname = "<none>";
  8. char symname[] = SYMDEF;
  9. char thechar = '2';
  10. char *thestring = "68020";
  11. /*
  12. * -H0 -T0x40004C -D0x10000000 is garbage unix
  13. * -H1 -T0x80020000 -R4 is garbage format
  14. * -H2 -T8224 -R8192 is plan9 format
  15. * -H3 -Tx -Rx is next boot
  16. */
  17. void
  18. main(int argc, char *argv[])
  19. {
  20. int i, c;
  21. char *a;
  22. Binit(&bso, 1, OWRITE);
  23. cout = -1;
  24. listinit();
  25. memset(debug, 0, sizeof(debug));
  26. nerrors = 0;
  27. outfile = "2.out";
  28. HEADTYPE = -1;
  29. INITTEXT = -1;
  30. INITDAT = -1;
  31. INITRND = -1;
  32. INITENTRY = 0;
  33. ARGBEGIN {
  34. default:
  35. c = ARGC();
  36. if(c >= 0 && c < sizeof(debug))
  37. debug[c]++;
  38. break;
  39. case 'o': /* output to (next arg) */
  40. outfile = ARGF();
  41. break;
  42. case 'E':
  43. a = ARGF();
  44. if(a)
  45. INITENTRY = a;
  46. break;
  47. case 'H':
  48. a = ARGF();
  49. if(a)
  50. HEADTYPE = atolwhex(a);
  51. break;
  52. case 'T':
  53. a = ARGF();
  54. if(a)
  55. INITTEXT = atolwhex(a);
  56. break;
  57. case 'D':
  58. a = ARGF();
  59. if(a)
  60. INITDAT = atolwhex(a);
  61. break;
  62. case 'R':
  63. a = ARGF();
  64. if(a)
  65. INITRND = atolwhex(a);
  66. break;
  67. } ARGEND
  68. USED(argc);
  69. if(*argv == 0) {
  70. diag("usage: 2l [-options] objects");
  71. errorexit();
  72. }
  73. if(!debug['9'] && !debug['U'] && !debug['B'])
  74. debug[DEFAULT] = 1;
  75. if(HEADTYPE == -1) {
  76. if(debug['U'])
  77. HEADTYPE = 2;
  78. if(debug['B'])
  79. HEADTYPE = 2;
  80. if(debug['9'])
  81. HEADTYPE = 2;
  82. }
  83. if(INITDAT != -1 && INITRND == -1)
  84. INITRND = 0;
  85. switch(HEADTYPE) {
  86. default:
  87. diag("unknown -H option %d", HEADTYPE);
  88. errorexit();
  89. case 0: /* this is garbage */
  90. HEADR = 20L+56L;
  91. if(INITTEXT == -1)
  92. INITTEXT = 0x40004CL;
  93. if(INITDAT == -1)
  94. INITDAT = 0x10000000L;
  95. if(INITDAT != 0 && INITRND == -1)
  96. INITRND = 0;
  97. if(INITRND == -1)
  98. INITRND = 0;
  99. break;
  100. case 1: /* plan9 boot data goes into text */
  101. HEADR = 32L;
  102. if(INITTEXT == -1)
  103. INITTEXT = 8224;
  104. if(INITDAT == -1)
  105. INITDAT = 0;
  106. if(INITDAT != 0 && INITRND == -1)
  107. INITRND = 0;
  108. if(INITRND == -1)
  109. INITRND = 8192;
  110. break;
  111. case 2: /* plan 9 */
  112. HEADR = 32L;
  113. if(INITTEXT == -1)
  114. INITTEXT = 8224;
  115. if(INITDAT == -1)
  116. INITDAT = 0;
  117. if(INITDAT != 0 && INITRND == -1)
  118. INITRND = 0;
  119. if(INITRND == -1)
  120. INITRND = 8192;
  121. break;
  122. case 3: /* next boot */
  123. HEADR = 28+124+192+24;
  124. if(INITTEXT == -1)
  125. INITTEXT = 0x04002000;
  126. if(INITDAT == -1)
  127. INITDAT = 0;
  128. if(INITDAT != 0 && INITRND == -1)
  129. INITRND = 0;
  130. if(INITRND == -1)
  131. INITRND = 8192L;
  132. break;
  133. case 4: /* preprocess pilot */
  134. HEADR = 32L;
  135. if(INITTEXT == -1)
  136. INITTEXT = 0;
  137. if(INITDAT == -1)
  138. INITDAT = 0;
  139. if(INITDAT != 0 && INITRND == -1)
  140. INITRND = 0;
  141. if(INITRND == -1)
  142. INITRND = 32;
  143. break;
  144. }
  145. if(INITDAT != 0 && INITRND != 0)
  146. print("warning: -D0x%lux is ignored because of -R0x%lux\n",
  147. INITDAT, INITRND);
  148. if(debug['v'])
  149. Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n",
  150. HEADTYPE, INITTEXT, INITDAT, INITRND);
  151. Bflush(&bso);
  152. for(i=1; optab[i].as; i++)
  153. if(i != optab[i].as) {
  154. diag("phase error in optab: %d", i);
  155. errorexit();
  156. }
  157. zprg.link = P;
  158. zprg.pcond = P;
  159. zprg.back = 2;
  160. zprg.as = AGOK;
  161. zprg.from.type = D_NONE;
  162. zprg.from.index = D_NONE;
  163. zprg.to = zprg.from;
  164. memset(special, 0, sizeof(special));
  165. special[D_CCR] = 1;
  166. special[D_SR] = 1;
  167. special[D_SFC] = 1;
  168. special[D_CACR] = 1;
  169. special[D_USP] = 1;
  170. special[D_VBR] = 1;
  171. special[D_CAAR] = 1;
  172. special[D_MSP] = 1;
  173. special[D_ISP] = 1;
  174. special[D_DFC] = 1;
  175. special[D_FPCR] = 1;
  176. special[D_FPSR] = 1;
  177. special[D_FPIAR] = 1;
  178. special[D_TC] = 1;
  179. special[D_ITT0] = 1;
  180. special[D_ITT1] = 1;
  181. special[D_DTT0] = 1;
  182. special[D_DTT1] = 1;
  183. special[D_MMUSR] = 1;
  184. special[D_URP] = 1;
  185. special[D_SRP] = 1;
  186. memset(simple, 0177, sizeof(simple));
  187. for(i=0; i<8; i++) {
  188. simple[D_R0+i] = i;
  189. simple[D_F0+i] = i+0100;
  190. simple[D_A0+i] = i+010;
  191. simple[D_A0+I_INDIR+i] = i+020;
  192. simple[D_A0+I_INDINC+i] = i+030;
  193. simple[D_A0+I_INDDEC+i] = i+040;
  194. }
  195. nuxiinit();
  196. histgen = 0;
  197. textp = P;
  198. datap = P;
  199. pc = 0;
  200. cout = create(outfile, 1, 0775);
  201. if(cout < 0) {
  202. diag("cannot create %s", outfile);
  203. errorexit();
  204. }
  205. version = 0;
  206. cbp = buf.cbuf;
  207. cbc = sizeof(buf.cbuf);
  208. firstp = prg();
  209. lastp = firstp;
  210. if(INITENTRY == 0) {
  211. INITENTRY = "_main";
  212. if(debug['p'])
  213. INITENTRY = "_mainp";
  214. if(!debug['l'])
  215. lookup(INITENTRY, 0)->type = SXREF;
  216. } else
  217. lookup(INITENTRY, 0)->type = SXREF;
  218. while(*argv)
  219. objfile(*argv++);
  220. if(!debug['l'])
  221. loadlib();
  222. firstp = firstp->link;
  223. if(firstp == P)
  224. errorexit();
  225. patch();
  226. if(debug['p'])
  227. if(debug['1'])
  228. doprof1();
  229. else
  230. doprof2();
  231. follow();
  232. dodata();
  233. dostkoff();
  234. span();
  235. asmb();
  236. undef();
  237. if(debug['v']) {
  238. Bprint(&bso, "%5.2f cpu time\n", cputime());
  239. Bprint(&bso, "%ld+%ld = %ld data statements\n",
  240. ndata, ncase, ndata+ncase);
  241. Bprint(&bso, "%ld symbols\n", nsymbol);
  242. Bprint(&bso, "%ld memory used\n", thunk);
  243. Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
  244. Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
  245. }
  246. Bflush(&bso);
  247. errorexit();
  248. }
  249. void
  250. loadlib(void)
  251. {
  252. int i;
  253. long h;
  254. Sym *s;
  255. loop:
  256. xrefresolv = 0;
  257. for(i=0; i<libraryp; i++) {
  258. if(debug['v'])
  259. Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
  260. objfile(library[i]);
  261. }
  262. if(xrefresolv)
  263. for(h=0; h<nelem(hash); h++)
  264. for(s = hash[h]; s != S; s = s->link)
  265. if(s->type == SXREF)
  266. goto loop;
  267. }
  268. void
  269. errorexit(void)
  270. {
  271. Bflush(&bso);
  272. if(nerrors) {
  273. if(cout >= 0)
  274. remove(outfile);
  275. exits("error");
  276. }
  277. exits(0);
  278. }
  279. void
  280. objfile(char *file)
  281. {
  282. long off, esym, cnt, l;
  283. int f, work;
  284. Sym *s;
  285. char magbuf[SARMAG];
  286. char name[100], pname[150];
  287. struct ar_hdr arhdr;
  288. char *e, *start, *stop;
  289. if(file[0] == '-' && file[1] == 'l') {
  290. if(debug['9'])
  291. sprint(name, "/%s/lib/lib", thestring);
  292. else
  293. sprint(name, "/usr/%clib/lib", thechar);
  294. strcat(name, file+2);
  295. strcat(name, ".a");
  296. file = name;
  297. }
  298. if(debug['v'])
  299. Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
  300. Bflush(&bso);
  301. f = open(file, 0);
  302. if(f < 0) {
  303. diag("cannot open file: %s", file);
  304. errorexit();
  305. }
  306. l = read(f, magbuf, SARMAG);
  307. if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
  308. /* load it as a regular file */
  309. l = seek(f, 0L, 2);
  310. seek(f, 0L, 0);
  311. ldobj(f, l, file);
  312. close(f);
  313. return;
  314. }
  315. l = read(f, &arhdr, SAR_HDR);
  316. if(l != SAR_HDR) {
  317. diag("%s: short read on archive file symbol header", file);
  318. goto out;
  319. }
  320. if(strncmp(arhdr.name, symname, strlen(symname))) {
  321. diag("%s: first entry not symbol header", file);
  322. goto out;
  323. }
  324. esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
  325. off = SARMAG + SAR_HDR;
  326. /*
  327. * just bang the whole symbol file into memory
  328. */
  329. seek(f, off, 0);
  330. cnt = esym - off;
  331. start = malloc(cnt + 10);
  332. cnt = read(f, start, cnt);
  333. if(cnt <= 0){
  334. close(f);
  335. return;
  336. }
  337. stop = &start[cnt];
  338. memset(stop, 0, 10);
  339. work = 1;
  340. while(work){
  341. if(debug['v'])
  342. Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);
  343. Bflush(&bso);
  344. work = 0;
  345. for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
  346. s = lookup(e+5, 0);
  347. if(s->type != SXREF)
  348. continue;
  349. sprint(pname, "%s(%s)", file, s->name);
  350. if(debug['v'])
  351. Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
  352. Bflush(&bso);
  353. l = e[1] & 0xff;
  354. l |= (e[2] & 0xff) << 8;
  355. l |= (e[3] & 0xff) << 16;
  356. l |= (e[4] & 0xff) << 24;
  357. seek(f, l, 0);
  358. l = read(f, &arhdr, SAR_HDR);
  359. if(l != SAR_HDR)
  360. goto bad;
  361. if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
  362. goto bad;
  363. l = atolwhex(arhdr.size);
  364. ldobj(f, l, pname);
  365. if(s->type == SXREF) {
  366. diag("%s: failed to load: %s", file, s->name);
  367. errorexit();
  368. }
  369. work = 1;
  370. xrefresolv = 1;
  371. }
  372. }
  373. return;
  374. bad:
  375. diag("%s: bad or out of date archive", file);
  376. out:
  377. close(f);
  378. }
  379. int
  380. zaddr(uchar *p, Adr *a, Sym *h[])
  381. {
  382. int c, t, i;
  383. long l;
  384. Sym *s;
  385. Auto *u;
  386. t = p[0];
  387. /*
  388. * first try the high-time formats
  389. */
  390. if(t == 0) {
  391. a->index = D_NONE;
  392. a->type = p[1];
  393. return 2;
  394. }
  395. if(t == T_OFFSET) {
  396. a->index = D_NONE;
  397. a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24);
  398. a->type = p[5];
  399. return 6;
  400. }
  401. if(t == (T_OFFSET|T_SYM)) {
  402. a->index = D_NONE;
  403. a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24);
  404. s = h[p[5]];
  405. a->sym = s;
  406. a->type = p[6];
  407. c = 7;
  408. goto dosym;
  409. }
  410. if(t == T_SYM) {
  411. a->index = D_NONE;
  412. s = h[p[1]];
  413. a->sym = s;
  414. a->type = p[2];
  415. c = 3;
  416. goto dosym;
  417. }
  418. if(t == (T_INDEX|T_OFFSET|T_SYM)) {
  419. a->index = p[1] | (p[2]<<8);
  420. a->scale = p[3];
  421. a->displace = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);
  422. a->offset = p[8] | (p[9]<<8) | (p[10]<<16) | (p[11]<<24);
  423. s = h[p[12]];
  424. a->sym = s;
  425. a->type = p[13];
  426. c = 14;
  427. goto dosym;
  428. }
  429. /*
  430. * now do it the hard way
  431. */
  432. c = 1;
  433. a->index = D_NONE;
  434. if(t & T_FIELD) {
  435. a->field = p[c] | (p[c+1]<<8);
  436. c += 2;
  437. }
  438. if(t & T_INDEX) {
  439. a->index = p[c] | (p[c+1]<<8);
  440. a->scale = p[c+2];
  441. a->displace = p[c+3] | (p[c+4]<<8) | (p[c+5]<<16) | (p[c+6]<<24);
  442. c += 7;
  443. }
  444. if(t & T_OFFSET) {
  445. a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
  446. c += 4;
  447. }
  448. if(t & T_SYM) {
  449. a->sym = h[p[c]];
  450. c += 1;
  451. }
  452. if(t & T_FCONST) {
  453. a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
  454. a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24);
  455. c += 8;
  456. a->type = D_FCONST;
  457. } else
  458. if(t & T_SCONST) {
  459. for(i=0; i<NSNAME; i++)
  460. a->scon[i] = p[c+i];
  461. c += NSNAME;
  462. a->type = D_SCONST;
  463. } else
  464. if(t & T_TYPE) {
  465. a->type = p[c] | (p[c+1]<<8);
  466. c += 2;
  467. } else {
  468. a->type = p[c];
  469. c++;
  470. }
  471. s = a->sym;
  472. if(s == S)
  473. return c;
  474. dosym:
  475. t = a->type & D_MASK;
  476. if(t != D_AUTO && t != D_PARAM)
  477. return c;
  478. l = a->offset;
  479. for(u=curauto; u; u=u->link) {
  480. if(u->asym == s)
  481. if(u->type == t) {
  482. if(u->aoffset > l)
  483. u->aoffset = l;
  484. return c;
  485. }
  486. }
  487. while(nhunk < sizeof(Auto))
  488. gethunk();
  489. u = (Auto*)hunk;
  490. nhunk -= sizeof(Auto);
  491. hunk += sizeof(Auto);
  492. u->link = curauto;
  493. curauto = u;
  494. u->asym = s;
  495. u->aoffset = l;
  496. u->type = t;
  497. return c;
  498. }
  499. void
  500. addlib(char *obj)
  501. {
  502. char name[1024], comp[256], *p;
  503. int i;
  504. if(histfrogp <= 0)
  505. return;
  506. if(histfrog[0]->name[1] == '/') {
  507. sprint(name, "");
  508. i = 1;
  509. } else
  510. if(histfrog[0]->name[1] == '.') {
  511. sprint(name, ".");
  512. i = 0;
  513. } else {
  514. if(debug['9'])
  515. sprint(name, "/%s/lib", thestring);
  516. else
  517. sprint(name, "/usr/%clib", thechar);
  518. i = 0;
  519. }
  520. for(; i<histfrogp; i++) {
  521. snprint(comp, sizeof comp, histfrog[i]->name+1);
  522. for(;;) {
  523. p = strstr(comp, "$O");
  524. if(p == 0)
  525. break;
  526. memmove(p+1, p+2, strlen(p+2)+1);
  527. p[0] = thechar;
  528. }
  529. for(;;) {
  530. p = strstr(comp, "$M");
  531. if(p == 0)
  532. break;
  533. if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
  534. diag("library component too long");
  535. return;
  536. }
  537. memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
  538. memmove(p, thestring, strlen(thestring));
  539. }
  540. if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
  541. diag("library component too long");
  542. return;
  543. }
  544. strcat(name, "/");
  545. strcat(name, comp);
  546. }
  547. for(i=0; i<libraryp; i++)
  548. if(strcmp(name, library[i]) == 0)
  549. return;
  550. if(libraryp == nelem(library)){
  551. diag("too many autolibs; skipping %s", name);
  552. return;
  553. }
  554. p = malloc(strlen(name) + 1);
  555. strcpy(p, name);
  556. library[libraryp] = p;
  557. p = malloc(strlen(obj) + 1);
  558. strcpy(p, obj);
  559. libraryobj[libraryp] = p;
  560. libraryp++;
  561. }
  562. void
  563. addhist(long line, int type)
  564. {
  565. Auto *u;
  566. Sym *s;
  567. int i, j, k;
  568. u = malloc(sizeof(Auto));
  569. s = malloc(sizeof(Sym));
  570. s->name = malloc(2*(histfrogp+1) + 1);
  571. u->asym = s;
  572. u->type = type;
  573. u->aoffset = line;
  574. u->link = curhist;
  575. curhist = u;
  576. j = 1;
  577. for(i=0; i<histfrogp; i++) {
  578. k = histfrog[i]->value;
  579. s->name[j+0] = k>>8;
  580. s->name[j+1] = k;
  581. j += 2;
  582. }
  583. }
  584. void
  585. histtoauto(void)
  586. {
  587. Auto *l;
  588. while(l = curhist) {
  589. curhist = l->link;
  590. l->link = curauto;
  591. curauto = l;
  592. }
  593. }
  594. void
  595. collapsefrog(Sym *s)
  596. {
  597. int i;
  598. /*
  599. * bad encoding of path components only allows
  600. * MAXHIST components. if there is an overflow,
  601. * first try to collapse xxx/..
  602. */
  603. for(i=1; i<histfrogp; i++)
  604. if(strcmp(histfrog[i]->name+1, "..") == 0) {
  605. memmove(histfrog+i-1, histfrog+i+1,
  606. (histfrogp-i-1)*sizeof(histfrog[0]));
  607. histfrogp--;
  608. goto out;
  609. }
  610. /*
  611. * next try to collapse .
  612. */
  613. for(i=0; i<histfrogp; i++)
  614. if(strcmp(histfrog[i]->name+1, ".") == 0) {
  615. memmove(histfrog+i, histfrog+i+1,
  616. (histfrogp-i-1)*sizeof(histfrog[0]));
  617. goto out;
  618. }
  619. /*
  620. * last chance, just truncate from front
  621. */
  622. memmove(histfrog+0, histfrog+1,
  623. (histfrogp-1)*sizeof(histfrog[0]));
  624. out:
  625. histfrog[histfrogp-1] = s;
  626. }
  627. uchar*
  628. readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
  629. {
  630. int n;
  631. n = stop - good;
  632. memmove(buf, good, stop - good);
  633. stop = buf + n;
  634. n = MAXIO - n;
  635. if(n > max)
  636. n = max;
  637. n = read(f, stop, n);
  638. if(n <= 0)
  639. return 0;
  640. return stop + n;
  641. }
  642. void
  643. ldobj(int f, long c, char *pn)
  644. {
  645. Prog *p;
  646. Sym *h[NSYM], *s;
  647. int v, o, r;
  648. long ipc, lv;
  649. double dv;
  650. uchar *bloc, *bsize, *stop;
  651. bsize = buf.xbuf;
  652. bloc = buf.xbuf;
  653. newloop:
  654. memset(h, 0, sizeof(h));
  655. version++;
  656. histfrogp = 0;
  657. ipc = pc;
  658. loop:
  659. if(c <= 0)
  660. goto eof;
  661. r = bsize - bloc;
  662. if(r < 100 && r < c) { /* enough for largest prog */
  663. bsize = readsome(f, buf.xbuf, bloc, bsize, c);
  664. if(bsize == 0)
  665. goto eof;
  666. bloc = buf.xbuf;
  667. goto loop;
  668. }
  669. o = bloc[0] | (bloc[1] << 8);
  670. if(o <= AXXX || o >= ALAST) {
  671. if(o < 0)
  672. goto eof;
  673. diag("%s: opcode out of range %d", pn, o);
  674. print(" probably not a .2 file\n");
  675. errorexit();
  676. }
  677. if(o == ANAME || o == ASIGNAME) {
  678. if(o == ASIGNAME) {
  679. bloc += 4;
  680. c -= 4;
  681. }
  682. stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
  683. if(stop == 0){
  684. bsize = readsome(f, buf.xbuf, bloc, bsize, c);
  685. if(bsize == 0)
  686. goto eof;
  687. bloc = buf.xbuf;
  688. stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
  689. if(stop == 0){
  690. fprint(2, "%s: name too long\n", pn);
  691. errorexit();
  692. }
  693. }
  694. v = bloc[2]; /* type */
  695. o = bloc[3]; /* sym */
  696. bloc += 4;
  697. c -= 4;
  698. r = 0;
  699. if(v == D_STATIC)
  700. r = version;
  701. s = lookup((char*)bloc, r);
  702. c -= &stop[1] - bloc;
  703. bloc = stop + 1;
  704. if(debug['W'])
  705. print(" ANAME %s\n", s->name);
  706. h[o] = s;
  707. if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
  708. s->type = SXREF;
  709. if(v == D_FILE) {
  710. if(s->type != SFILE) {
  711. histgen++;
  712. s->type = SFILE;
  713. s->value = histgen;
  714. }
  715. if(histfrogp < MAXHIST) {
  716. histfrog[histfrogp] = s;
  717. histfrogp++;
  718. } else
  719. collapsefrog(s);
  720. }
  721. goto loop;
  722. }
  723. while(nhunk < sizeof(Prog))
  724. gethunk();
  725. p = (Prog*)hunk;
  726. nhunk -= sizeof(Prog);
  727. hunk += sizeof(Prog);
  728. p->as = o;
  729. p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24);
  730. p->back = 2;
  731. r = zaddr(bloc+6, &p->from, h) + 6;
  732. r += zaddr(bloc+r, &p->to, h);
  733. bloc += r;
  734. c -= r;
  735. if(debug['W'])
  736. print("%P\n", p);
  737. switch(p->as) {
  738. case AHISTORY:
  739. if(p->to.offset == -1) {
  740. addlib(pn);
  741. histfrogp = 0;
  742. goto loop;
  743. }
  744. addhist(p->line, D_FILE); /* 'z' */
  745. if(p->to.offset)
  746. addhist(p->to.offset, D_FILE1); /* 'Z' */
  747. histfrogp = 0;
  748. goto loop;
  749. case AEND:
  750. histtoauto();
  751. if(curtext != P)
  752. curtext->to.autom = curauto;
  753. curauto = 0;
  754. curtext = P;
  755. if(c)
  756. goto newloop;
  757. return;
  758. case AGLOBL:
  759. s = p->from.sym;
  760. if(s->type == 0 || s->type == SXREF) {
  761. s->type = SBSS;
  762. s->value = 0;
  763. }
  764. if(s->type != SBSS) {
  765. diag("%s: redefinition: %s in %s",
  766. pn, s->name, TNAME);
  767. s->type = SBSS;
  768. s->value = 0;
  769. }
  770. if(p->to.offset > s->value)
  771. s->value = p->to.offset;
  772. goto loop;
  773. case ABCASE:
  774. ncase++;
  775. goto casdef;
  776. case ADATA:
  777. p->link = datap;
  778. datap = p;
  779. ndata++;
  780. goto loop;
  781. case AGOK:
  782. diag("%s: unknown opcode in %s", pn, TNAME);
  783. pc++;
  784. goto loop;
  785. case ATEXT:
  786. if(curtext != P) {
  787. histtoauto();
  788. curtext->to.autom = curauto;
  789. curauto = 0;
  790. }
  791. curtext = p;
  792. lastp->link = p;
  793. lastp = p;
  794. p->pc = pc;
  795. s = p->from.sym;
  796. if(s->type != 0 && s->type != SXREF)
  797. diag("%s: redefinition: %s", pn, s->name);
  798. s->type = STEXT;
  799. s->value = p->pc;
  800. pc++;
  801. p->pcond = P;
  802. if(textp == P) {
  803. textp = p;
  804. etextp = p;
  805. goto loop;
  806. }
  807. etextp->pcond = p;
  808. etextp = p;
  809. goto loop;
  810. case AJSR:
  811. p->as = ABSR;
  812. case ABSR:
  813. if(p->to.index != D_NONE)
  814. p->as = AJSR;
  815. if(p->to.type != D_EXTERN && p->to.type != D_STATIC)
  816. p->as = AJSR;
  817. goto casdef;
  818. case AMOVL:
  819. case AMOVB:
  820. case AMOVW:
  821. if(p->from.type != D_CONST)
  822. goto casdef;
  823. lv = p->from.offset;
  824. if(lv >= -128 && lv < 128)
  825. if(p->to.type >= D_R0 && p->to.type < D_R0+8)
  826. if(p->to.index == D_NONE) {
  827. p->from.type = D_QUICK;
  828. goto casdef;
  829. }
  830. if(lv >= -0x7fff && lv <= 0x7fff)
  831. if(p->to.type >= D_A0 && p->to.type < D_A0+8)
  832. if(p->to.index == D_NONE)
  833. if(p->as == AMOVL)
  834. p->as = AMOVW;
  835. goto casdef;
  836. case AADDB:
  837. case AADDL:
  838. case AADDW:
  839. if(p->from.type != D_CONST)
  840. goto casdef;
  841. lv = p->from.offset;
  842. if(lv < 0) {
  843. lv = -lv;
  844. p->from.offset = lv;
  845. if(p->as == AADDB)
  846. p->as = ASUBB;
  847. else
  848. if(p->as == AADDW)
  849. p->as = ASUBW;
  850. else
  851. if(p->as == AADDL)
  852. p->as = ASUBL;
  853. }
  854. if(lv > 0)
  855. if(lv <= 8)
  856. p->from.type = D_QUICK;
  857. goto casdef;
  858. case ASUBB:
  859. case ASUBL:
  860. case ASUBW:
  861. if(p->from.type != D_CONST)
  862. goto casdef;
  863. lv = p->from.offset;
  864. if(lv < 0) {
  865. lv = -lv;
  866. p->from.offset = lv;
  867. if(p->as == ASUBB)
  868. p->as = AADDB;
  869. else
  870. if(p->as == ASUBW)
  871. p->as = AADDW;
  872. else
  873. if(p->as == ASUBL)
  874. p->as = AADDL;
  875. }
  876. if(lv > 0)
  877. if(lv <= 8)
  878. p->from.type = D_QUICK;
  879. goto casdef;
  880. case AROTRB:
  881. case AROTRL:
  882. case AROTRW:
  883. case AROTLB:
  884. case AROTLL:
  885. case AROTLW:
  886. case AASLB:
  887. case AASLL:
  888. case AASLW:
  889. case AASRB:
  890. case AASRL:
  891. case AASRW:
  892. case ALSLB:
  893. case ALSLL:
  894. case ALSLW:
  895. case ALSRB:
  896. case ALSRL:
  897. case ALSRW:
  898. if(p->from.type == D_CONST)
  899. if(p->from.offset > 0)
  900. if(p->from.offset <= 8)
  901. p->from.type = D_QUICK;
  902. goto casdef;
  903. case ATSTL:
  904. if(p->to.type >= D_A0 && p->to.type < D_A0+8) {
  905. p->as = ACMPW;
  906. p->from = p->to;
  907. p->to.type = D_CONST;
  908. p->to.offset = 0;
  909. }
  910. goto casdef;
  911. case ACMPL:
  912. if(p->to.type != D_CONST)
  913. goto casdef;
  914. lv = p->to.offset;
  915. if(lv >= -0x7fff && lv <= 0x7fff)
  916. if(p->from.type >= D_A0 && p->from.type < D_A0+8)
  917. if(p->from.index == D_NONE)
  918. p->as = ACMPW;
  919. goto casdef;
  920. case ACLRL:
  921. if(p->to.type >= D_A0 && p->to.type < D_A0+8) {
  922. p->as = AMOVW;
  923. p->from.type = D_CONST;
  924. p->from.offset = 0;
  925. }
  926. goto casdef;
  927. casdef:
  928. default:
  929. if(p->from.type == D_FCONST)
  930. if(optab[p->as].fas != AXXX) {
  931. dv = ieeedtod(&p->from.ieee);
  932. if(dv >= -(1L<<30) && dv <= (1L<<30)) {
  933. lv = dv;
  934. if(lv == dv) {
  935. p->as = optab[p->as].fas;
  936. p->from.type = D_CONST;
  937. p->from.offset = lv;
  938. p->from.displace = 0;
  939. }
  940. }
  941. }
  942. if(p->to.type == D_BRANCH)
  943. p->to.offset += ipc;
  944. lastp->link = p;
  945. lastp = p;
  946. p->pc = pc;
  947. pc++;
  948. goto loop;
  949. }
  950. /* not reached */
  951. eof:
  952. diag("%s: truncated object file in %s", pn, TNAME);
  953. }
  954. Sym*
  955. lookup(char *symb, int v)
  956. {
  957. Sym *s;
  958. char *p;
  959. long h;
  960. int l, c;
  961. h = v;
  962. for(p=symb; c = *p; p++)
  963. h = h+h+h + c;
  964. l = (p - symb) + 1;
  965. if(h < 0)
  966. h = ~h;
  967. h %= NHASH;
  968. for(s = hash[h]; s != S; s = s->link)
  969. if(s->version == v)
  970. if(memcmp(s->name, symb, l) == 0)
  971. return s;
  972. while(nhunk < sizeof(Sym))
  973. gethunk();
  974. s = (Sym*)hunk;
  975. nhunk -= sizeof(Sym);
  976. hunk += sizeof(Sym);
  977. s->name = malloc(l + 1);
  978. memmove(s->name, symb, l);
  979. s->link = hash[h];
  980. s->type = 0;
  981. s->version = v;
  982. s->value = 0;
  983. hash[h] = s;
  984. nsymbol++;
  985. return s;
  986. }
  987. Prog*
  988. prg(void)
  989. {
  990. Prog *p;
  991. while(nhunk < sizeof(Prog))
  992. gethunk();
  993. p = (Prog*)hunk;
  994. nhunk -= sizeof(Prog);
  995. hunk += sizeof(Prog);
  996. *p = zprg;
  997. return p;
  998. }
  999. Prog*
  1000. copyp(Prog *q)
  1001. {
  1002. Prog *p;
  1003. p = prg();
  1004. *p = *q;
  1005. return p;
  1006. }
  1007. Prog*
  1008. appendp(Prog *q)
  1009. {
  1010. Prog *p;
  1011. p = prg();
  1012. p->link = q->link;
  1013. q->link = p;
  1014. p->line = q->line;
  1015. return p;
  1016. }
  1017. void
  1018. gethunk(void)
  1019. {
  1020. char *h;
  1021. long nh;
  1022. nh = NHUNK;
  1023. if(thunk >= 5L*NHUNK) {
  1024. nh = 5L*NHUNK;
  1025. if(thunk >= 25L*NHUNK)
  1026. nh = 25L*NHUNK;
  1027. }
  1028. h = mysbrk(nh);
  1029. if(h == (char*)-1) {
  1030. diag("out of memory");
  1031. errorexit();
  1032. }
  1033. hunk = h;
  1034. nhunk = nh;
  1035. thunk += nh;
  1036. }
  1037. void
  1038. doprof1(void)
  1039. {
  1040. Sym *s;
  1041. long n;
  1042. Prog *p, *q;
  1043. if(debug['v'])
  1044. Bprint(&bso, "%5.2f profile 1\n", cputime());
  1045. Bflush(&bso);
  1046. s = lookup("__mcount", 0);
  1047. n = 1;
  1048. for(p = firstp->link; p != P; p = p->link) {
  1049. if(p->as == ATEXT) {
  1050. q = prg();
  1051. q->as = AADDL;
  1052. q->line = p->line;
  1053. q->pc = p->pc;
  1054. q->link = p->link;
  1055. p->link = q;
  1056. q->from.type = D_CONST;
  1057. q->from.offset = 1;
  1058. q->to.type = D_EXTERN;
  1059. q->to.sym = s;
  1060. q->to.offset = n*4 + 4;
  1061. q = prg();
  1062. q->as = ADATA;
  1063. q->line = p->line;
  1064. q->link = datap;
  1065. datap = q;
  1066. q->from.type = D_EXTERN;
  1067. q->from.sym = s;
  1068. q->from.offset = n*4;
  1069. q->from.displace = 4;
  1070. q->to.type = D_EXTERN;
  1071. q->to.sym = p->from.sym;
  1072. n += 2;
  1073. continue;
  1074. }
  1075. }
  1076. q = prg();
  1077. q->line = 0;
  1078. q->as = ADATA;
  1079. q->link = datap;
  1080. datap = q;
  1081. q->from.type = D_EXTERN;
  1082. q->from.sym = s;
  1083. q->from.displace = 4;
  1084. q->to.type = D_CONST;
  1085. q->to.offset = n;
  1086. s->type = SBSS;
  1087. s->value = n*4;
  1088. }
  1089. void
  1090. doprof2(void)
  1091. {
  1092. Sym *s2, *s4;
  1093. Prog *p, *q, *ps2, *ps4;
  1094. if(debug['v'])
  1095. Bprint(&bso, "%5.2f profile 2\n", cputime());
  1096. Bflush(&bso);
  1097. s2 = lookup("_profin", 0);
  1098. s4 = lookup("_profout", 0);
  1099. if(s2->type != STEXT || s4->type != STEXT) {
  1100. diag("_profin/_profout not defined");
  1101. return;
  1102. }
  1103. ps2 = P;
  1104. ps4 = P;
  1105. for(p = firstp; p != P; p = p->link) {
  1106. if(p->as == ATEXT) {
  1107. if(p->from.sym == s2) {
  1108. ps2 = p;
  1109. p->from.displace = 1;
  1110. }
  1111. if(p->from.sym == s4) {
  1112. ps4 = p;
  1113. p->from.displace = 1;
  1114. }
  1115. }
  1116. }
  1117. for(p = firstp; p != P; p = p->link) {
  1118. if(p->as == ATEXT) {
  1119. if(p->from.displace != 0) {
  1120. for(;;) {
  1121. q = p->link;
  1122. if(q == P)
  1123. break;
  1124. if(q->as == ATEXT)
  1125. break;
  1126. p = q;
  1127. }
  1128. continue;
  1129. }
  1130. q = prg();
  1131. q->line = p->line;
  1132. q->pc = p->pc;
  1133. q->link = p->link;
  1134. p->link = q;
  1135. p = q;
  1136. p->as = ABSR;
  1137. p->to.type = D_BRANCH;
  1138. p->pcond = ps2;
  1139. p->to.sym = s2;
  1140. continue;
  1141. }
  1142. if(p->as == ARTS) {
  1143. /*
  1144. * RTS
  1145. */
  1146. q = prg();
  1147. q->as = ARTS;
  1148. q->from = p->from;
  1149. q->to = p->to;
  1150. q->link = p->link;
  1151. p->link = q;
  1152. /*
  1153. * BSR profout
  1154. */
  1155. p->as = ABSR;
  1156. p->from = zprg.from;
  1157. p->to = zprg.to;
  1158. p->to.type = D_BRANCH;
  1159. p->pcond = ps4;
  1160. p->to.sym = s4;
  1161. p = q;
  1162. continue;
  1163. }
  1164. }
  1165. }
  1166. long
  1167. reuse(Prog *r, Sym *s)
  1168. {
  1169. Prog *p;
  1170. if(r == P)
  1171. return 0;
  1172. for(p = datap; p != r; p = p->link)
  1173. if(p->to.sym == s)
  1174. return p->from.offset;
  1175. return 0;
  1176. }
  1177. void
  1178. nuxiinit(void)
  1179. {
  1180. int i, c;
  1181. for(i=0; i<4; i++) {
  1182. c = find1(0x01020304L, i+1);
  1183. if(i >= 2)
  1184. inuxi2[i-2] = c;
  1185. if(i >= 3)
  1186. inuxi1[i-3] = c;
  1187. inuxi4[i] = c;
  1188. fnuxi8[i] = c+4;
  1189. fnuxi8[i+4] = c;
  1190. c = find2(0x01020304L, i+1);
  1191. gnuxi8[i] = c+4;
  1192. gnuxi8[i+4] = c;
  1193. }
  1194. if(debug['v']) {
  1195. Bprint(&bso, "inuxi = ");
  1196. for(i=0; i<1; i++)
  1197. Bprint(&bso, "%d", inuxi1[i]);
  1198. Bprint(&bso, " ");
  1199. for(i=0; i<2; i++)
  1200. Bprint(&bso, "%d", inuxi2[i]);
  1201. Bprint(&bso, " ");
  1202. for(i=0; i<4; i++)
  1203. Bprint(&bso, "%d", inuxi4[i]);
  1204. Bprint(&bso, "\n[fg]nuxi = ");
  1205. for(i=0; i<8; i++)
  1206. Bprint(&bso, "%d", fnuxi8[i]);
  1207. Bprint(&bso, " ");
  1208. for(i=0; i<8; i++)
  1209. Bprint(&bso, "%d", gnuxi8[i]);
  1210. Bprint(&bso, "\n");
  1211. }
  1212. Bflush(&bso);
  1213. }
  1214. int
  1215. find1(long l, int c)
  1216. {
  1217. char *p;
  1218. int i;
  1219. p = (char*)&l;
  1220. for(i=0; i<4; i++)
  1221. if(*p++ == c)
  1222. return i;
  1223. return 0;
  1224. }
  1225. int
  1226. find2(long l, int c)
  1227. {
  1228. short *p;
  1229. int i;
  1230. p = (short*)&l;
  1231. for(i=0; i<4; i+=2) {
  1232. if(((*p >> 8) & 0xff) == c)
  1233. return i;
  1234. if((*p++ & 0xff) == c)
  1235. return i+1;
  1236. }
  1237. return 0;
  1238. }
  1239. long
  1240. ieeedtof(Ieee *e)
  1241. {
  1242. int exp;
  1243. long v;
  1244. if(e->h == 0)
  1245. return 0;
  1246. exp = (e->h>>20) & ((1L<<11)-1L);
  1247. exp -= (1L<<10) - 2L;
  1248. v = (e->h & 0xfffffL) << 3;
  1249. v |= (e->l >> 29) & 0x7L;
  1250. if((e->l >> 28) & 1) {
  1251. v++;
  1252. if(v & 0x800000L) {
  1253. v = (v & 0x7fffffL) >> 1;
  1254. exp++;
  1255. }
  1256. }
  1257. if(exp <= -126 || exp >= 130)
  1258. diag("double fp to single fp overflow");
  1259. v |= ((exp + 126) & 0xffL) << 23;
  1260. v |= e->h & 0x80000000L;
  1261. return v;
  1262. }
  1263. double
  1264. ieeedtod(Ieee *ieeep)
  1265. {
  1266. Ieee e;
  1267. double fr;
  1268. int exp;
  1269. if(ieeep->h & (1L<<31)) {
  1270. e.h = ieeep->h & ~(1L<<31);
  1271. e.l = ieeep->l;
  1272. return -ieeedtod(&e);
  1273. }
  1274. if(ieeep->l == 0 && ieeep->h == 0)
  1275. return 0;
  1276. fr = ieeep->l & ((1L<<16)-1L);
  1277. fr /= 1L<<16;
  1278. fr += (ieeep->l>>16) & ((1L<<16)-1L);
  1279. fr /= 1L<<16;
  1280. fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
  1281. fr /= 1L<<21;
  1282. exp = (ieeep->h>>20) & ((1L<<11)-1L);
  1283. exp -= (1L<<10) - 2L;
  1284. return ldexp(fr, exp);
  1285. }