archive.c 4.7 KB

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