scan.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include "arch.h"
  13. #include "out.h"
  14. #include "ranlib.h"
  15. #include "const.h"
  16. #include "assert.h"
  17. #include "memory.h"
  18. #include "scan.h"
  19. #include "debug.h"
  20. #include "defs.h"
  21. #include "object.h"
  22. #define READ 0
  23. #define IND_EMIT(x) (IND_CHAR(x) + (ind_t)align((x).oh_nchar))
  24. #define IND_RELO(x) (IND_EMIT(x) + (x).oh_nsect * sizeof(ind_t))
  25. #ifdef SYMDBUG
  26. #define IND_DBUG(x) (IND_RELO(x) + sizeof(ind_t))
  27. #endif /* SYMDBUG */
  28. extern bool incore;
  29. extern int infile;
  30. extern int passnumber;
  31. char *archname; /* Name of archive, if reading from archive. */
  32. char *modulname; /* Name of object module. */
  33. #ifdef SYMDBUG
  34. long objectsize;
  35. #endif /* SYMDBUG */
  36. static long align(long size);
  37. static char *modulbase;
  38. static long modulsize(struct outhead *head);
  39. static void scan_modul();
  40. static bool all_alloc();
  41. static bool direct_alloc(struct outhead *head);
  42. static bool indirect_alloc(struct outhead *head);
  43. static bool putemitindex(ind_t sectindex, ind_t emitoff, int allopiece);
  44. static bool putreloindex(ind_t relooff, long nrelobytes);
  45. #ifdef SYMDBUG
  46. static bool putdbugindex(ind_t dbugoff, long ndbugbytes);
  47. #endif /* SYMDBUG */
  48. static void get_indirect(struct outhead *head, struct outsect *sect);
  49. static void read_modul();
  50. /*
  51. * Open the file with name `filename' (if necessary) and examine the first
  52. * few bytes to see if it's a plain file or an archive.
  53. * In case of a plain file, the file pointer is repositioned after the
  54. * examination. Otherwise it is at the beginning of the table of contents.
  55. */
  56. int getfile(char *filename)
  57. {
  58. struct ar_hdr archive_header;
  59. unsigned short magic_number;
  60. #ifdef SYMDBUG
  61. struct stat statbuf;
  62. #endif /* SYMDBUG */
  63. archname = (char *)0;
  64. modulname = (char *)0;
  65. if (passnumber == FIRST || !incore) {
  66. if ((infile = open(filename, READ)) < 0)
  67. fatal("can't read %s", filename);
  68. magic_number = rd_unsigned2(infile);
  69. } else {
  70. modulbase = modulptr((ind_t)0);
  71. magic_number = *(unsigned short *)modulbase;
  72. }
  73. switch (magic_number) {
  74. case O_MAGIC:
  75. #ifdef SYMDBUG
  76. if (passnumber == FIRST || !incore) {
  77. if (fstat(infile, &statbuf) < 0)
  78. fatal("cannot stat %s", filename);
  79. objectsize = statbuf.st_size;
  80. }
  81. #endif /* SYMDBUG */
  82. seek((long)0);
  83. modulname = filename;
  84. return PLAIN;
  85. case ARMAG:
  86. case AALMAG:
  87. archname = filename;
  88. if (passnumber == FIRST) {
  89. rd_arhdr(infile, &archive_header);
  90. if (strcmp(archive_header.ar_name, SYMDEF))
  91. fatal("%s: no table of contents", filename);
  92. } else if (incore) {
  93. modulbase += sizeof(int);
  94. core_position += sizeof(int);
  95. }
  96. return ARCHIVE;
  97. default:
  98. fatal("%s: wrong magic number", filename);
  99. }
  100. /* NOTREACHED */
  101. return 0;
  102. }
  103. /* ARGSUSED */
  104. void closefile(char *filename)
  105. {
  106. if (passnumber == FIRST || !incore)
  107. close(infile);
  108. }
  109. void get_archive_header(struct ar_hdr *archive_header)
  110. {
  111. if (passnumber == FIRST || !incore) {
  112. rd_arhdr(infile, archive_header);
  113. } else {
  114. /* Copy structs. */
  115. *archive_header = *(struct ar_hdr *)modulbase;
  116. modulbase += int_align(sizeof(struct ar_hdr));
  117. core_position += int_align(sizeof(struct ar_hdr));
  118. }
  119. #ifdef SYMDBUG
  120. objectsize = archive_header.ar_size;
  121. #endif /* SYMDBUG */
  122. }
  123. void get_modul()
  124. {
  125. if (passnumber == FIRST) {
  126. rd_fdopen(infile);
  127. scan_modul();
  128. } else if (!incore) {
  129. rd_fdopen(infile);
  130. read_modul();
  131. }
  132. }
  133. /*
  134. * Read module from the current file. If it doesn't fit into core, the strategy
  135. * to keep everything in core is abandoned, but we will always put the header,
  136. * the section table, and the name and string table into core.
  137. */
  138. static void scan_modul()
  139. {
  140. bool space;
  141. struct outhead *head;
  142. struct outsect *sect;
  143. space = all_alloc();
  144. head = (struct outhead *)modulptr(IND_HEAD);
  145. if (space) {
  146. sect = (struct outsect *)modulptr(IND_SECT(*head));
  147. get_indirect(head, sect);
  148. }
  149. rd_name((struct outname *)modulptr(IND_NAME(*head)), head->oh_nname);
  150. rd_string((char *)modulptr(IND_CHAR(*head)), head->oh_nchar);
  151. #ifdef SYMDBUG
  152. if (space) {
  153. get_dbug(*(ind_t *)modulptr(IND_DBUG(*head)),
  154. ojectsize - OFF_DBUG(*head)
  155. );
  156. }
  157. #endif /* SYMDBUG */
  158. }
  159. /*
  160. * Allocate space for and read in the header and section table.
  161. * First get the header. With this we can determine what to allocate
  162. * for the rest of the module, and with the rest we can determine what
  163. * to allocate for the section contents.
  164. * If possible, allocate space for the rest of the module. Return whether
  165. * this was possible.
  166. */
  167. static bool all_alloc()
  168. {
  169. struct outhead head;
  170. if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF)
  171. fatal("no space for module header");
  172. rd_ohead((struct outhead *)modulptr(IND_HEAD));
  173. /*
  174. * Copy the header because we need it so often.
  175. */
  176. head = *(struct outhead *)modulptr(IND_HEAD);
  177. return direct_alloc(&head) && indirect_alloc(&head);
  178. }
  179. /*
  180. * Allocate space for the rest of the direct bytes.
  181. * First allocate the section table and read it in, then allocate the rest
  182. * and return whether this succeeded.
  183. */
  184. static bool direct_alloc(struct outhead *head)
  185. {
  186. ind_t sectindex = IND_SECT(*head);
  187. struct outsect *sects;
  188. unsigned short nsect = head->oh_nsect;
  189. long size, rest;
  190. #ifdef SYMDBUG
  191. rest = nsect * sizeof(ind_t) + sizeof(ind_t) + sizeof(ind_t);
  192. #else /* SYMDBUG */
  193. rest = nsect * sizeof(ind_t) + sizeof(ind_t);
  194. #endif /* SYMDBUG */
  195. /*
  196. * We already allocated space for the header, we now need
  197. * the section, name an string table.
  198. */
  199. size = modulsize(head) - sizeof(struct outhead) - rest;
  200. if (hard_alloc(ALLOMODL, size) == BADOFF)
  201. fatal("no space for module");
  202. rd_sect(sects = ((struct outsect *)modulptr(sectindex)), nsect);
  203. while (nsect--) {
  204. if (sects->os_lign > 1) {
  205. sects->os_size += sects->os_lign - 1;
  206. sects->os_size -= sects->os_size % sects->os_lign;
  207. }
  208. sects++;
  209. }
  210. return incore && alloc(ALLOMODL, rest) != BADOFF;
  211. }
  212. /*
  213. * Allocate space for the indirectly accessed pieces: the section contents and
  214. * the relocation table, and put their indices in the right place.
  215. */
  216. static bool indirect_alloc(struct outhead *head)
  217. {
  218. int allopiece;
  219. unsigned short nsect = head->oh_nsect;
  220. unsigned short nrelo = head->oh_nrelo;
  221. ind_t sectindex = IND_SECT(*head);
  222. ind_t emitoff = IND_EMIT(*head);
  223. ind_t relooff = IND_RELO(*head);
  224. #ifdef SYMDBUG
  225. ind_t dbugoff = IND_DBUG(*head);
  226. extern long objectsize;
  227. long dbugsize = objectsize - OFF_DBUG(*head);
  228. #endif /* SYMDBUG */
  229. assert(incore);
  230. for (allopiece = ALLOEMIT; allopiece < ALLOEMIT + nsect; allopiece++) {
  231. if (!putemitindex(sectindex, emitoff, allopiece))
  232. return FALSE;
  233. sectindex += sizeof(struct outsect);
  234. emitoff += sizeof(ind_t);
  235. }
  236. #ifdef SYMDBUG
  237. return putreloindex(relooff, (long)nrelo * sizeof(struct outrelo))
  238. &&
  239. putdbugindex(dbugoff, dbugsize);
  240. #else /* SYMDBUG */
  241. return putreloindex(relooff, (long)nrelo * sizeof(struct outrelo));
  242. #endif /* SYMDBUG */
  243. }
  244. /*
  245. * Allocate space for the contents of the section of which the table entry is
  246. * at offset `sectindex'. Put the offset of the allocated piece at offset
  247. * `emitoff'.
  248. */
  249. static bool putemitindex(ind_t sectindex, ind_t emitoff, int allopiece)
  250. {
  251. long flen;
  252. ind_t emitindex;
  253. static long zeros[MAXSECT];
  254. long zero = zeros[allopiece - ALLOEMIT];
  255. /*
  256. * Notice that "sectindex" is not a section number!
  257. * It contains the offset of the section from the beginning
  258. * of the module. Thus, it cannot be used to index "zeros".
  259. * AIAIAIAIA
  260. */
  261. flen = ((struct outsect *)modulptr(sectindex))->os_flen;
  262. if (flen && zero) {
  263. if ((emitindex = alloc(allopiece, zero)) != BADOFF){
  264. char *p = address(allopiece, emitindex);
  265. debug("Zeros %ld\n", zero);
  266. while (zero--) *p++ = 0;
  267. }
  268. else return FALSE;
  269. zero = 0;
  270. }
  271. zeros[allopiece - ALLOEMIT] =
  272. zero + ((struct outsect *) modulptr(sectindex))->os_size - flen;
  273. if ((emitindex = alloc(allopiece, flen)) != BADOFF) {
  274. *(ind_t *)modulptr(emitoff) = emitindex;
  275. return TRUE;
  276. }
  277. return FALSE;
  278. }
  279. /*
  280. * Allocate space for a relocation table with `nrelobytes' bytes, and put the
  281. * offset at `relooff'.
  282. */
  283. static bool putreloindex(ind_t relooff, long nrelobytes)
  284. {
  285. ind_t reloindex;
  286. if ((reloindex = alloc(ALLORELO, nrelobytes)) != BADOFF) {
  287. *(ind_t *)modulptr(relooff) = reloindex;
  288. return TRUE;
  289. }
  290. return FALSE;
  291. }
  292. #ifdef SYMDBUG
  293. /*
  294. * Allocate space for debugging information and put the offset at `dbugoff'.
  295. */
  296. static bool putdbugindex(ind_t dbugoff, long ndbugbytes)
  297. {
  298. ind_t dbugindex;
  299. if ((dbugindex = alloc(ALLODBUG, ndbugbytes)) != BADOFF) {
  300. *(ind_t *)modulptr(dbugoff) = dbugindex;
  301. return TRUE;
  302. }
  303. return FALSE;
  304. }
  305. #endif /* SYMDBUG */
  306. /*
  307. * Compute addresses and read in. Remember that the contents of the sections
  308. * and also the relocation table are accessed indirectly.
  309. */
  310. static void get_indirect(struct outhead *head, struct outsect *sect)
  311. {
  312. ind_t *emitindex;
  313. int nsect;
  314. int piece;
  315. ind_t *reloindex;
  316. emitindex = (ind_t *)modulptr(IND_EMIT(*head));
  317. piece = ALLOEMIT;
  318. for (nsect = 0; nsect < head->oh_nsect; nsect++) {
  319. rd_outsect(nsect);
  320. rd_emit(address(piece, *emitindex), sect->os_flen);
  321. piece++; emitindex++; sect++;
  322. }
  323. reloindex = (ind_t *)modulptr(IND_RELO(*head));
  324. rd_relo((struct outrelo *)address(ALLORELO, *reloindex),
  325. head->oh_nrelo
  326. );
  327. }
  328. /*
  329. * Set the file pointer at `pos'.
  330. */
  331. void seek(long pos)
  332. {
  333. if (passnumber == FIRST || !incore)
  334. lseek(infile, pos, 0);
  335. }
  336. /*
  337. * A file pointer is advanced automatically when reading, a char pointer
  338. * is not. That's why we do it here. If we don't keep everything in core,
  339. * we give the space allocated for a module back.
  340. */
  341. void skip_modul(struct outhead *head)
  342. {
  343. ind_t skip = modulsize(head);
  344. if (incore) {
  345. core_position += int_align(skip);
  346. if (passnumber == SECOND)
  347. modulbase += int_align(skip);
  348. } else {
  349. dealloc(ALLOMODL);
  350. core_position = (ind_t)0;
  351. }
  352. }
  353. /*
  354. * Read in what we need in pass 2, because we couldn't keep it in core.
  355. */
  356. static void read_modul()
  357. {
  358. struct outhead *head;
  359. struct outsect *sects;
  360. struct outname *names;
  361. char *chars;
  362. ind_t sectindex, nameindex, charindex;
  363. unsigned short nsect, nname;
  364. long size;
  365. long nchar;
  366. assert(passnumber == SECOND);
  367. assert(!incore);
  368. if (hard_alloc(ALLOMODL, (long)sizeof(struct outhead)) == BADOFF)
  369. fatal("no space for module header");
  370. head = (struct outhead *)modulptr(IND_HEAD);
  371. rd_ohead(head);
  372. nsect = head->oh_nsect; sectindex = IND_SECT(*head);
  373. nname = head->oh_nname; nameindex = IND_NAME(*head);
  374. nchar = head->oh_nchar; charindex = IND_CHAR(*head);
  375. #ifdef SYMDBUG
  376. size = modulsize(head) - (nsect * sizeof(ind_t) + 2 * sizeof(ind_t));
  377. #else /* SYMDBUG */
  378. size = modulsize(head) - (nsect * sizeof(ind_t) + sizeof(ind_t));
  379. #endif /* SYMDBUG */
  380. if (hard_alloc(ALLOMODL, size) == BADOFF)
  381. fatal("no space for module");
  382. sects = (struct outsect *)modulptr(sectindex);
  383. names = (struct outname *)modulptr(nameindex);
  384. chars = modulptr(charindex);
  385. rd_sect(sects, nsect);
  386. while (nsect--) {
  387. if (sects->os_lign > 1) {
  388. sects->os_size += sects->os_lign - 1;
  389. sects->os_size -= sects->os_size % sects->os_lign;
  390. }
  391. sects++;
  392. }
  393. rd_name(names, nname);
  394. rd_string(chars, nchar);
  395. }
  396. /*
  397. * Align `size' to a multiple of the size of a double.
  398. * This is assumed to be a power of 2.
  399. */
  400. static long align(long size)
  401. {
  402. return (size + (sizeof(double) - 1)) & ~(int)(sizeof(double) - 1);
  403. }
  404. /*
  405. * Compute how many DIRECT bytes must be allocated for a module of which the
  406. * header is pointed to by `head':
  407. * 0. the header,
  408. * 1. the section table,
  409. * 2. the name table,
  410. * 3. the string table,
  411. * 4. for each section the offset of its contents,
  412. * 5. the offset of the relocation table.
  413. #ifdef SYMDBUG
  414. * 6. the offset of the debugging information.
  415. #endif
  416. */
  417. static long modulsize(struct outhead *head)
  418. {
  419. return sizeof(struct outhead) + /* 0 */
  420. head->oh_nsect * sizeof(struct outsect) + /* 1 */
  421. head->oh_nname * sizeof(struct outname) + /* 2 */
  422. align(head->oh_nchar) + /* 3 */
  423. head->oh_nsect * sizeof(ind_t) + /* 4 */
  424. #ifdef SYMDBUG
  425. sizeof(ind_t) + /* 5 */
  426. sizeof(ind_t); /* 6 */
  427. #else /* SYMDBUG */
  428. sizeof(ind_t); /* 5 */
  429. #endif /* SYMDBUG */
  430. }
  431. /* ------------------------------------------------------------------------- */
  432. /*
  433. * Walk through the relocation table of the current module. We must either walk
  434. * through core or through file. Startrelo() should be called first.
  435. */
  436. static struct outrelo *walkrelo;
  437. static unsigned short cnt_relos;
  438. static unsigned short relind;
  439. #define _RELSIZ 64
  440. void startrelo(struct outhead *head)
  441. {
  442. ind_t reloindex;
  443. if (incore) {
  444. reloindex = *(ind_t *)(modulbase + IND_RELO(*head));
  445. walkrelo = (struct outrelo *)address(ALLORELO, reloindex);
  446. }
  447. else {
  448. relind = _RELSIZ;
  449. rd_rew_relos(head);
  450. cnt_relos = head->oh_nrelo;
  451. }
  452. }
  453. struct outrelo *nextrelo()
  454. {
  455. static struct outrelo relobuf[_RELSIZ];
  456. if (incore)
  457. return walkrelo++;
  458. if (relind == _RELSIZ) {
  459. unsigned int i = cnt_relos >= _RELSIZ ? _RELSIZ : cnt_relos;
  460. cnt_relos -= i;
  461. rd_relo(relobuf, i);
  462. relind = 0;
  463. }
  464. return &relobuf[relind++];
  465. }
  466. /* ------------------------------------------------------------------------- */
  467. /*
  468. * Get the section contents in core of which the describing struct has index
  469. * `sectindex'. `Head' points to the header of the module.
  470. */
  471. char *getemit(struct outhead *head, struct outsect *sects, int sectindex)
  472. {
  473. char *ret;
  474. ind_t off;
  475. if (!incore) {
  476. ret = core_alloc(ALLOMODL, sects[sectindex].os_flen);
  477. if (ret == (char *)0)
  478. return 0;
  479. rd_outsect(sectindex);
  480. rd_emit(ret, sects[sectindex].os_flen);
  481. return ret;
  482. }
  483. /*
  484. * We have an offset in the contents of the final output
  485. * "file" where normally the contents would be.
  486. */
  487. off = *((ind_t *)(modulbase + IND_EMIT(*head)) + sectindex);
  488. return address(ALLOEMIT + sectindex, off);
  489. }
  490. char *getblk(long totalsz, long *pblksz, int sectindex)
  491. {
  492. char *ret;
  493. long sz = (1L << 30);
  494. assert(!incore);
  495. while (sz >= totalsz) sz >>= 1;
  496. while (sz) {
  497. ret = core_alloc(ALLOMODL, sz);
  498. if (ret != (char *) 0) {
  499. rd_outsect(sectindex);
  500. *pblksz = sz;
  501. return ret;
  502. }
  503. sz >>= 1;
  504. }
  505. fatal("no space for section contents");
  506. return (char *) 0;
  507. }
  508. void endemit(char *emit)
  509. {
  510. core_free(ALLOMODL, emit);
  511. }