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