pass.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. #include "l.h"
  2. void
  3. dodata(void)
  4. {
  5. int i, t;
  6. Sym *s;
  7. Prog *p, *p1;
  8. vlong orig, orig1, v;
  9. if(debug['v'])
  10. Bprint(&bso, "%5.2f dodata\n", cputime());
  11. Bflush(&bso);
  12. for(p = datap; p != P; p = p->link) {
  13. s = p->from.sym;
  14. if(p->as == ADYNT || p->as == AINIT)
  15. s->value = dtype;
  16. if(s->type == SBSS)
  17. s->type = SDATA;
  18. if(s->type != SDATA)
  19. diag("initialize non-data (%d): %s\n%P",
  20. s->type, s->name, p);
  21. v = p->from.offset + p->reg;
  22. if(v > s->value)
  23. diag("initialize bounds (%lld): %s\n%P",
  24. s->value, s->name, p);
  25. }
  26. /*
  27. * pass 1
  28. * assign 'small' variables to data segment
  29. * (rational is that data segment is more easily
  30. * addressed through offset on REGSB)
  31. */
  32. orig = 0;
  33. for(i=0; i<NHASH; i++)
  34. for(s = hash[i]; s != S; s = s->link) {
  35. t = s->type;
  36. if(t != SDATA && t != SBSS)
  37. continue;
  38. v = s->value;
  39. if(v == 0) {
  40. diag("%s: no size", s->name);
  41. v = 1;
  42. }
  43. v = rnd(v, 4);
  44. s->value = v;
  45. if(v > MINSIZ)
  46. continue;
  47. if(v >= 8)
  48. orig = rnd(orig, 8);
  49. s->value = orig;
  50. orig += v;
  51. s->type = SDATA1;
  52. }
  53. orig1 = orig;
  54. /*
  55. * pass 2
  56. * assign 'data' variables to data segment
  57. */
  58. for(i=0; i<NHASH; i++)
  59. for(s = hash[i]; s != S; s = s->link) {
  60. t = s->type;
  61. if(t != SDATA) {
  62. if(t == SDATA1)
  63. s->type = SDATA;
  64. continue;
  65. }
  66. v = s->value;
  67. if(v >= 8)
  68. orig = rnd(orig, 8);
  69. s->value = orig;
  70. orig += v;
  71. s->type = SDATA1;
  72. }
  73. if(orig)
  74. orig = rnd(orig, 8);
  75. datsize = orig;
  76. /*
  77. * pass 3
  78. * everything else to bss segment
  79. */
  80. for(i=0; i<NHASH; i++)
  81. for(s = hash[i]; s != S; s = s->link) {
  82. if(s->type != SBSS)
  83. continue;
  84. v = s->value;
  85. if(v >= 8)
  86. orig = rnd(orig, 8);
  87. s->value = orig;
  88. orig += v;
  89. }
  90. if(orig)
  91. orig = rnd(orig, 8);
  92. bsssize = orig-datsize;
  93. /*
  94. * pass 4
  95. * add literals to all large values.
  96. * at this time:
  97. * small data is allocated DATA
  98. * large data is allocated DATA1
  99. * large bss is allocated BSS
  100. * the new literals are loaded between
  101. * small data and large data.
  102. */
  103. orig = 0;
  104. for(p = firstp; p != P; p = p->link) {
  105. if(p->as != AMOVW)
  106. continue;
  107. if(p->from.type != D_CONST)
  108. continue;
  109. if(s = p->from.sym) {
  110. t = s->type;
  111. if(t != SDATA && t != SDATA1 && t != SBSS)
  112. continue;
  113. t = p->from.name;
  114. if(t != D_EXTERN && t != D_STATIC)
  115. continue;
  116. v = s->value + p->from.offset;
  117. if(v >= 0 && v <= 0xffff)
  118. continue;
  119. if(!strcmp(s->name, "setSB"))
  120. continue;
  121. /* size should be 19 max */
  122. if(strlen(s->name) >= 10) /* has loader address */
  123. sprint(literal, "$%p.%llux", s, p->from.offset);
  124. else
  125. sprint(literal, "$%s.%d.%llux", s->name, s->version, p->from.offset);
  126. } else {
  127. if(p->from.name != D_NONE)
  128. continue;
  129. if(p->from.reg != NREG)
  130. continue;
  131. v = p->from.offset;
  132. if(v >= -0x7fff-1 && v <= 0x7fff)
  133. continue;
  134. if(!(v & 0xffff))
  135. continue;
  136. if(v)
  137. continue; /* quicker to build it than load it */
  138. /* size should be 9 max */
  139. sprint(literal, "$%llux", v);
  140. }
  141. s = lookup(literal, 0);
  142. if(s->type == 0) {
  143. s->type = SDATA;
  144. s->value = orig1+orig;
  145. orig += 4;
  146. p1 = prg();
  147. p1->as = ADATA;
  148. p1->line = p->line;
  149. p1->from.type = D_OREG;
  150. p1->from.sym = s;
  151. p1->from.name = D_EXTERN;
  152. p1->reg = 4;
  153. p1->to = p->from;
  154. p1->link = datap;
  155. datap = p1;
  156. }
  157. if(s->type != SDATA)
  158. diag("literal not data: %s", s->name);
  159. p->from.type = D_OREG;
  160. p->from.sym = s;
  161. p->from.name = D_EXTERN;
  162. p->from.offset = 0;
  163. continue;
  164. }
  165. while(orig & 7)
  166. orig++;
  167. /*
  168. * pass 5
  169. * re-adjust offsets
  170. */
  171. for(i=0; i<NHASH; i++)
  172. for(s = hash[i]; s != S; s = s->link) {
  173. t = s->type;
  174. if(t == SBSS) {
  175. s->value += orig;
  176. continue;
  177. }
  178. if(t == SDATA1) {
  179. s->type = SDATA;
  180. s->value += orig;
  181. continue;
  182. }
  183. }
  184. datsize += orig;
  185. xdefine("setSB", SDATA, 0+BIG);
  186. xdefine("bdata", SDATA, 0);
  187. xdefine("edata", SDATA, datsize);
  188. xdefine("end", SBSS, datsize+bsssize);
  189. xdefine("etext", STEXT, 0);
  190. }
  191. void
  192. undef(void)
  193. {
  194. int i;
  195. Sym *s;
  196. for(i=0; i<NHASH; i++)
  197. for(s = hash[i]; s != S; s = s->link)
  198. if(s->type == SXREF)
  199. diag("%s: not defined", s->name);
  200. }
  201. int
  202. relinv(int a)
  203. {
  204. switch(a) {
  205. case ABEQ: return ABNE;
  206. case ABNE: return ABEQ;
  207. case ABGE: return ABLT;
  208. case ABLT: return ABGE;
  209. case ABGT: return ABLE;
  210. case ABLE: return ABGT;
  211. case ABVC: return ABVS;
  212. case ABVS: return ABVC;
  213. }
  214. return 0;
  215. }
  216. void
  217. follow(void)
  218. {
  219. if(debug['v'])
  220. Bprint(&bso, "%5.2f follow\n", cputime());
  221. Bflush(&bso);
  222. firstp = prg();
  223. lastp = firstp;
  224. xfol(textp);
  225. firstp = firstp->link;
  226. lastp->link = P;
  227. }
  228. void
  229. xfol(Prog *p)
  230. {
  231. Prog *q, *r;
  232. int a, b, i;
  233. loop:
  234. if(p == P)
  235. return;
  236. a = p->as;
  237. if(a == ATEXT)
  238. curtext = p;
  239. if(a == ABR) {
  240. q = p->cond;
  241. if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
  242. p->mark |= FOLL;
  243. lastp->link = p;
  244. lastp = p;
  245. p = p->link;
  246. xfol(p);
  247. p = q;
  248. if(p && !(p->mark & FOLL))
  249. goto loop;
  250. return;
  251. }
  252. if(q != P) {
  253. p->mark |= FOLL;
  254. p = q;
  255. if(!(p->mark & FOLL))
  256. goto loop;
  257. }
  258. }
  259. if(p->mark & FOLL) {
  260. for(i=0,q=p; i<4; i++,q=q->link) {
  261. if(q == lastp || (q->mark&NOSCHED))
  262. break;
  263. b = 0; /* set */
  264. a = q->as;
  265. if(a == ANOP) {
  266. i--;
  267. continue;
  268. }
  269. if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
  270. goto copy;
  271. if(!q->cond || (q->cond->mark&FOLL))
  272. continue;
  273. b = relinv(a);
  274. if(!b)
  275. continue;
  276. copy:
  277. for(;;) {
  278. r = prg();
  279. *r = *p;
  280. if(!(r->mark&FOLL))
  281. print("cant happen 1\n");
  282. r->mark |= FOLL;
  283. if(p != q) {
  284. p = p->link;
  285. lastp->link = r;
  286. lastp = r;
  287. continue;
  288. }
  289. lastp->link = r;
  290. lastp = r;
  291. if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
  292. return;
  293. r->as = b;
  294. r->cond = p->link;
  295. r->link = p->cond;
  296. if(!(r->link->mark&FOLL))
  297. xfol(r->link);
  298. if(!(r->cond->mark&FOLL))
  299. print("cant happen 2\n");
  300. return;
  301. }
  302. }
  303. a = ABR;
  304. q = prg();
  305. q->as = a;
  306. q->line = p->line;
  307. q->to.type = D_BRANCH;
  308. q->to.offset = p->pc;
  309. q->cond = p;
  310. p = q;
  311. }
  312. p->mark |= FOLL;
  313. lastp->link = p;
  314. lastp = p;
  315. if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID){
  316. if(p->mark & NOSCHED){
  317. p = p->link;
  318. goto loop;
  319. }
  320. return;
  321. }
  322. if(p->cond != P)
  323. if(a != ABL && p->link != P) {
  324. xfol(p->link);
  325. p = p->cond;
  326. if(p == P || (p->mark&FOLL))
  327. return;
  328. goto loop;
  329. }
  330. p = p->link;
  331. goto loop;
  332. }
  333. void
  334. patch(void)
  335. {
  336. long c;
  337. Prog *p, *q;
  338. Sym *s;
  339. int a;
  340. vlong vexit;
  341. if(debug['v'])
  342. Bprint(&bso, "%5.2f patch\n", cputime());
  343. Bflush(&bso);
  344. mkfwd();
  345. s = lookup("exit", 0);
  346. vexit = s->value;
  347. for(p = firstp; p != P; p = p->link) {
  348. a = p->as;
  349. if(a == ATEXT)
  350. curtext = p;
  351. if((a == ABL || a == ARETURN) && p->to.sym != S) {
  352. s = p->to.sym;
  353. if(s->type != STEXT && s->type != SUNDEF) {
  354. diag("undefined: %s\n%P", s->name, p);
  355. s->type = STEXT;
  356. s->value = vexit;
  357. }
  358. if(s->type == SUNDEF){
  359. p->to.offset = 0;
  360. p->cond = UP;
  361. }
  362. else
  363. p->to.offset = s->value;
  364. p->to.type = D_BRANCH;
  365. }
  366. if(p->to.type != D_BRANCH || p->cond == UP)
  367. continue;
  368. c = p->to.offset;
  369. for(q = firstp; q != P;) {
  370. if(q->forwd != P)
  371. if(c >= q->forwd->pc) {
  372. q = q->forwd;
  373. continue;
  374. }
  375. if(c == q->pc)
  376. break;
  377. q = q->link;
  378. }
  379. if(q == P) {
  380. diag("branch out of range %ld\n%P", c, p);
  381. p->to.type = D_NONE;
  382. }
  383. p->cond = q;
  384. }
  385. for(p = firstp; p != P; p = p->link) {
  386. if(p->as == ATEXT)
  387. curtext = p;
  388. p->mark = 0; /* initialization for follow */
  389. if(p->cond != P && p->cond != UP) {
  390. p->cond = brloop(p->cond);
  391. if(p->cond != P)
  392. if(p->to.type == D_BRANCH)
  393. p->to.offset = p->cond->pc;
  394. }
  395. }
  396. }
  397. #define LOG 5
  398. void
  399. mkfwd(void)
  400. {
  401. Prog *p;
  402. long dwn[LOG], cnt[LOG], i;
  403. Prog *lst[LOG];
  404. for(i=0; i<LOG; i++) {
  405. if(i == 0)
  406. cnt[i] = 1; else
  407. cnt[i] = LOG * cnt[i-1];
  408. dwn[i] = 1;
  409. lst[i] = P;
  410. }
  411. i = 0;
  412. for(p = firstp; p != P; p = p->link) {
  413. if(p->as == ATEXT)
  414. curtext = p;
  415. i--;
  416. if(i < 0)
  417. i = LOG-1;
  418. p->forwd = P;
  419. dwn[i]--;
  420. if(dwn[i] <= 0) {
  421. dwn[i] = cnt[i];
  422. if(lst[i] != P)
  423. lst[i]->forwd = p;
  424. lst[i] = p;
  425. }
  426. }
  427. }
  428. Prog*
  429. brloop(Prog *p)
  430. {
  431. Prog *q;
  432. int c;
  433. for(c=0; p!=P;) {
  434. if(p->as != ABR || (p->mark&NOSCHED))
  435. return p;
  436. q = p->cond;
  437. if(q <= p) {
  438. c++;
  439. if(q == p || c > 5000)
  440. break;
  441. }
  442. p = q;
  443. }
  444. return P;
  445. }
  446. vlong
  447. atolwhex(char *s)
  448. {
  449. vlong n;
  450. int f;
  451. n = 0;
  452. f = 0;
  453. while(*s == ' ' || *s == '\t')
  454. s++;
  455. if(*s == '-' || *s == '+') {
  456. if(*s++ == '-')
  457. f = 1;
  458. while(*s == ' ' || *s == '\t')
  459. s++;
  460. }
  461. if(s[0]=='0' && s[1]){
  462. if(s[1]=='x' || s[1]=='X'){
  463. s += 2;
  464. for(;;){
  465. if(*s >= '0' && *s <= '9')
  466. n = n*16 + *s++ - '0';
  467. else if(*s >= 'a' && *s <= 'f')
  468. n = n*16 + *s++ - 'a' + 10;
  469. else if(*s >= 'A' && *s <= 'F')
  470. n = n*16 + *s++ - 'A' + 10;
  471. else
  472. break;
  473. }
  474. } else
  475. while(*s >= '0' && *s <= '7')
  476. n = n*8 + *s++ - '0';
  477. } else
  478. while(*s >= '0' && *s <= '9')
  479. n = n*10 + *s++ - '0';
  480. if(f)
  481. n = -n;
  482. return n;
  483. }
  484. vlong
  485. rnd(vlong v, long r)
  486. {
  487. vlong c;
  488. if(r <= 0)
  489. return v;
  490. v += r - 1;
  491. c = v % r;
  492. if(c < 0)
  493. c += r;
  494. v -= c;
  495. return v;
  496. }
  497. void
  498. import(void)
  499. {
  500. int i;
  501. Sym *s;
  502. for(i = 0; i < NHASH; i++)
  503. for(s = hash[i]; s != S; s = s->link)
  504. if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
  505. undefsym(s);
  506. Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value);
  507. if(debug['S'])
  508. s->sig = 0;
  509. }
  510. }
  511. void
  512. ckoff(Sym *s, vlong v)
  513. {
  514. if(v < 0 || v >= 1<<Roffset)
  515. diag("relocation offset %lld for %s out of range", v, s->name);
  516. }
  517. static Prog*
  518. newdata(Sym *s, int o, int w, int t)
  519. {
  520. Prog *p;
  521. p = prg();
  522. p->link = datap;
  523. datap = p;
  524. p->as = ADATA;
  525. p->reg = w;
  526. p->from.type = D_OREG;
  527. p->from.name = t;
  528. p->from.sym = s;
  529. p->from.offset = o;
  530. p->to.type = D_CONST;
  531. p->to.name = D_NONE;
  532. return p;
  533. }
  534. void
  535. export(void)
  536. {
  537. int i, j, n, off, nb, sv, ne;
  538. Sym *s, *et, *str, **esyms;
  539. Prog *p;
  540. char buf[NSNAME], *t;
  541. n = 0;
  542. for(i = 0; i < NHASH; i++)
  543. for(s = hash[i]; s != S; s = s->link)
  544. if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
  545. n++;
  546. esyms = malloc(n*sizeof(Sym*));
  547. ne = n;
  548. n = 0;
  549. for(i = 0; i < NHASH; i++)
  550. for(s = hash[i]; s != S; s = s->link)
  551. if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
  552. esyms[n++] = s;
  553. for(i = 0; i < ne-1; i++)
  554. for(j = i+1; j < ne; j++)
  555. if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
  556. s = esyms[i];
  557. esyms[i] = esyms[j];
  558. esyms[j] = s;
  559. }
  560. nb = 0;
  561. off = 0;
  562. et = lookup(EXPTAB, 0);
  563. if(et->type != 0 && et->type != SXREF)
  564. diag("%s already defined", EXPTAB);
  565. et->type = SDATA;
  566. str = lookup(".string", 0);
  567. if(str->type == 0)
  568. str->type = SDATA;
  569. sv = str->value;
  570. for(i = 0; i < ne; i++){
  571. s = esyms[i];
  572. Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type);
  573. /* signature */
  574. p = newdata(et, off, sizeof(long), D_EXTERN);
  575. off += sizeof(long);
  576. p->to.offset = s->sig;
  577. /* address */
  578. p = newdata(et, off, sizeof(long), D_EXTERN);
  579. off += sizeof(long); /* TO DO: bug */
  580. p->to.name = D_EXTERN;
  581. p->to.sym = s;
  582. /* string */
  583. t = s->name;
  584. n = strlen(t)+1;
  585. for(;;){
  586. buf[nb++] = *t;
  587. sv++;
  588. if(nb >= NSNAME){
  589. p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
  590. p->to.type = D_SCONST;
  591. memmove(p->to.sval, buf, NSNAME);
  592. nb = 0;
  593. }
  594. if(*t++ == 0)
  595. break;
  596. }
  597. /* name */
  598. p = newdata(et, off, sizeof(long), D_EXTERN);
  599. off += sizeof(long);
  600. p->to.name = D_STATIC;
  601. p->to.sym = str;
  602. p->to.offset = sv-n;
  603. }
  604. if(nb > 0){
  605. p = newdata(str, sv-nb, nb, D_STATIC);
  606. p->to.type = D_SCONST;
  607. memmove(p->to.sval, buf, nb);
  608. }
  609. for(i = 0; i < 3; i++){
  610. newdata(et, off, sizeof(long), D_EXTERN);
  611. off += sizeof(long);
  612. }
  613. et->value = off;
  614. if(sv == 0)
  615. sv = 1;
  616. str->value = sv;
  617. exports = ne;
  618. free(esyms);
  619. }