comm4.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /* $Header$ */
  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. 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 != NULL) {
  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 'd':
  63. #ifdef LISTING
  64. dflag = 0;
  65. while (*p >= '0' && *p <= '7')
  66. dflag = (dflag << 3) + *p++ - '0';
  67. if ((dflag & 0777) == 0)
  68. dflag |= 0700;
  69. dflag &= ~4;
  70. #endif
  71. break;
  72. case 's':
  73. sflag = 0;
  74. while (*p >= '0' && *p <= '7')
  75. sflag = (sflag << 3) + *p++ - '0';
  76. break;
  77. case 'r':
  78. #ifdef RELOCATION
  79. #ifdef ASLD
  80. rflag = 1;
  81. #endif ASLD
  82. #endif RELOCATION
  83. break;
  84. case 'b':
  85. #ifdef THREE_PASS
  86. bflag = 1;
  87. #endif
  88. break;
  89. #ifndef ASLD
  90. case 'u':
  91. case '\0':
  92. uflag = 1;
  93. break;
  94. #endif
  95. default:
  96. continue;
  97. }
  98. argv[i] = 0;
  99. }
  100. #ifdef RELOCATION
  101. if (rflag)
  102. sflag |= SYM_SCT;
  103. #endif RELOCATION
  104. pass_1(argc, argv);
  105. #ifdef THREE_PASS
  106. pass_23(PASS_2);
  107. #endif
  108. pass_23(PASS_3);
  109. oflush();
  110. wr_close();
  111. stop();
  112. }
  113. /* ---------- pass 1: arguments, modules, archives ---------- */
  114. pass_1(argc, argv)
  115. char **argv;
  116. {
  117. register char *p;
  118. register item_t *ip;
  119. #ifdef ASLD
  120. char armagic[2];
  121. #else
  122. register nfile = 0;
  123. #endif
  124. tempfile = fftemp(temppath, "asTXXXXXX");
  125. #ifdef LISTING
  126. listmode = dflag;
  127. if (listmode & 0440)
  128. listfile = fftemp(listpath, "asLXXXXXX");
  129. #endif
  130. for (ip = keytab; ip->i_type; ip++)
  131. item_insert(ip, H_KEY+hash(ip->i_name));
  132. machstart(PASS_1);
  133. while (--argc >= 0) {
  134. p = *argv++;
  135. if (p == 0)
  136. continue;
  137. #ifndef ASLD
  138. if (nfile != 0)
  139. fatal("second source file %s", p);
  140. nfile++;
  141. #endif
  142. if (p[0] == '-' && p[1] == '\0') {
  143. input = stdin;
  144. parse("STDIN");
  145. continue;
  146. }
  147. if ((input = fopen(p, "r")) == NULL)
  148. fatal("can't open %s", p);
  149. #ifdef ASLD
  150. if (
  151. fread(armagic, 2, 1, input) == 1
  152. &&
  153. ((armagic[0]&0377) |
  154. ((unsigned)(armagic[1]&0377)<<8)) == ARMAG
  155. ) {
  156. archive();
  157. fclose(input);
  158. continue;
  159. }
  160. rewind(input);
  161. #endif
  162. parse(p);
  163. fclose(input);
  164. }
  165. commfinish();
  166. machfinish(PASS_1);
  167. #ifdef ASLD
  168. if (unresolved) {
  169. register int i;
  170. nerrors++;
  171. fflush(stdout);
  172. fprintf(stderr, "unresolved references:\n");
  173. for (i = 0; i < H_SIZE; i++) {
  174. ip = hashtab[H_GLOBAL+i];
  175. while (ip != 0) {
  176. if ((ip->i_type & (S_EXT|S_TYP)) == (S_EXT|S_UND))
  177. fprintf(stderr, "\t%s\n", ip->i_name);
  178. ip = ip->i_next;
  179. }
  180. }
  181. }
  182. #else
  183. if (unresolved)
  184. outhead.oh_flags |= HF_LINK;
  185. if (nfile == 0)
  186. fatal("no source file");
  187. #endif
  188. }
  189. #ifdef ASLD
  190. archive() {
  191. register long offset;
  192. struct ar_hdr header;
  193. char getsize[AR_TOTAL];
  194. archmode++;
  195. offset = 2;
  196. for (;;) {
  197. if (unresolved == 0)
  198. break;
  199. fseek(input,offset,0);
  200. if (fread(getsize,AR_TOTAL,1,input) != 1)
  201. break;
  202. offset += AR_TOTAL;
  203. strncpy(header.ar_name,getsize,sizeof header.ar_name) ;
  204. header.ar_size= (((((long) (getsize[AR_SIZE+1]&0377))<<8)+
  205. ((long) (getsize[AR_SIZE ]&0377))<<8)+
  206. ((long) (getsize[AR_SIZE+3]&0377))<<8)+
  207. ((long) (getsize[AR_SIZE+2]&0377)) ;
  208. archsize = header.ar_size;
  209. if (needed()) {
  210. fseek(input,offset,0);
  211. archsize = header.ar_size;
  212. header.ar_name[14] = '\0';
  213. parse(remember(header.ar_name));
  214. }
  215. offset += header.ar_size;
  216. while (offset % 2)
  217. offset++;
  218. }
  219. archmode = 0;
  220. }
  221. needed()
  222. {
  223. register c, first;
  224. register item_t *ip;
  225. register need;
  226. #ifdef LISTING
  227. register save;
  228. save = listflag; listflag = 0;
  229. #endif
  230. need = 0;
  231. peekc = -1;
  232. first = 1;
  233. for (;;) {
  234. c = nextchar();
  235. if (c == '\n') {
  236. first = 1;
  237. continue;
  238. }
  239. if (c == ' ' || c == '\t' || c == ',')
  240. continue;
  241. if (ISALPHA(c) == 0)
  242. break;
  243. if ((ip = item_search(readident(c))) == 0) {
  244. if (first)
  245. break;
  246. continue;
  247. }
  248. if (first) {
  249. if (ip == &keytab[KEYSECT]) {
  250. while ((c = nextchar()) != '\n')
  251. ;
  252. continue;
  253. }
  254. if (ip != &keytab[KEYDEFINE])
  255. break;
  256. first = 0;
  257. }
  258. if ((ip->i_type & S_TYP) == S_UND) {
  259. need++;
  260. break;
  261. }
  262. }
  263. #ifdef LISTING
  264. listflag = save;
  265. #endif
  266. return(need);
  267. }
  268. #endif ASLD
  269. parse(s)
  270. char *s;
  271. {
  272. register i;
  273. register item_t *ip;
  274. register char *p;
  275. for (p = s; *p; )
  276. if (*p++ == '/')
  277. s = p;
  278. #ifdef ASLD
  279. yylval.y_strp = s;
  280. putval(MODULE);
  281. #endif
  282. for (i = 0; i < FB_SIZE; i++)
  283. fb_ptr[FB_BACK+i] = 0;
  284. newmodule(s);
  285. peekc = -1;
  286. yyparse();
  287. /*
  288. * Check for undefined symbols
  289. */
  290. #ifdef ASLD
  291. for (i = 0; i < H_SIZE; i++) {
  292. while (ip = hashtab[H_LOCAL+i]) {
  293. /*
  294. * cleanup local queue
  295. */
  296. hashtab[H_LOCAL+i] = ip->i_next;
  297. /*
  298. * make undefined references extern
  299. */
  300. if ((ip->i_type & (S_VAR|S_TYP)) == S_UND)
  301. ip->i_type |= S_EXT;
  302. /*
  303. * relink externals in global queue
  304. */
  305. if (ip->i_type & S_EXT)
  306. item_insert(ip, H_GLOBAL+i);
  307. }
  308. }
  309. #else
  310. for (i = 0; i < H_SIZE; i++) {
  311. for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
  312. if (ip->i_type & S_EXT)
  313. continue;
  314. if (ip->i_type != S_UND)
  315. continue;
  316. if (uflag == 0)
  317. serror("undefined symbol %s", ip->i_name);
  318. ip->i_type |= S_EXT;
  319. }
  320. }
  321. #endif
  322. /*
  323. * Check for undefined numeric labels
  324. */
  325. for (i = 0; i < FB_SIZE; i++) {
  326. if ((ip = fb_ptr[FB_FORW+i]) == 0)
  327. continue;
  328. serror("undefined label %d", i);
  329. fb_ptr[FB_FORW+i] = 0;
  330. }
  331. }
  332. pass_23(n)
  333. {
  334. register i;
  335. #ifdef ASLD
  336. register addr_t base = 0;
  337. #endif
  338. register sect_t *sp;
  339. if (nerrors)
  340. stop();
  341. pass = n;
  342. #ifdef LISTING
  343. listmode >>= 3;
  344. if (listmode & 4)
  345. ffreopen(listpath, listfile);
  346. listeoln = 1;
  347. #endif
  348. #ifdef THREE_PASS
  349. nbits = 0;
  350. #endif
  351. for (i = 0; i < FB_SIZE; i++)
  352. fb_ptr[FB_FORW+i] = fb_ptr[FB_HEAD+i];
  353. outhead.oh_nemit = 0;
  354. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  355. #ifdef ASLD
  356. if (sp->s_flag & BASED) {
  357. base = sp->s_base;
  358. if (base % sp->s_lign)
  359. fatal("base not aligned");
  360. } else {
  361. base += (sp->s_lign - 1);
  362. base -= (base % sp->s_lign);
  363. sp->s_base = base;
  364. }
  365. base += sp->s_size;
  366. base += sp->s_comm;
  367. #endif
  368. outhead.oh_nemit += sp->s_size - sp->s_zero;
  369. }
  370. if (pass == PASS_3)
  371. setupoutput();
  372. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  373. sp->s_size = 0;
  374. sp->s_zero = 0;
  375. #ifdef THREE_PASS
  376. sp->s_gain = 0;
  377. #endif
  378. }
  379. machstart(n);
  380. #ifndef ASLD
  381. newmodule(modulename);
  382. #endif ASLD
  383. ffreopen(temppath, tempfile);
  384. yyparse();
  385. commfinish();
  386. machfinish(n);
  387. }
  388. newmodule(s)
  389. char *s;
  390. {
  391. switchsect(S_UND);
  392. modulename = s;
  393. lineno = 1;
  394. if ((sflag & (SYM_EXT|SYM_LOC|SYM_LAB)) && PASS_SYMB)
  395. newsymb(s, S_MOD, (short)0, (valu_t)0);
  396. #ifdef LISTING
  397. listtemp = 0;
  398. if (dflag & 01000)
  399. listtemp = listmode;
  400. listflag = listtemp;
  401. #endif
  402. }
  403. setupoutput()
  404. {
  405. register sect_t *sp;
  406. register long off;
  407. struct outsect outsect;
  408. register struct outsect *pos = &outsect;
  409. if (! wr_open(aoutpath)) {
  410. fatal("can't create %s", aoutpath);
  411. }
  412. wr_ohead(&outhead);
  413. /*
  414. * section table generation
  415. */
  416. off = SZ_HEAD;
  417. off += (long)outhead.oh_nsect * SZ_SECT;
  418. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  419. sp->s_foff = off;
  420. pos->os_base = SETBASE(sp);
  421. pos->os_size = sp->s_size + sp->s_comm;
  422. pos->os_foff = sp->s_foff;
  423. pos->os_flen = sp->s_size - sp->s_zero;
  424. pos->os_lign = sp->s_lign;
  425. off += pos->os_flen;
  426. wr_sect(pos, 1);
  427. }
  428. #ifdef RELOCATION
  429. off += (long)outhead.oh_nrelo * SZ_RELO;
  430. #endif
  431. if (sflag == 0)
  432. return;
  433. off += (long)outhead.oh_nname * SZ_NAME;
  434. outhead.oh_nchar = off; /* see newsymb() */
  435. }
  436. commfinish()
  437. {
  438. #ifndef ASLD
  439. register int i;
  440. #endif
  441. register struct common_t *cp;
  442. register item_t *ip;
  443. register sect_t *sp;
  444. register valu_t addr;
  445. switchsect(S_UND);
  446. /*
  447. * assign .comm labels and produce .comm symbol table entries
  448. */
  449. for (cp = commons; cp; cp = cp->c_next) {
  450. ip = cp->c_it;
  451. #ifndef ASLD
  452. if (!( ip->i_type & S_EXT)) {
  453. #endif
  454. sp = &sect[(ip->i_type & S_TYP) - S_MIN];
  455. if (pass == PASS_1) {
  456. addr = sp->s_size + sp->s_comm;
  457. sp->s_comm += ip->i_valu;
  458. ip->i_valu = addr;
  459. #ifndef ASLD
  460. ip->i_type &= ~S_COM;
  461. #endif
  462. }
  463. #ifdef ASLD
  464. #ifdef THREE_PASS
  465. if (pass == PASS_2) {
  466. ip->i_valu -= sp->s_gain;
  467. }
  468. #endif
  469. if ((sflag & SYM_EXT) && PASS_SYMB)
  470. newsymb(
  471. ip->i_name,
  472. ip->i_type & (S_EXT|S_TYP),
  473. (short)0,
  474. load(ip)
  475. );
  476. #else not ASLD
  477. #ifdef THREE_PASS
  478. if (pass == PASS_2) {
  479. cp->c_size -= sp->s_gain;
  480. }
  481. #endif THREE_PASS
  482. }
  483. if (pass == PASS_1) cp->c_size = ip->i_valu;
  484. if (PASS_SYMB) {
  485. if (pass != PASS_3 && (ip->i_type & S_EXT)) {
  486. ip->i_valu = outhead.oh_nname;
  487. }
  488. newsymb(
  489. ip->i_name,
  490. ip->i_type,
  491. (short) 0,
  492. cp->c_size
  493. );
  494. }
  495. #endif not ASLD
  496. }
  497. if (PASS_SYMB == 0)
  498. return;
  499. #ifndef ASLD
  500. /*
  501. * produce symbol table entries for undefined's
  502. */
  503. for (i = 0; i<H_SIZE; i++)
  504. for (ip = hashtab[H_LOCAL+i]; ip; ip = ip->i_next) {
  505. if (ip->i_type != (S_EXT|S_UND))
  506. continue;
  507. if (pass != PASS_3)
  508. /*
  509. * save symbol table index
  510. * for possible relocation
  511. */
  512. ip->i_valu = outhead.oh_nname;
  513. newsymb(
  514. ip->i_name,
  515. S_EXT|S_UND,
  516. (short)0,
  517. (valu_t)0
  518. );
  519. }
  520. #endif not ASLD
  521. /*
  522. * produce symbol table entries for sections
  523. */
  524. if (sflag & SYM_SCT)
  525. for (sp = sect; sp < &sect[outhead.oh_nsect]; sp++) {
  526. ip = sp->s_item;
  527. newsymb(
  528. ip->i_name,
  529. (short)(ip->i_type | S_SCT),
  530. (short)0,
  531. load(ip)
  532. );
  533. }
  534. }