main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. #ifndef lint
  6. static char rcsid[] = "$Id$";
  7. #endif
  8. /*
  9. * led - linkage editor for ACK assemblers output format
  10. */
  11. #include <stdio.h>
  12. #include <out.h>
  13. #include "const.h"
  14. #include "debug.h"
  15. #include "defs.h"
  16. #include "memory.h"
  17. #include "orig.h"
  18. extern bool incore;
  19. #ifndef NOSTATISTICS
  20. int statistics;
  21. #endif
  22. #ifndef NDEBUG
  23. int DEB = 0;
  24. #endif
  25. int Verbose = 0;
  26. static initializations();
  27. static first_pass();
  28. static long number();
  29. static setlign();
  30. static setbase();
  31. static struct outname *makename();
  32. static pass1();
  33. static evaluate();
  34. static norm_commons();
  35. static complete_sections();
  36. static change_names();
  37. static bool tstbit();
  38. static second_pass();
  39. static pass2();
  40. #ifndef NOSTATISTICS
  41. static do_statistics();
  42. #endif
  43. main(argc, argv)
  44. int argc;
  45. char **argv;
  46. {
  47. initializations(argc, argv);
  48. first_pass(argv);
  49. #ifndef NOSTATISTICS
  50. if (statistics) do_statistics();
  51. #endif
  52. freeze_core();
  53. evaluate();
  54. beginoutput();
  55. second_pass(argv);
  56. endoutput();
  57. stop();
  58. }
  59. #ifndef NOSTATISTICS
  60. static
  61. do_statistics()
  62. {
  63. register struct memory *m = mems;
  64. while (m <= &mems[NMEMS-1]) {
  65. fprintf(stderr, "mem %d: full %lx, free %lx\n",
  66. (int)(m - mems),
  67. (long) m->mem_full,
  68. (long) m->mem_left);
  69. m++;
  70. }
  71. }
  72. #endif
  73. char *progname; /* Name this program was invoked with. */
  74. int passnumber; /* Pass we are in. */
  75. struct outhead outhead; /* Header of final output file. */
  76. struct outsect outsect[MAXSECT];/* Its section table. */
  77. /* ARGSUSED */
  78. static
  79. initializations(argc, argv)
  80. int argc;
  81. char *argv[];
  82. {
  83. /*
  84. * Avoid malloc()s.
  85. */
  86. setbuf(stdin, (char *)NULL);
  87. setbuf(stdout, (char *)NULL);
  88. setbuf(stderr, (char *)NULL);
  89. progname = argv[0];
  90. passnumber = FIRST;
  91. init_core();
  92. init_symboltable();
  93. outhead.oh_magic = O_MAGIC;
  94. outhead.oh_stamp = O_STAMP;
  95. }
  96. /* ------------------------ ROUTINES OF FIRST PASS ------------------------- */
  97. int flagword = 0; /* To store command-line options. */
  98. char *outputname = "a.out"; /* Name of the resulting object file. */
  99. int exitstatus = 0;
  100. /*
  101. * Scan the arguments.
  102. * If the argument starts with a '-', it's a flag, else it is either
  103. * a plain file to be loaded, or an archive.
  104. */
  105. static
  106. first_pass(argv)
  107. register char **argv;
  108. {
  109. register char *argp;
  110. int sectno;
  111. int h;
  112. extern int atoi();
  113. extern char *strindex();
  114. extern int hash();
  115. extern struct outname *searchname();
  116. while (*++argv) {
  117. argp = *argv;
  118. if (*argp != '-') {
  119. pass1(argp);
  120. continue;
  121. }
  122. /* It's a flag. */
  123. switch (*++argp) {
  124. case 'a':
  125. /*
  126. * The rest of the argument must be of the form
  127. * `<section number>:<alignment>', where
  128. * <section number> and <alignment> are numbers.
  129. * <alignment> will be the alignment in the machine of
  130. * section <section number>.
  131. */
  132. sectno = atoi(++argp);
  133. if ((argp = strindex(argp, ':')) == (char *)0)
  134. fatal("usage: -a<section number>:<alignment>");
  135. setlign(sectno, number(++argp));
  136. break;
  137. case 'b':
  138. /*
  139. * The rest of the argument must be of the form
  140. * `<section number>:<base>', where <section number>
  141. * and base are decimal numbers. <base> will be
  142. * the base address in the machine of section
  143. * <section number>.
  144. */
  145. sectno = atoi(++argp);
  146. if ((argp = strindex(argp, ':')) == (char *)0)
  147. fatal("usage: -b<section number>:<base>");
  148. setbase(sectno, number(++argp));
  149. break;
  150. case 'c':
  151. /*
  152. * Leave relocation information in the output, so that
  153. * a next pass can see where relocation was done. The
  154. * resulting output however is no longer relocatable.
  155. */
  156. flagword &= ~RFLAG;
  157. flagword |= CFLAG;
  158. break;
  159. #ifndef NDEBUG
  160. case 'd':
  161. DEB = 1;
  162. break;
  163. #endif
  164. case 'o':
  165. /*
  166. * The `name' argument after -o is used as name
  167. * of the led output file, instead of "a.out".
  168. */
  169. if ((outputname = *++argv) == (char *)0)
  170. fatal("-o needs filename");
  171. break;
  172. case 'r':
  173. /*
  174. * Generate relocation information in the output file
  175. * so that it can be the subject of another led run.
  176. * This flag also prevents final definitions from being
  177. * given to common symbols, and suppresses the
  178. * `Undefined:' diagnostic.
  179. */
  180. if (flagword & CFLAG) break;
  181. if (flagword & SFLAG)
  182. warning("-r contradicts -s: -s ignored");
  183. flagword |= RFLAG;
  184. break;
  185. case 's':
  186. /*
  187. * `Strip' the output, that is, remove the symbol table
  188. * and relocation table to save space (but impair the
  189. * usefullness of the debuggers). This information can
  190. * also be removed by astrip(1).
  191. */
  192. if (flagword & RFLAG)
  193. warning("-s contradicts -r: -s ignored");
  194. else
  195. flagword |= SFLAG;
  196. break;
  197. case 'u':
  198. /*
  199. * Take the following argument as a symbol and enter it
  200. * as undefined in the symbol table. This is useful for
  201. * loading wholly from a library, since initially the
  202. * symbol table is empty and an unresolved reference is
  203. * needed to force the loading of the first routine.
  204. */
  205. if (*++argv == (char *)0)
  206. fatal("-u needs symbol name");
  207. h = hash(*argv);
  208. if (searchname(*argv, h) == (struct outname *)0)
  209. entername(makename(*argv), h);
  210. break;
  211. case 'v':
  212. Verbose = 1;
  213. break;
  214. case 'S':
  215. statistics = 1;
  216. break;
  217. default:
  218. warning("bad flag letter %c", *argp);
  219. break;
  220. }
  221. }
  222. }
  223. /*
  224. * If `s' starts with 0x/0X, it's hexadecimal,
  225. * else if it starts with 0b/0B, it's binary,
  226. * else if it starts with 0, it's octal,
  227. * else it's decimal.
  228. */
  229. static long
  230. number(s)
  231. register char *s;
  232. {
  233. register int digit;
  234. register long value = 0;
  235. register int radix = 10;
  236. if (*s == '0') {
  237. radix = 8;
  238. s++;
  239. if (*s == 'x' || *s == 'X') {
  240. radix = 16;
  241. s++;
  242. } else if (*s == 'b' || *s == 'B') {
  243. radix = 2;
  244. s++;
  245. }
  246. }
  247. while (digit = *s++) {
  248. if (digit >= 'A' && digit <= 'F')
  249. digit = digit - 'A' + 10;
  250. else if (digit >= 'a' && digit <= 'f')
  251. digit = digit - 'a' + 10;
  252. else if (digit >= '0' && digit <= '9')
  253. digit = digit - '0';
  254. else
  255. fatal("wrong digit %c", digit);
  256. if (digit >= radix)
  257. fatal("digit %c exceeds radix %d", digit, radix);
  258. value = radix * value + digit;
  259. }
  260. return value;
  261. }
  262. /*
  263. * We use one bit per section to indicate whether a base was already given or
  264. * not. Only one base may be given. The same applies for alignments.
  265. */
  266. static char basemap[MAXSECT / WIDTH];
  267. static long sect_base[MAXSECT];
  268. static char lignmap[MAXSECT / WIDTH];
  269. static long sect_lign[MAXSECT];
  270. /*
  271. /*
  272. * Set the alignment of section `sectno' to `lign', if this doesn't
  273. * conflict with earlier alignment.
  274. */
  275. static
  276. setlign(sectno, lign)
  277. register int sectno;
  278. register long lign;
  279. {
  280. extern bool setbit();
  281. if (setbit(sectno, lignmap) && sect_lign[sectno] != lign)
  282. fatal("section has different alignments");
  283. if (lign == (long)0)
  284. fatal("alignment cannot be zero");
  285. sect_lign[sectno] = lign;
  286. }
  287. /*
  288. * Set the base of section `sectno' to `base', if no other base has been
  289. * given yet.
  290. */
  291. static
  292. setbase(sectno, base)
  293. register int sectno;
  294. register long base;
  295. {
  296. extern bool setbit();
  297. if (setbit(sectno, basemap) && sect_base[sectno] != base)
  298. fatal("section has different bases");
  299. sect_base[sectno] = base;
  300. }
  301. static struct outname *
  302. makename(string)
  303. char *string;
  304. {
  305. static struct outname namebuf;
  306. namebuf.on_mptr = string;
  307. namebuf.on_type = S_UND + S_EXT;
  308. namebuf.on_valu = (long)0;
  309. return &namebuf;
  310. }
  311. /*
  312. * If `file' is a plain file, symboltable information and section sizes are
  313. * extracted. If it is an archive it is examined to see if it defines any
  314. * undefined symbols.
  315. */
  316. static
  317. pass1(file)
  318. char *file;
  319. {
  320. if (getfile(file) == PLAIN) {
  321. debug("%s: plain file\n", file, 0, 0, 0);
  322. extract();
  323. } else {
  324. /* It must be an archive. */
  325. debug("%s: archive\n", file, 0, 0, 0);
  326. arch();
  327. }
  328. closefile(file);
  329. }
  330. /* ---------------- ROUTINES BETWEEN FIRST AND SECOND PASS ----------------- */
  331. /*
  332. * After pass 1 we know the sizes of all commons so we can give each common
  333. * name an address within its section and we can compute the sizes of all
  334. * sections in the machine. After this we can compute the bases of all
  335. * sections. We then add the section bases to the values of names in
  336. * corresponding sections.
  337. */
  338. static
  339. evaluate()
  340. {
  341. norm_commons();
  342. complete_sections();
  343. if (!(flagword&RFLAG))
  344. change_names();
  345. }
  346. extern unsigned short NGlobals, NLocals;
  347. /*
  348. * Sect_comm[N] is the number of common bytes in section N.
  349. * It is computed after pass 1.
  350. */
  351. long sect_comm[MAXSECT];
  352. /*
  353. * If there are undefined names, we print them and we set a flag so that
  354. * the output can be subject to another led run and we return.
  355. * We now know how much space each common name needs. We change the value
  356. * of the common name from the size to the address within its section,
  357. * just like "normal" names. We also count the total size of common names
  358. * within each section to be able to compute the final size in the machine.
  359. */
  360. static
  361. norm_commons()
  362. {
  363. register struct outname *name;
  364. register int cnt;
  365. register int und = FALSE;
  366. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  367. cnt = NGlobals;
  368. while (cnt-- > 0) {
  369. if (ISUNDEFINED(name)) {
  370. if (!und) {
  371. und = TRUE;
  372. if (!(flagword & RFLAG)) {
  373. exitstatus = 1;
  374. fprintf(stderr, "Undefined:\n");
  375. }
  376. outhead.oh_flags |= HF_LINK;
  377. if (flagword & RFLAG) break;
  378. flagword = (flagword & ~SFLAG) | RFLAG;
  379. }
  380. fprintf(stderr, "\t%s\n",
  381. address(ALLOGCHR, (ind_t)name->on_foff)
  382. );
  383. }
  384. name++;
  385. }
  386. if (flagword & RFLAG) return;
  387. /*
  388. * RFLAG is off, so we need not produce relocatable output.
  389. * We can now assign an address to common names.
  390. * It also means that there are no undefined names.
  391. */
  392. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  393. cnt = NGlobals;
  394. while (cnt-- > 0) {
  395. if (!ISABSOLUTE(name) && ISCOMMON(name)) {
  396. register long size;
  397. register int sectindex;
  398. size = name->on_valu; /* XXX rounding? */
  399. sectindex = (name->on_type & S_TYP) - S_MIN;
  400. name->on_valu =
  401. outsect[sectindex].os_size +
  402. sect_comm[sectindex];
  403. sect_comm[sectindex] += size;
  404. name->on_type &= ~S_COM;
  405. }
  406. name++;
  407. }
  408. }
  409. struct orig relorig[MAXSECT];
  410. /*
  411. * Compute the offsets in file and machine that the sections will have.
  412. * Also set the origins to 0.
  413. */
  414. static
  415. complete_sections()
  416. {
  417. register long base = 0;
  418. register long foff;
  419. register struct outsect *sc;
  420. register int sectindex;
  421. foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT;
  422. for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) {
  423. relorig[sectindex].org_size = (long)0;
  424. sc = &outsect[sectindex];
  425. sc->os_foff = foff;
  426. foff += sc->os_flen;
  427. if (flagword & RFLAG)
  428. continue;
  429. sc->os_size += sect_comm[sectindex];
  430. sc->os_lign =
  431. tstbit(sectindex, lignmap) ? sect_lign[sectindex] : 1;
  432. if (tstbit(sectindex, basemap)) {
  433. base = sect_base[sectindex];
  434. if (sc->os_lign && base % sc->os_lign)
  435. fatal("base not aligned");
  436. } else if (sc->os_lign) {
  437. base += sc->os_lign - 1;
  438. base -= base % sc->os_lign;
  439. }
  440. sc->os_base = base;
  441. base += sc->os_size;
  442. }
  443. }
  444. /*
  445. * For each name we add the base of its section to its value, unless
  446. * the output has to be able to be linked again, as indicated by RFLAG.
  447. */
  448. static
  449. change_names()
  450. {
  451. register int cnt;
  452. register struct outname *name;
  453. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  454. cnt = NGlobals;
  455. while (cnt-- > 0) {
  456. addbase(name);
  457. name++;
  458. }
  459. if (!incore)
  460. return;
  461. /*
  462. * Do the same with the local names.
  463. */
  464. name = (struct outname *)address(ALLOLOCL, (ind_t)0);
  465. cnt = NLocals;
  466. while (cnt-- > 0) {
  467. addbase(name);
  468. name++;
  469. }
  470. }
  471. #define BIT 0x01
  472. /*
  473. * This function sets a bit with index `indx' in string.
  474. * It returns whether it was already set.
  475. */
  476. bool
  477. setbit(indx, string)
  478. int indx;
  479. char string[];
  480. {
  481. register int byte_index, bit_index;
  482. register int byte;
  483. byte_index = indx / WIDTH; /* Index of byte with bit we need. */
  484. bit_index = indx % WIDTH; /* Index of bit we need. */
  485. byte = string[byte_index];
  486. byte >>= bit_index;
  487. if (byte & BIT) return TRUE;
  488. byte = BIT;
  489. byte <<= bit_index;
  490. string[byte_index] |= byte;
  491. return FALSE;
  492. }
  493. /*
  494. * This function returns whether the bit given by `indx' is set in `string'.
  495. */
  496. static bool
  497. tstbit(indx, string)
  498. int indx;
  499. char string[];
  500. {
  501. register int byte_index, bit_index;
  502. register int byte;
  503. byte_index = indx / WIDTH; /* Index of byte with bit we need. */
  504. bit_index = indx % WIDTH; /* Index of bit we need. */
  505. byte = string[byte_index];
  506. byte >>= bit_index;
  507. return byte & BIT;
  508. }
  509. /*
  510. * Add the base of the section of a name to its value.
  511. */
  512. addbase(name)
  513. struct outname *name;
  514. {
  515. register int type = name->on_type & S_TYP;
  516. register int sectindex = type - S_MIN;
  517. if (type == S_UND || type == S_ABS || type == S_CRS)
  518. return;
  519. if (name->on_type & S_COM)
  520. return;
  521. name->on_valu += outsect[sectindex].os_base;
  522. debug( "%s: type 0x%x, value %ld\n",
  523. address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR,
  524. (ind_t)name->on_foff
  525. ),
  526. name->on_type, name->on_valu, 0
  527. );
  528. }
  529. /* ------------------------ ROUTINES OF SECOND PASS ------------------------ */
  530. /*
  531. * Flags have already been processed, so we ignore them here.
  532. */
  533. static
  534. second_pass(argv)
  535. char **argv;
  536. {
  537. passnumber = SECOND;
  538. while (*++argv) {
  539. if ((*argv)[0] != '-') {
  540. pass2(*argv);
  541. continue;
  542. }
  543. switch ((*argv)[1]) {
  544. case 'o':
  545. case 'u':
  546. ++argv;
  547. break;
  548. default:
  549. break;
  550. }
  551. }
  552. }
  553. static
  554. pass2(file)
  555. char *file;
  556. {
  557. if (getfile(file) == PLAIN) {
  558. debug("%s: plain file\n", file, 0, 0, 0);
  559. finish();
  560. } else {
  561. /* It must be an archive. */
  562. debug("%s: archive\n", file, 0, 0, 0);
  563. arch2();
  564. }
  565. closefile(file);
  566. }