main.c 13 KB

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