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: extract.c,v 3.11 1994/06/24 10:34:40 ceriel Exp $";
23 extern ind_t savechar();
25 * Get section sizes and symboltable information from present module.
33 * Copy head because we need it so often but it can change place,
34 * so we can't trust a pointer to it.
36 head = *(struct outhead *)modulptr(IND_HEAD);
42 unsigned short NLocals = 0; /* Number of local names to be saved. */
43 unsigned short NGlobals = 0; /* Number of global names. */
46 * Walk through the nametable of this module, counting the locals that must
47 * appear in the final output file if this module is linked.
48 * That number will be returned.
52 register struct outhead *head;
55 register ind_t nameindex, charindex;
56 register ind_t charoff;
59 nnames = head->oh_nname;
60 nameindex = IND_NAME(*head);
61 charindex = IND_CHAR(*head);
62 charoff = OFF_CHAR(*head);
64 struct outname name; /* A local copy. */
66 * Because savelocal/getexternal might relocate the modules
67 * we have to compute the core addresses again.
69 name = *(struct outname *)modulptr(nameindex);
71 * Change the offset in file into an offset in the memory area.
72 * There will always be at least a header before the string
73 * area, so we don't have to be afraid to confuse "no name"
74 * with "the first name".
77 if (name.on_foff < charoff ||
78 name.on_foff >= charoff+head->oh_nchar) {
79 fatal("illegal offset in name");
81 name.on_foff += charindex - charoff;
84 if ((name.on_type & S_TYP) == S_CRS) {
85 name.on_valu += charindex - charoff;
86 name.on_valu = savechar(ALLOGCHR, (ind_t)name.on_valu);
88 if (name.on_type & S_EXT) {
92 * The only thing we want to know about locals is
93 * whether they must appear in the output file.
95 if (!(flagword & SFLAG) && mustsavelocal(&name)) {
100 nameindex += sizeof(struct outname);
104 extern struct orig relorig[];
108 register struct outhead *head;
110 register struct outsect *sects;
111 register struct outsect *outsp;
113 register struct orig *orig = relorig;
114 extern struct outhead outhead;
115 extern struct outsect outsect[];
117 outhead.oh_nrelo += head->oh_nrelo;
118 outhead.oh_nemit += head->oh_nemit;
119 if (head->oh_nsect > outhead.oh_nsect)
120 outhead.oh_nsect = head->oh_nsect;
121 sects = (struct outsect *)modulptr(IND_SECT(*head));
122 nsect = head->oh_nsect;
125 if (sects->os_flen) {
126 /* contains non-zero stuff */
127 outhead.oh_nemit += outsp->os_size - outsp->os_flen;
128 outsp->os_flen = outsp->os_size + sects->os_flen;
131 outsp->os_flen += sects->os_flen;
133 outsp->os_size += sects->os_size;
135 * Add all flen's and all (size - flen == zero)'s of
136 * preceding sections with the same number.
138 orig->org_size = outsp->os_size;
139 orig++; outsp++; sects++;
144 * Add relocation constant for names in user defined sections.
145 * The value of a common name indicates a size instead of an offset,
146 * and hence shouldn't be relocated.
147 * Otherwise we just add the accumulated size of all normal parts in preceding
148 * sections with the same size.
151 register struct outname *name;
153 register int type = name->on_type;
154 register int sct = type & S_TYP;
156 if (sct == S_UND || sct == S_ABS || sct == S_CRS)
159 if ( ! (type&S_EXT) ) fatal("local commons should be handled by the assembler") ;
163 name->on_valu += relorig[(type & S_TYP) - S_MIN].org_size;
167 * If we see this name for the first time, we must remember it for
168 * we might need it later on. Otherwise it must confirm to what we already
169 * know about it, and eventually add to that knowledge.
173 register struct outname *name;
175 register char *string;
177 register struct outname *old;
179 extern struct outname *searchname();
181 string = modulptr((ind_t)name->on_foff);
183 old = searchname(string, h);
184 if (old == (struct outname *)0) {
187 if (ISUNDEFINED(name)) {
188 verbose("requires %s", string, 0, 0, 0);
190 } else if (!ISUNDEFINED(name)) {
191 if (ISUNDEFINED(old)) {
192 name->on_mptr = string; /* Just for convenience. */
195 name->on_mptr = string; /* Just for convenience. */
202 * Handle the redefinition of `new' in the current module.
203 * A name can be defined in three ways, in increasing priority:
206 * defined in a section.
207 * A name may become "higher" when defined, but not "lower".
208 * A redefinition as common is allowed. It is ignored, but a warning is given
209 * when the desired section of `new' doesn't correspond with the section of
210 * `old'. If a common definition is given again for a name, we take the
211 * greatest value so that the common declared name always has enough space.
212 * If a common is defined as a not-common, the old definition is ignored.
216 register struct outname *new, *old;
218 if (!ISCOMMON(old)) {
220 error("%s: multiply defined", new->on_mptr);
222 else if ((new->on_type & S_TYP) != (old->on_type & S_TYP))
223 warning("%s: sections differ", new->on_mptr);
226 /* `Old' is common. */
228 if ((new->on_type & S_TYP) != (old->on_type & S_TYP))
229 warning("%s: sections differ", new->on_mptr);
231 if (new->on_valu > old->on_valu)
232 old->on_valu = new->on_valu;
240 * Transfer things we want to know from `src' to `dst'.
244 register struct outname *src, *dst;
246 debug("%s defined here\n", src->on_mptr, 0, 0, 0);
247 dst->on_valu = src->on_valu;
248 dst->on_type = src->on_type;
249 dst->on_desc = src->on_desc;