main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  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 *strchr();
  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 = strchr(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 = strchr(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 'n':
  165. /* In the resulting name list, leave offsets with
  166. respect to the beginning of the section instead
  167. of absolute addresses.
  168. */
  169. flagword |= NFLAG;
  170. break;
  171. case 'o':
  172. /*
  173. * The `name' argument after -o is used as name
  174. * of the led output file, instead of "a.out".
  175. */
  176. if ((outputname = *++argv) == (char *)0)
  177. fatal("-o needs filename");
  178. break;
  179. case 'r':
  180. /*
  181. * Generate relocation information in the output file
  182. * so that it can be the subject of another led run.
  183. * This flag also prevents final definitions from being
  184. * given to common symbols, and suppresses the
  185. * `Undefined:' diagnostic.
  186. */
  187. if (flagword & CFLAG) break;
  188. if (flagword & SFLAG)
  189. warning("-r contradicts -s: -s ignored");
  190. flagword |= RFLAG;
  191. break;
  192. case 's':
  193. /*
  194. * `Strip' the output, that is, remove the symbol table
  195. * and relocation table to save space (but impair the
  196. * usefullness of the debuggers). This information can
  197. * also be removed by astrip(1).
  198. */
  199. if (flagword & RFLAG)
  200. warning("-s contradicts -r: -s ignored");
  201. else
  202. flagword |= SFLAG;
  203. break;
  204. case 'u':
  205. /*
  206. * Take the following argument as a symbol and enter it
  207. * as undefined in the symbol table. This is useful for
  208. * loading wholly from a library, since initially the
  209. * symbol table is empty and an unresolved reference is
  210. * needed to force the loading of the first routine.
  211. */
  212. if (*++argv == (char *)0)
  213. fatal("-u needs symbol name");
  214. h = hash(*argv);
  215. if (searchname(*argv, h) == (struct outname *)0)
  216. entername(makename(*argv), h);
  217. break;
  218. case 'v':
  219. Verbose = 1;
  220. break;
  221. case 'S':
  222. statistics = 1;
  223. break;
  224. default:
  225. warning("bad flag letter %c", *argp);
  226. break;
  227. }
  228. }
  229. }
  230. /*
  231. * If `s' starts with 0x/0X, it's hexadecimal,
  232. * else if it starts with 0b/0B, it's binary,
  233. * else if it starts with 0, it's octal,
  234. * else it's decimal.
  235. */
  236. static long
  237. number(s)
  238. register char *s;
  239. {
  240. register int digit;
  241. register long value = 0;
  242. register int radix = 10;
  243. if (*s == '0') {
  244. radix = 8;
  245. s++;
  246. if (*s == 'x' || *s == 'X') {
  247. radix = 16;
  248. s++;
  249. } else if (*s == 'b' || *s == 'B') {
  250. radix = 2;
  251. s++;
  252. }
  253. }
  254. while (digit = *s++) {
  255. if (digit >= 'A' && digit <= 'F')
  256. digit = digit - 'A' + 10;
  257. else if (digit >= 'a' && digit <= 'f')
  258. digit = digit - 'a' + 10;
  259. else if (digit >= '0' && digit <= '9')
  260. digit = digit - '0';
  261. else
  262. fatal("wrong digit %c", digit);
  263. if (digit >= radix)
  264. fatal("digit %c exceeds radix %d", digit, radix);
  265. value = radix * value + digit;
  266. }
  267. return value;
  268. }
  269. /*
  270. * We use one bit per section to indicate whether a base was already given or
  271. * not. Only one base may be given. The same applies for alignments.
  272. */
  273. static char basemap[MAXSECT / WIDTH];
  274. static long sect_base[MAXSECT];
  275. static char lignmap[MAXSECT / WIDTH];
  276. static long sect_lign[MAXSECT];
  277. /*
  278. /*
  279. * Set the alignment of section `sectno' to `lign', if this doesn't
  280. * conflict with earlier alignment.
  281. */
  282. static
  283. setlign(sectno, lign)
  284. register int sectno;
  285. register long lign;
  286. {
  287. extern bool setbit();
  288. if (setbit(sectno, lignmap) && sect_lign[sectno] != lign)
  289. fatal("section has different alignments");
  290. if (lign == (long)0)
  291. fatal("alignment cannot be zero");
  292. sect_lign[sectno] = lign;
  293. }
  294. /*
  295. * Set the base of section `sectno' to `base', if no other base has been
  296. * given yet.
  297. */
  298. static
  299. setbase(sectno, base)
  300. register int sectno;
  301. register long base;
  302. {
  303. extern bool setbit();
  304. if (setbit(sectno, basemap) && sect_base[sectno] != base)
  305. fatal("section has different bases");
  306. sect_base[sectno] = base;
  307. }
  308. static struct outname *
  309. makename(string)
  310. char *string;
  311. {
  312. static struct outname namebuf;
  313. namebuf.on_mptr = string;
  314. namebuf.on_type = S_UND + S_EXT;
  315. namebuf.on_valu = (long)0;
  316. return &namebuf;
  317. }
  318. /*
  319. * If `file' is a plain file, symboltable information and section sizes are
  320. * extracted. If it is an archive it is examined to see if it defines any
  321. * undefined symbols.
  322. */
  323. static
  324. pass1(file)
  325. char *file;
  326. {
  327. if (getfile(file) == PLAIN) {
  328. debug("%s: plain file\n", file, 0, 0, 0);
  329. extract();
  330. } else {
  331. /* It must be an archive. */
  332. debug("%s: archive\n", file, 0, 0, 0);
  333. arch();
  334. }
  335. closefile(file);
  336. }
  337. /* ---------------- ROUTINES BETWEEN FIRST AND SECOND PASS ----------------- */
  338. /*
  339. * After pass 1 we know the sizes of all commons so we can give each common
  340. * name an address within its section and we can compute the sizes of all
  341. * sections in the machine. After this we can compute the bases of all
  342. * sections. We then add the section bases to the values of names in
  343. * corresponding sections.
  344. */
  345. static
  346. evaluate()
  347. {
  348. norm_commons();
  349. complete_sections();
  350. if (!(flagword&(RFLAG|NFLAG)))
  351. change_names();
  352. }
  353. extern unsigned short NGlobals, NLocals;
  354. /*
  355. * Sect_comm[N] is the number of common bytes in section N.
  356. * It is computed after pass 1.
  357. */
  358. long sect_comm[MAXSECT];
  359. /*
  360. * If there are undefined names, we print them and we set a flag so that
  361. * the output can be subject to another led run and we return.
  362. * We now know how much space each common name needs. We change the value
  363. * of the common name from the size to the address within its section,
  364. * just like "normal" names. We also count the total size of common names
  365. * within each section to be able to compute the final size in the machine.
  366. */
  367. static
  368. norm_commons()
  369. {
  370. register struct outname *name;
  371. register int cnt;
  372. register int und = FALSE;
  373. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  374. cnt = NGlobals;
  375. while (cnt-- > 0) {
  376. if (ISUNDEFINED(name)) {
  377. if (!und) {
  378. und = TRUE;
  379. if (!(flagword & RFLAG)) {
  380. exitstatus = 1;
  381. fprintf(stderr, "Undefined:\n");
  382. }
  383. outhead.oh_flags |= HF_LINK;
  384. if (flagword & RFLAG) break;
  385. flagword = (flagword & ~SFLAG) | RFLAG;
  386. }
  387. fprintf(stderr, "\t%s\n",
  388. address(ALLOGCHR, (ind_t)name->on_foff)
  389. );
  390. }
  391. name++;
  392. }
  393. if (flagword & RFLAG) return;
  394. /*
  395. * RFLAG is off, so we need not produce relocatable output.
  396. * We can now assign an address to common names.
  397. * It also means that there are no undefined names.
  398. */
  399. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  400. cnt = NGlobals;
  401. while (cnt-- > 0) {
  402. if (!ISABSOLUTE(name) && ISCOMMON(name)) {
  403. register long size;
  404. register int sectindex;
  405. size = name->on_valu; /* XXX rounding? */
  406. sectindex = (name->on_type & S_TYP) - S_MIN;
  407. name->on_valu =
  408. outsect[sectindex].os_size +
  409. sect_comm[sectindex];
  410. sect_comm[sectindex] += size;
  411. name->on_type &= ~S_COM;
  412. }
  413. name++;
  414. }
  415. }
  416. struct orig relorig[MAXSECT];
  417. /*
  418. * Compute the offsets in file and machine that the sections will have.
  419. * Also set the origins to 0.
  420. */
  421. static
  422. complete_sections()
  423. {
  424. register long base = 0;
  425. register long foff;
  426. register struct outsect *sc;
  427. register int sectindex;
  428. foff = SZ_HEAD + outhead.oh_nsect * SZ_SECT;
  429. for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) {
  430. relorig[sectindex].org_size = (long)0;
  431. sc = &outsect[sectindex];
  432. sc->os_foff = foff;
  433. foff += sc->os_flen;
  434. if (flagword & RFLAG)
  435. continue;
  436. sc->os_size += sect_comm[sectindex];
  437. sc->os_lign =
  438. tstbit(sectindex, lignmap) ? sect_lign[sectindex] : 1;
  439. if (tstbit(sectindex, basemap)) {
  440. base = sect_base[sectindex];
  441. if (sc->os_lign && base % sc->os_lign)
  442. fatal("base not aligned");
  443. } else if (sc->os_lign) {
  444. base += sc->os_lign - 1;
  445. base -= base % sc->os_lign;
  446. }
  447. sc->os_base = base;
  448. base += sc->os_size;
  449. }
  450. }
  451. /*
  452. * For each name we add the base of its section to its value, unless
  453. * the output has to be able to be linked again, as indicated by RFLAG.
  454. */
  455. static
  456. change_names()
  457. {
  458. register int cnt;
  459. register struct outname *name;
  460. name = (struct outname *)address(ALLOGLOB, (ind_t)0);
  461. cnt = NGlobals;
  462. while (cnt-- > 0) {
  463. addbase(name);
  464. name++;
  465. }
  466. if (!incore)
  467. return;
  468. /*
  469. * Do the same with the local names.
  470. */
  471. name = (struct outname *)address(ALLOLOCL, (ind_t)0);
  472. cnt = NLocals;
  473. while (cnt-- > 0) {
  474. addbase(name);
  475. name++;
  476. }
  477. }
  478. #define BIT 0x01
  479. /*
  480. * This function sets a bit with index `indx' in string.
  481. * It returns whether it was already set.
  482. */
  483. bool
  484. setbit(indx, string)
  485. int indx;
  486. char string[];
  487. {
  488. register int byte_index, bit_index;
  489. register int byte;
  490. byte_index = indx / WIDTH; /* Index of byte with bit we need. */
  491. bit_index = indx % WIDTH; /* Index of bit we need. */
  492. byte = string[byte_index];
  493. byte >>= bit_index;
  494. if (byte & BIT) return TRUE;
  495. byte = BIT;
  496. byte <<= bit_index;
  497. string[byte_index] |= byte;
  498. return FALSE;
  499. }
  500. /*
  501. * This function returns whether the bit given by `indx' is set in `string'.
  502. */
  503. static bool
  504. tstbit(indx, string)
  505. int indx;
  506. char string[];
  507. {
  508. register int byte_index, bit_index;
  509. register int byte;
  510. byte_index = indx / WIDTH; /* Index of byte with bit we need. */
  511. bit_index = indx % WIDTH; /* Index of bit we need. */
  512. byte = string[byte_index];
  513. byte >>= bit_index;
  514. return byte & BIT;
  515. }
  516. /*
  517. * Add the base of the section of a name to its value.
  518. */
  519. addbase(name)
  520. struct outname *name;
  521. {
  522. register int type = name->on_type & S_TYP;
  523. register int sectindex = type - S_MIN;
  524. if (type == S_UND || type == S_ABS || type == S_CRS)
  525. return;
  526. if (name->on_type & S_COM)
  527. return;
  528. name->on_valu += outsect[sectindex].os_base;
  529. debug( "%s: type 0x%x, value %ld\n",
  530. address((name->on_type & S_EXT) ? ALLOGCHR : ALLOLCHR,
  531. (ind_t)name->on_foff
  532. ),
  533. name->on_type, name->on_valu, 0
  534. );
  535. }
  536. /* ------------------------ ROUTINES OF SECOND PASS ------------------------ */
  537. /*
  538. * Flags have already been processed, so we ignore them here.
  539. */
  540. static
  541. second_pass(argv)
  542. char **argv;
  543. {
  544. passnumber = SECOND;
  545. while (*++argv) {
  546. if ((*argv)[0] != '-') {
  547. pass2(*argv);
  548. continue;
  549. }
  550. switch ((*argv)[1]) {
  551. case 'o':
  552. case 'u':
  553. ++argv;
  554. break;
  555. default:
  556. break;
  557. }
  558. }
  559. }
  560. static
  561. pass2(file)
  562. char *file;
  563. {
  564. if (getfile(file) == PLAIN) {
  565. debug("%s: plain file\n", file, 0, 0, 0);
  566. finish();
  567. } else {
  568. /* It must be an archive. */
  569. debug("%s: archive\n", file, 0, 0, 0);
  570. arch2();
  571. }
  572. closefile(file);
  573. }