archive.c 4.6 KB

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