comm4.c 9.8 KB

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