main.c 14 KB

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