archive.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include "arch.h"
  11. #include "out.h"
  12. #include "ranlib.h"
  13. #include "const.h"
  14. #include "debug.h"
  15. #include "memory.h"
  16. #include "defs.h"
  17. #define ENDLIB ((long)0)
  18. static struct ar_hdr arhdr;
  19. static void notelib(long pos);
  20. /*
  21. * First read a long telling how many ranlib structs there are, then
  22. * the structs themselves. Second read a long telling how many chars there are
  23. * in the string table, then the string table itself.
  24. * We keep only one ranlib table in core, so this table always starts at offset
  25. * (ind_t)0 from its base.
  26. */
  27. static long getsymdeftable()
  28. {
  29. ind_t off;
  30. struct ranlib *ran;
  31. long count;
  32. long nran, nchar;
  33. extern long rd_long();
  34. extern int infile;
  35. count = nran = rd_long(infile);
  36. debug("%ld ranlib structs, ", nran);
  37. off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib));
  38. if (off == BADOFF)
  39. fatal("no space for ranlib structs");
  40. ran = (struct ranlib *)address(ALLORANL, off);
  41. rd_ranlib(infile, ran, count);
  42. nchar = rd_long(infile);
  43. debug("%ld ranlib chars\n", nchar);
  44. if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF)
  45. fatal("no space for ranlib strings");
  46. rd_bytes(infile, address(ALLORANL, off), nchar);
  47. ran = (struct ranlib *)address(ALLORANL, (ind_t)0);
  48. while (count--) {
  49. /*
  50. * Adjust because names are now in core, not on file.
  51. * Note that `ran_off' is measured from the beginning of the
  52. * string area, NOT from the beginning of the file.
  53. */
  54. if (ran->ran_off >= nchar)
  55. fatal("bad ranlib string offset");
  56. ran->ran_off += off;
  57. ran++;
  58. }
  59. return nran;
  60. }
  61. extern char *modulname;
  62. /*
  63. * Process archive with table of contents. The table of contents tells
  64. * of symbols in which module they are defined. We scan the table for
  65. * symbols that are known but not yet defined. Then we extract all necessary
  66. * information from the corresponding module. This module may need symbols that
  67. * were defined in modules located before this one in the archive, so we
  68. * scan the table again. We perform these actions as long as new symbols
  69. * are defined.
  70. */
  71. void arch()
  72. {
  73. long nran;
  74. bool resolved;
  75. nran = getsymdeftable();
  76. savemagic();
  77. do {
  78. register ind_t ranindex;
  79. register long count;
  80. debug("(re)scan ranlib table\n");
  81. ranindex = (ind_t)0;
  82. count = nran;
  83. resolved = FALSE;
  84. while (count > 0) {
  85. register struct ranlib *ran;
  86. register char *string;
  87. register struct outname *name;
  88. register long pos;
  89. extern int hash();
  90. extern struct outname *searchname();
  91. ran = (struct ranlib *)address(ALLORANL, ranindex);
  92. string = address(ALLORANL, (ind_t)ran->ran_off);
  93. name = searchname(string, hash(string));
  94. if (name == (struct outname *)0 || !ISUNDEFINED(name)) {
  95. ranindex += sizeof(struct ranlib);
  96. count--;
  97. continue;
  98. }
  99. seek(ran->ran_pos);
  100. get_archive_header(&arhdr);
  101. modulname = arhdr.ar_name;
  102. verbose("defines %s", string);
  103. resolved = TRUE;
  104. /*
  105. * This archive member is going to be linked,
  106. * so we don't need to know what else it defines.
  107. * Note that we assume that all ranlib information of
  108. * one archive member is contiguous.
  109. */
  110. pos = ran->ran_pos;
  111. do {
  112. count--; ran++;
  113. ranindex += sizeof(struct ranlib);
  114. } while (count > 0 && ran->ran_pos == pos);
  115. notelib(pos);
  116. savehdr(&arhdr);
  117. extract();
  118. }
  119. } while (resolved);
  120. dealloc(ALLORANL);
  121. notelib(ENDLIB);
  122. }
  123. /*
  124. * An archive member that will be loaded is remembered by storing its position
  125. * in the archive into the table of positions.
  126. */
  127. static void notelib(long pos)
  128. {
  129. ind_t off;
  130. if ((off = hard_alloc(ALLOARCH, (long)sizeof(long))) == BADOFF)
  131. fatal("no space for archive position");
  132. *(long *)address(ALLOARCH, off) = pos;
  133. }
  134. /*
  135. * Index of position of first archive member of next archive.
  136. */
  137. static ind_t posindex = (ind_t)0;
  138. /*
  139. * Process the archive in pass 2.
  140. * We walk through the table of positions telling at what byte offset the
  141. * archive header + module is located, until this position is ENDLIB, meaning
  142. * that we've processed all needed modules in this archive. Each group of
  143. * positions of an archive is terminated with ENDLIB.
  144. */
  145. void arch2()
  146. {
  147. long *pos;
  148. ind_t localpos;
  149. localpos = posindex;
  150. for ( pos = (long *)address(ALLOARCH, localpos);
  151. *pos != ENDLIB;
  152. pos++, localpos += sizeof(long)
  153. ) {
  154. seek(*pos);
  155. get_archive_header(&arhdr);
  156. modulname = arhdr.ar_name;
  157. debug("%s: archive member\n", modulname);
  158. finish();
  159. }
  160. localpos += sizeof(long); /* Skip ENDLIB. */
  161. posindex = localpos; /* Remember for next call. */
  162. }