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".
6 static char rcsid[] = "$Id: archive.c,v 3.3 1994/06/24 10:34:23 ceriel Exp $";
17 #define ENDLIB ((long)0)
19 extern ind_t hard_alloc();
21 static struct ar_hdr arhdr;
24 * First read a long telling how many ranlib structs there are, then
25 * the structs themselves. Second read a long telling how many chars there are
26 * in the string table, then the string table itself.
27 * We keep only one ranlib table in core, so this table always starts at offset
28 * (ind_t)0 from its base.
34 register struct ranlib *ran;
36 register long nran, nchar;
37 extern long rd_long();
40 count = nran = rd_long(infile);
41 debug("%ld ranlib structs, ", nran, 0, 0, 0);
42 off = hard_alloc(ALLORANL, nran * sizeof(struct ranlib));
44 fatal("no space for ranlib structs");
45 ran = (struct ranlib *)address(ALLORANL, off);
46 rd_ranlib(infile, ran, count);
47 nchar = rd_long(infile);
48 debug("%ld ranlib chars\n", nchar, 0, 0, 0);
49 if ((off = hard_alloc(ALLORANL, nchar)) == BADOFF)
50 fatal("no space for ranlib strings");
51 rd_bytes(infile, address(ALLORANL, off), nchar);
52 ran = (struct ranlib *)address(ALLORANL, (ind_t)0);
55 * Adjust because names are now in core, not on file.
56 * Note that `ran_off' is measured from the beginning of the
57 * string area, NOT from the beginning of the file.
59 if (ran->ran_off >= nchar)
60 fatal("bad ranlib string offset");
67 extern char *modulname;
70 * Process archive with table of contents. The table of contents tells
71 * of symbols in which module they are defined. We scan the table for
72 * symbols that are known but not yet defined. Then we extract all necessary
73 * information from the corresponding module. This module may need symbols that
74 * were defined in modules located before this one in the archive, so we
75 * scan the table again. We perform these actions as long as new symbols
83 nran = getsymdeftable();
87 register ind_t ranindex;
90 debug("(re)scan ranlib table\n", 0, 0, 0, 0);
95 register struct ranlib *ran;
96 register char *string;
97 register struct outname *name;
100 extern struct outname *searchname();
102 ran = (struct ranlib *)address(ALLORANL, ranindex);
103 string = address(ALLORANL, (ind_t)ran->ran_off);
104 name = searchname(string, hash(string));
105 if (name == (struct outname *)0 || !ISUNDEFINED(name)) {
106 ranindex += sizeof(struct ranlib);
111 get_archive_header(&arhdr);
112 modulname = arhdr.ar_name;
113 verbose("defines %s", string, 0, 0, 0);
116 * This archive member is going to be linked,
117 * so we don't need to know what else it defines.
118 * Note that we assume that all ranlib information of
119 * one archive member is contiguous.
124 ranindex += sizeof(struct ranlib);
125 } while (count > 0 && ran->ran_pos == pos);
137 * An archive member that will be loaded is remembered by storing its position
138 * in the archive into the table of positions.
145 if ((off = hard_alloc(ALLOARCH, (long)sizeof(long))) == BADOFF)
146 fatal("no space for archive position");
147 *(long *)address(ALLOARCH, off) = pos;
151 * Index of position of first archive member of next archive.
153 static ind_t posindex = (ind_t)0;
156 * Process the archive in pass 2.
157 * We walk through the table of positions telling at what byte offset the
158 * archive header + module is located, until this position is ENDLIB, meaning
159 * that we've processed all needed modules in this archive. Each group of
160 * positions of an archive is terminated with ENDLIB.
165 register ind_t localpos;
168 for ( pos = (long *)address(ALLOARCH, localpos);
170 pos++, localpos += sizeof(long)
173 get_archive_header(&arhdr);
174 modulname = arhdr.ar_name;
175 debug("%s: archive member\n", modulname, 0, 0, 0);
178 localpos += sizeof(long); /* Skip ENDLIB. */
179 posindex = localpos; /* Remember for next call. */