asm.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. #include "l.h"
  2. #define Dbufslop 100
  3. long
  4. entryvalue(void)
  5. {
  6. char *a;
  7. Sym *s;
  8. a = INITENTRY;
  9. if(*a >= '0' && *a <= '9')
  10. return atolwhex(a);
  11. s = lookup(a, 0);
  12. if(s->type == 0)
  13. return INITTEXT;
  14. if(s->type != STEXT && s->type != SLEAF)
  15. diag("entry not text: %s %d", s->name, s->type);
  16. return s->value;
  17. }
  18. void
  19. asmb(void)
  20. {
  21. Prog *p;
  22. long v;
  23. ulong *op1;
  24. if(debug['v'])
  25. Bprint(&bso, "%5.2f asmb\n", cputime());
  26. Bflush(&bso);
  27. seek(cout, HEADR, 0);
  28. pc = INITTEXT;
  29. curp = firstp;
  30. for(p = firstp; p != P; p = p->link) {
  31. if(p->as == ATEXT) {
  32. curtext = p;
  33. autosize = p->to.offset + 4;
  34. }
  35. if(p->pc != pc) {
  36. if(!debug['a'])
  37. print("%P\n", curp);
  38. diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME);
  39. pc = p->pc;
  40. }
  41. curp = p;
  42. asmins(p);
  43. if(cbc < sizeof(and))
  44. cflush();
  45. if(debug['a']) {
  46. Bprint(&bso, pcstr, pc);
  47. for(op1 = and; op1 < andptr; op1++)
  48. Bprint(&bso, " %.8lux", *op1);
  49. Bprint(&bso, "\t%P\n", curp);
  50. }
  51. for(op1 = and; op1 < andptr; op1++) {
  52. v = *op1;
  53. cbp[0] = v;
  54. cbp[1] = v>>8;
  55. cbp[2] = v>>16;
  56. cbp[3] = v>>24;
  57. cbp += 4;
  58. pc += 4;
  59. cbc -= 4;
  60. }
  61. }
  62. cflush();
  63. switch(HEADTYPE) {
  64. default:
  65. diag("unknown header type %d", HEADTYPE);
  66. case 0:
  67. seek(cout, rnd(HEADR+textsize, 8192), 0);
  68. break;
  69. case 1:
  70. textsize = rnd(HEADR+textsize, 4096)-HEADR;
  71. seek(cout, textsize+HEADR, 0);
  72. break;
  73. case 2:
  74. seek(cout, HEADR+textsize, 0);
  75. break;
  76. case 3:
  77. seek(cout, HEADR+rnd(textsize, INITRND), 0);
  78. break;
  79. case 4:
  80. textsize = rnd(textsize, 4);
  81. seek(cout, textsize+HEADR, 0);
  82. break;
  83. }
  84. if(debug['v'])
  85. Bprint(&bso, "%5.2f datblk\n", cputime());
  86. Bflush(&bso);
  87. for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
  88. if(datsize-v > sizeof(buf)-Dbufslop)
  89. datblk(v, sizeof(buf)-Dbufslop);
  90. else
  91. datblk(v, datsize-v);
  92. }
  93. symsize = 0;
  94. lcsize = 0;
  95. if(!debug['s']) {
  96. if(debug['v'])
  97. Bprint(&bso, "%5.2f sym\n", cputime());
  98. Bflush(&bso);
  99. switch(HEADTYPE) {
  100. default:
  101. case 0:
  102. seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
  103. break;
  104. case 1:
  105. seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
  106. break;
  107. case 2:
  108. seek(cout, HEADR+textsize+datsize, 0);
  109. break;
  110. case 3:
  111. debug['s'] = 1;
  112. break;
  113. case 4:
  114. debug['s'] = 1;
  115. break;
  116. }
  117. if(!debug['s'])
  118. asmsym();
  119. if(debug['v'])
  120. Bprint(&bso, "%5.2f sp\n", cputime());
  121. Bflush(&bso);
  122. if(!debug['s'])
  123. asmlc();
  124. cflush();
  125. }
  126. if(debug['v'])
  127. Bprint(&bso, "%5.2f headr\n", cputime());
  128. Bflush(&bso);
  129. seek(cout, 0L, 0);
  130. switch(HEADTYPE) {
  131. default:
  132. case 0: /* garbage */
  133. lput(0x160L<<16); /* magic and sections */
  134. lput(0L); /* time and date */
  135. lput(rnd(HEADR+textsize, 4096)+datsize);
  136. lput(symsize); /* nsyms */
  137. lput((0x38L<<16)|7L); /* size of optional hdr and flags */
  138. lput((0413<<16)|0437L); /* magic and version */
  139. lput(rnd(HEADR+textsize, 4096)); /* sizes */
  140. lput(datsize);
  141. lput(bsssize);
  142. lput(entryvalue()); /* va of entry */
  143. lput(INITTEXT-HEADR); /* va of base of text */
  144. lput(INITDAT); /* va of base of data */
  145. lput(INITDAT+datsize); /* va of base of bss */
  146. lput(~0L); /* gp reg mask */
  147. lput(0L);
  148. lput(0L);
  149. lput(0L);
  150. lput(0L);
  151. lput(~0L); /* gp value ?? */
  152. break;
  153. case 1: /* unix coff */
  154. case 4:
  155. /*
  156. * file header
  157. */
  158. if(HEADTYPE == 4)
  159. lputl(0x00020161); /* 2 sections, magic */
  160. else
  161. lputl(0x0002014c); /* 2 sections, magic */
  162. lputl(0); /* unix time stamp */
  163. lputl(0); /* symbol table */
  164. lputl(0); /* nsyms */
  165. lputl(0x00030020); /* flags, sizeof a.out header */
  166. /*
  167. * a.out header
  168. */
  169. lputl(0x10b); /* magic, version stamp */
  170. lputl(rnd(textsize, INITRND)); /* text sizes */
  171. lputl(datsize); /* data sizes */
  172. lputl(bsssize); /* bss sizes */
  173. lput(entryvalue()); /* va of entry */
  174. lputl(INITTEXT); /* text start */
  175. lputl(INITDAT); /* data start */
  176. lputl(0); /* tag entries */
  177. /*
  178. * text section header
  179. */
  180. s8put(".text");
  181. lputl(INITTEXT); /* pa */
  182. lputl(INITTEXT); /* va */
  183. lputl(textsize); /* text size */
  184. lputl(HEADR); /* file offset */
  185. lputl(0); /* relocation */
  186. lputl(0); /* line numbers */
  187. lputl(0); /* relocation, line numbers */
  188. lputl(0x20); /* flags text only */
  189. lputl(0); /* alignment */
  190. /*
  191. * data section header
  192. */
  193. s8put(".data");
  194. lputl(INITDAT); /* pa */
  195. lputl(INITDAT); /* va */
  196. lputl(datsize); /* data size */
  197. lputl(HEADR+textsize); /* file offset */
  198. lputl(0); /* relocation */
  199. lputl(0); /* line numbers */
  200. lputl(0); /* relocation, line numbers */
  201. lputl(0x40); /* flags data only */
  202. lputl(0); /* alignment */
  203. break;
  204. case 2: /* plan9 */
  205. lput(4*12*12+7); /* magic */
  206. lput(textsize); /* sizes */
  207. lput(datsize);
  208. lput(bsssize);
  209. lput(symsize); /* nsyms */
  210. lput(entryvalue()); /* va of entry */
  211. lput(0); /* sp offsets */
  212. lput(lcsize); /* line offsets */
  213. break;
  214. case 3:
  215. /* msdos boot */
  216. break;
  217. }
  218. cflush();
  219. }
  220. void
  221. lput(long l)
  222. {
  223. CPUT(l>>24)
  224. CPUT(l>>16)
  225. CPUT(l>>8)
  226. CPUT(l)
  227. }
  228. void
  229. lputl(long l)
  230. {
  231. CPUT(l)
  232. CPUT(l>>8)
  233. CPUT(l>>16)
  234. CPUT(l>>24)
  235. }
  236. void
  237. s8put(char *n)
  238. {
  239. char name[8];
  240. int i;
  241. strncpy(name, n, sizeof(name));
  242. for(i=0; i<sizeof(name); i++)
  243. CPUT(name[i])
  244. }
  245. void
  246. cflush(void)
  247. {
  248. int n;
  249. n = sizeof(buf.cbuf) - cbc;
  250. if(n)
  251. write(cout, buf.cbuf, n);
  252. cbp = buf.cbuf;
  253. cbc = sizeof(buf.cbuf);
  254. }
  255. void
  256. datblk(long s, long n)
  257. {
  258. Prog *p;
  259. char *cast;
  260. long l, fl, j;
  261. int i, c;
  262. memset(buf.dbuf, 0, n+Dbufslop);
  263. for(p = datap; p != P; p = p->link) {
  264. curp = p;
  265. l = p->from.sym->value + p->from.offset - s;
  266. c = p->from.scale;
  267. i = 0;
  268. if(l < 0) {
  269. if(l+c <= 0)
  270. continue;
  271. while(l < 0) {
  272. l++;
  273. i++;
  274. }
  275. }
  276. if(l >= n)
  277. continue;
  278. for(j=l+(c-i)-1; j>=l; j--)
  279. if(buf.dbuf[j]) {
  280. print("%P\n", p);
  281. diag("multiple initialization");
  282. break;
  283. }
  284. switch(p->to.type) {
  285. case D_FCONST:
  286. switch(c) {
  287. default:
  288. case 4:
  289. fl = ieeedtof(&p->to.ieee);
  290. cast = (char*)&fl;
  291. if(debug['a'] && i == 0) {
  292. Bprint(&bso, pcstr, l+s+INITDAT);
  293. for(j=0; j<c; j++)
  294. Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);
  295. Bprint(&bso, "\t%P\n", curp);
  296. }
  297. for(; i<c; i++) {
  298. buf.dbuf[l] = cast[fnuxi4[i]];
  299. l++;
  300. }
  301. break;
  302. case 8:
  303. cast = (char*)&p->to.ieee;
  304. if(debug['a'] && i == 0) {
  305. Bprint(&bso, pcstr, l+s+INITDAT);
  306. for(j=0; j<c; j++)
  307. Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
  308. Bprint(&bso, "\t%P\n", curp);
  309. }
  310. for(; i<c; i++) {
  311. buf.dbuf[l] = cast[fnuxi8[i]];
  312. l++;
  313. }
  314. break;
  315. }
  316. break;
  317. case D_SCONST:
  318. if(debug['a'] && i == 0) {
  319. Bprint(&bso, pcstr, l+s+INITDAT);
  320. for(j=0; j<c; j++)
  321. Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
  322. Bprint(&bso, "\t%P\n", curp);
  323. }
  324. for(; i<c; i++) {
  325. buf.dbuf[l] = p->to.scon[i];
  326. l++;
  327. }
  328. break;
  329. default:
  330. fl = p->to.offset;
  331. if(p->to.type == D_ADDR) {
  332. if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
  333. diag("DADDR type%P", p);
  334. if(p->to.sym) {
  335. fl += p->to.sym->value;
  336. if(p->to.sym->type != STEXT && p->to.sym->type != SLEAF)
  337. fl += INITDAT;
  338. }
  339. }
  340. cast = (char*)&fl;
  341. switch(c) {
  342. default:
  343. diag("bad nuxi %d %d\n%P", c, i, curp);
  344. break;
  345. case 1:
  346. if(debug['a'] && i == 0) {
  347. Bprint(&bso, pcstr, l+s+INITDAT);
  348. for(j=0; j<c; j++)
  349. Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);
  350. Bprint(&bso, "\t%P\n", curp);
  351. }
  352. for(; i<c; i++) {
  353. buf.dbuf[l] = cast[inuxi1[i]];
  354. l++;
  355. }
  356. break;
  357. case 2:
  358. if(debug['a'] && i == 0) {
  359. Bprint(&bso, pcstr, l+s+INITDAT);
  360. for(j=0; j<c; j++)
  361. Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);
  362. Bprint(&bso, "\t%P\n", curp);
  363. }
  364. for(; i<c; i++) {
  365. buf.dbuf[l] = cast[inuxi2[i]];
  366. l++;
  367. }
  368. break;
  369. case 4:
  370. if(debug['a'] && i == 0) {
  371. Bprint(&bso, pcstr, l+s+INITDAT);
  372. for(j=0; j<c; j++)
  373. Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);
  374. Bprint(&bso, "\t%P\n", curp);
  375. }
  376. for(; i<c; i++) {
  377. buf.dbuf[l] = cast[inuxi4[i]];
  378. l++;
  379. }
  380. break;
  381. }
  382. break;
  383. }
  384. }
  385. write(cout, buf.dbuf, n);
  386. }
  387. long
  388. rnd(long v, long r)
  389. {
  390. long c;
  391. if(r <= 0)
  392. return v;
  393. v += r - 1;
  394. c = v % r;
  395. if(c < 0)
  396. c += r;
  397. v -= c;
  398. return v;
  399. }