comm4.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* @(#)comm4.c 1.6 */
  7. /*
  8. * Micro processor assembler framework written by
  9. * Johan Stevenson, Vrije Universiteit, Amsterdam
  10. * modified by
  11. * Johan Stevenson, Han Schaminee and Hans de Vries
  12. * Philips S&I, T&M, PMDS, Eindhoven
  13. */
  14. #include "comm0.h"
  15. #include "comm1.h"
  16. #include "y.tab.h"
  17. extern YYSTYPE yylval;
  18. /* ========== Machine independent C routines ========== */
  19. void stop() {
  20. #if DEBUG < 2
  21. unlink(temppath);
  22. #ifdef LISTING
  23. unlink(listpath);
  24. #endif
  25. #endif
  26. exit(nerrors != 0);
  27. }
  28. main(argc, argv)
  29. char **argv;
  30. {
  31. register char *p;
  32. register i;
  33. static char sigs[] = {
  34. SIGHUP, SIGINT, SIGQUIT, SIGTERM, 0
  35. };
  36. /* the next test should be performed by the
  37. * preprocessor, but it cannot, so it is performed by the compiler.
  38. */
  39. switch(0) {
  40. case 1: break;
  41. case (S_ETC|S_COM|S_VAR|S_DOT) != S_ETC : break;
  42. }
  43. progname = *argv++; argc--;
  44. for (p = sigs; i = *p++; )
  45. if (signal(i, SIG_IGN) != SIG_IGN)
  46. signal(i, stop);
  47. for (i = 0; i < argc; i++) {
  48. p = argv[i];
  49. if (*p++ != '-')
  50. continue;
  51. switch (*p++) {
  52. case 'o':
  53. if (*p != '\0') {
  54. aoutpath = p;
  55. break;
  56. }
  57. argv[i] = 0;
  58. if (++i >= argc)
  59. fatal("-o needs filename");
  60. aoutpath = argv[i];
  61. break;
  62. case 'T':
  63. if (*p != '\0') {
  64. extern char *tmp_dir;
  65. tmp_dir = p;
  66. }
  67. break;
  68. case 'd':
  69. #ifdef LISTING
  70. dflag = 0;
  71. while (*p >= '0' && *p <= '7')
  72. dflag = (dflag << 3) + *p++ - '0';
  73. if ((dflag & 0777) == 0)
  74. dflag |= 0700;
  75. dflag &= ~4;
  76. #endif
  77. break;
  78. case 's':
  79. sflag = 0;
  80. while (*p >= '0' && *p <= '7')
  81. sflag = (sflag << 3) + *p++ - '0';
  82. break;
  83. case 'r':
  84. #ifdef RELOCATION
  85. #ifdef ASLD
  86. rflag = 1;
  87. #endif /* ASLD */
  88. #endif /* RELOCATION */
  89. break;
  90. case 'b':
  91. #ifdef THREE_PASS
  92. bflag = 1;
  93. #endif
  94. break;
  95. #ifndef ASLD
  96. case 'u':
  97. case '\0':
  98. uflag = 1;
  99. break;
  100. #endif
  101. default:
  102. continue;
  103. }
  104. argv[i] = 0;
  105. }
  106. #ifdef RELOCATION
  107. if (rflag)
  108. sflag |= SYM_SCT;
  109. #endif /* RELOCATION */
  110. pass_1(argc, argv);
  111. #ifdef THREE_PASS
  112. pass_23(PASS_2);
  113. #endif
  114. pass_23(PASS_3);
  115. wr_close();
  116. stop();
  117. }
  118. /* ---------- pass 1: arguments, modules, archives ---------- */
  119. pass_1(argc, argv)
  120. char **argv;
  121. {
  122. register char *p;
  123. register item_t *ip;
  124. #ifdef ASLD
  125. char armagic[2];
  126. #else
  127. register nfile = 0;
  128. #endif
  129. #ifdef THREE_PASS
  130. bitindex = -1;
  131. nbits = BITCHUNK;
  132. #endif
  133. tempfile = fftemp(temppath, "asTXXXXXX");
  134. #ifdef LISTING
  135. listmode = dflag;
  136. if (listmode & 0440)
  137. listfile = fftemp(listpath, "asLXXXXXX");
  138. #endif
  139. for (ip = keytab; ip->i_type; ip++)
  140. item_insert(ip, H_KEY+hash(ip->i_name));
  141. machstart(PASS_1);
  142. while (--argc >= 0) {
  143. p = *argv++;
  144. if (p == 0)
  145. continue;
  146. #ifndef ASLD
  147. if (nfile != 0)
  148. fatal("second source file %s", p);
  149. nfile++;
  150. #else
  151. if (p[0] == '-' && p[1] == '\0') {
  152. input = stdin;
  153. parse("STDIN");
  154. continue;
  155. }
  156. #endif
  157. if ((input = fopen(p, "r")) == NULL)
  158. fatal("can't open %s", p);
  159. #ifdef ASLD
  160. if (
  161. fread(armagic, 2, 1, input) == 1
  162. &&
  163. ((armagic[0]&0377) |
  164. ((unsigned)(armagic[1]&0377)<<8)) == ARMAG
  165. ) {
  166. archive();
  167. fclose(input);
  168. continue;
  169. }
  170. rewind(input);
  171. #endif
  172. parse(p);
  173. fclose(input);
  174. }
  175. #ifndef ASLD
  176. if (nfile == 0) {
  177. input = stdin;
  178. parse("STDIN");
  179. }
  180. #endif
  181. commfinish();
  182. machfinish(PASS_1);
  183. #ifdef ASLD
  184. if (unresolved) {
  185. register int i;
  186. nerrors++;
  187. fflush(stdout);
  188. fprintf(stderr, "unresolved references:\n");
  189. for (i = 0; i < H_SIZE; i++) {
  190. ip = hashtab[H_GLOBAL+i];
  191. while (ip != 0) {
  192. if ((ip->i_type & (S_EXT|S_TYP)) == (S_EXT|S_UND))
  193. fprintf(stderr, "\t%s\n", ip->i_name);
  194. ip = ip->i_next;
  195. }
  196. }
  197. }
  198. #else
  199. if (unresolved)
  200. outhead.oh_flags |= HF_LINK;
  201. /*
  202. if (nfile == 0)
  203. fatal("no source file");
  204. */
  205. #endif
  206. }
  207. #ifdef ASLD
  208. archive() {
  209. register long offset;
  210. struct ar_hdr header;
  211. char getsize[AR_TOTAL];
  212. archmode++;
  213. offset = 2;
  214. for (;;) {
  215. if (unresolved == 0)
  216. break;
  217. fseek(input,offset,0);
  218. if (fread(getsize,AR_TOTAL,1,input) != 1)
  219. break;
  220. offset += AR_TOTAL;
  221. strncpy(header.ar_name,getsize,sizeof header.ar_name) ;
  222. header.ar_size= (((((long) (getsize[AR_SIZE+1]&0377))<<8)+
  223. ((long) (getsize[AR_SIZE ]&0377))<<8)+
  224. ((long) (getsize[AR_SIZE+3]&0377))<<8)+
  225. ((long) (getsize[AR_SIZE+2]&0377)) ;
  226. archsize = header.ar_size;
  227. if (needed()) {
  228. fseek(input,offset,0);
  229. archsize = header.ar_size;
  230. header.ar_name[14] = '\0';
  231. parse(remember(header.ar_name));
  232. }
  233. offset += header.ar_size;
  234. while (offset % 2)
  235. offset++;
  236. }
  237. archmode = 0;
  238. }
  239. needed()
  240. {
  241. register c, first;
  242. register item_t *ip;
  243. register need;
  244. #ifdef LISTING
  245. register save;
  246. save = listflag; listflag = 0;
  247. #endif
  248. need = 0;
  249. peekc = -1;
  250. first = 1;
  251. for (;;) {
  252. c = nextchar();
  253. if (c == '\n') {
  254. first = 1;
  255. continue;
  256. }
  257. if (c == ' ' || c == '\t' || c == ',')
  258. continue;
  259. if (ISALPHA(c) == 0)
  260. break;
  261. if ((ip = item_search(readident(c))) == 0) {
  262. if (first)
  263. break;
  264. continue;
  265. }
  266. if (first) {
  267. if (ip == &keytab[KEYSECT]) {
  268. while ((c = nextchar()) != '\n')
  269. ;
  270. continue;
  271. }
  272. if (ip != &keytab[KEYDEFINE])
  273. break;
  274. first = 0;
  275. }
  276. if ((ip->i_type & S_TYP) == S_UND) {
  277. need++;
  278. break;
  279. }
  280. }
  281. #ifdef LISTING
  282. listflag = save;
  283. #endif
  284. return(need);
  285. }
  286. #endif /* ASLD */
  287. parse(s)
  288. char *s;
  289. {
  290. register i;
  291. register item_t *ip;
  292. register char *p;
  293. for (p = s; *p; )
  294. if (*p++ == '/')
  295. s = p;
  296. #ifdef ASLD
  297. yylval.y_strp = s;
  298. putval(MODULE);
  299. #endif
  300. for (i = 0; i < FB_SIZE; i++)
  301. fb_ptr[FB_BACK+i] = 0;
  302. newmodule(s);
  303. peekc = -1;
  304. yyparse();
  305. /*
  306. * Check for undefined symbols
  307. */
  308. #ifdef ASLD
  309. for (i = 0; i < H_SIZE; i++) {
  310. while (ip = hashtab[H_LOCAL+i]) {
  311. /*
  312. * cleanup local queue
  313. */
  314. hashtab[H_LOCAL+i] = ip->i_next;
  315. /*
  316. * make undefined references extern
  317. */
  318. if ((ip->i_type & (S_VAR|S_TYP)) == S_UND)
  319. ip->i_type |= S_EXT;
  320. /*
  321. * relink externals in global queue
  322. */
  323. if (ip->i_type & S_EXT)
  324. item_insert(ip, H_GLOBAL+i);
  325. }
  326. }
  327. #else
  328. for (i = 0; i < H_SIZE; i++) {
  329. for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
  330. if (ip->i_type & S_EXT)
  331. continue;
  332. if (ip->i_type != S_UND)
  333. continue;
  334. if (uflag == 0)
  335. serror("undefined symbol %s", ip->i_name);
  336. ip->i_type |= S_EXT;
  337. }
  338. }
  339. #endif
  340. /*
  341. * Check for undefined numeric labels
  342. */
  343. for (i = 0; i < FB_SIZE; i++) {
  344. if ((ip = fb_ptr[FB_FORW+i]) == 0)
  345. continue;
  346. serror("undefined label %d", i);
  347. fb_ptr[FB_FORW+i] = 0;
  348. }
  349. }
  350. pass_23(n)
  351. {
  352. register i;
  353. #ifdef ASLD
  354. register ADDR_T base = 0;
  355. #endif
  356. register sect_t *sp;
  357. if (nerrors)
  358. stop();
  359. pass = n;
  360. #ifdef LISTING
  361. listmode >>= 3;
  362. if (listmode & 4)
  363. ffreopen(listpath, listfile);
  364. listeoln = 1;
  365. #endif
  366. #ifdef THREE_PASS
  367. bitindex = -1;
  368. nbits = BITCHUNK;
  369. #endif
  370. for (i = 0; i < FB_SIZE; i++)
  371. fb_ptr[FB_FORW+i] = fb_ptr[FB_HEAD+i];
  372. outhead.oh_nemit = 0;
  373. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  374. #ifdef ASLD
  375. if (sp->s_flag & BASED) {
  376. base = sp->s_base;
  377. if (base % sp->s_lign)
  378. fatal("base not aligned");
  379. } else {
  380. base += (sp->s_lign - 1);
  381. base -= (base % sp->s_lign);
  382. sp->s_base = base;
  383. }
  384. base += sp->s_size;
  385. base += sp->s_comm;
  386. #endif
  387. outhead.oh_nemit += sp->s_size - sp->s_zero;
  388. }
  389. if (pass == PASS_3)
  390. setupoutput();
  391. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  392. sp->s_size = 0;
  393. sp->s_zero = 0;
  394. #ifdef THREE_PASS
  395. sp->s_gain = 0;
  396. #endif
  397. }
  398. machstart(n);
  399. #ifndef ASLD
  400. newmodule(modulename);
  401. #endif /* ASLD */
  402. ffreopen(temppath, tempfile);
  403. yyparse();
  404. commfinish();
  405. machfinish(n);
  406. }
  407. newmodule(s)
  408. char *s;
  409. {
  410. static char nmbuf[STRINGMAX];
  411. switchsect(S_UND);
  412. if (s && s != modulename) {
  413. strncpy(nmbuf, s, STRINGMAX-1);
  414. modulename = nmbuf;
  415. }
  416. else modulename = s;
  417. lineno = 1;
  418. #ifdef NEEDED
  419. /*
  420. * problem: it shows the name of the tempfile, not any name
  421. * the user is familiar with. Moreover, it is not reproducable.
  422. */
  423. if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB)
  424. newsymb(s, S_MOD, 0, (valu_t)0);
  425. #endif
  426. #ifdef LISTING
  427. listtemp = 0;
  428. if (dflag & 01000)
  429. listtemp = listmode;
  430. listflag = listtemp;
  431. #endif
  432. }
  433. setupoutput()
  434. {
  435. register sect_t *sp;
  436. register long off;
  437. struct outsect outsect;
  438. register struct outsect *pos = &outsect;
  439. if (! wr_open(aoutpath)) {
  440. fatal("can't create %s", aoutpath);
  441. }
  442. wr_ohead(&outhead);
  443. /*
  444. * section table generation
  445. */
  446. off = SZ_HEAD;
  447. off += (long)outhead.oh_nsect * SZ_SECT;
  448. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  449. sp->s_foff = off;
  450. pos->os_base = SETBASE(sp);
  451. pos->os_size = sp->s_size + sp->s_comm;
  452. pos->os_foff = sp->s_foff;
  453. pos->os_flen = sp->s_size - sp->s_zero;
  454. pos->os_lign = sp->s_lign;
  455. off += pos->os_flen;
  456. wr_sect(pos, 1);
  457. }
  458. #ifdef RELOCATION
  459. off += (long)outhead.oh_nrelo * SZ_RELO;
  460. #endif
  461. if (sflag == 0)
  462. return;
  463. off += (long)outhead.oh_nname * SZ_NAME;
  464. outhead.oh_nchar = off; /* see newsymb() */
  465. }
  466. commfinish()
  467. {
  468. #ifndef ASLD
  469. register int i;
  470. #endif
  471. register struct common_t *cp;
  472. register item_t *ip;
  473. register sect_t *sp;
  474. register valu_t addr;
  475. switchsect(S_UND);
  476. /*
  477. * assign .comm labels and produce .comm symbol table entries
  478. */
  479. for (cp = commons; cp; cp = cp->c_next) {
  480. ip = cp->c_it;
  481. #ifndef ASLD
  482. if (!( ip->i_type & S_EXT)) {
  483. #endif
  484. sp = &sect[(ip->i_type & S_TYP) - S_MIN];
  485. if (pass == PASS_1) {
  486. addr = sp->s_size + sp->s_comm;
  487. sp->s_comm += ip->i_valu;
  488. ip->i_valu = addr;
  489. #ifndef ASLD
  490. ip->i_type &= ~S_COM;
  491. #endif
  492. }
  493. #ifdef ASLD
  494. #ifdef THREE_PASS
  495. if (pass == PASS_2) {
  496. ip->i_valu -= sp->s_gain;
  497. }
  498. #endif
  499. if ((sflag & SYM_EXT) && PASS_SYMB)
  500. newsymb(
  501. ip->i_name,
  502. ip->i_type & (S_EXT|S_TYP),
  503. 0,
  504. load(ip)
  505. );
  506. #else /* not ASLD */
  507. #ifdef THREE_PASS
  508. if (pass == PASS_2) {
  509. cp->c_size -= sp->s_gain;
  510. }
  511. #endif /* THREE_PASS */
  512. }
  513. if (pass == PASS_1) cp->c_size = ip->i_valu;
  514. if (PASS_SYMB) {
  515. if (pass != PASS_3 && (ip->i_type & S_EXT)) {
  516. ip->i_valu = outhead.oh_nname;
  517. }
  518. newsymb(
  519. ip->i_name,
  520. ip->i_type,
  521. 0,
  522. cp->c_size
  523. );
  524. }
  525. #endif /* not ASLD */
  526. }
  527. if (PASS_SYMB == 0)
  528. return;
  529. #ifndef ASLD
  530. /*
  531. * produce symbol table entries for undefined's
  532. */
  533. for (i = 0; i<H_SIZE; i++)
  534. for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
  535. if (ip->i_type != (S_EXT|S_UND))
  536. continue;
  537. if (pass != PASS_3)
  538. /*
  539. * save symbol table index
  540. * for possible relocation
  541. */
  542. ip->i_valu = outhead.oh_nname;
  543. newsymb(
  544. ip->i_name,
  545. S_EXT|S_UND,
  546. 0,
  547. (valu_t)0
  548. );
  549. }
  550. #endif /* not ASLD */
  551. /*
  552. * produce symbol table entries for sections
  553. */
  554. if (sflag & SYM_SCT)
  555. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  556. ip = sp->s_item;
  557. newsymb(
  558. ip->i_name,
  559. (ip->i_type | S_SCT),
  560. 0,
  561. load(ip)
  562. );
  563. }
  564. }