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: finish.c,v 3.9 1994/06/24 10:34:44 ceriel Exp $";
17 extern unsigned short NLocals;
19 extern struct outname *searchname();
21 static adjust_names();
22 static handle_relos();
24 static compute_origins();
27 * We know all there is to know about the current module.
28 * Now we relocate the values in the emitted bytes and write
29 * those to the final output file. Then we compute the relative origins
30 * for the next module.
35 struct outsect *sects;
36 struct outname *names;
40 head = (struct outhead *)modulptr(IND_HEAD);
41 sects = (struct outsect *)modulptr(IND_SECT(*head));
42 names = (struct outname *)modulptr(IND_NAME(*head));
43 chars = (char *)modulptr(IND_CHAR(*head));
44 adjust_names(names, head, chars);
45 handle_relos(head, sects, names);
46 if (!incore && !(flagword & SFLAG)) {
47 put_locals(names, head->oh_nname);
49 put_dbug(OFF_DBUG(*head));
52 compute_origins(sects, head->oh_nsect);
57 * Adjust all local names for the move into core.
60 adjust_names(name, head, chars)
61 register struct outname *name;
66 register long charoff;
67 struct outname *base = name;
70 charoff = OFF_CHAR(*head);
72 if (name->on_foff != (long)0)
73 name->on_mptr = chars + (ind_t)(name->on_foff - charoff);
77 do_crs(base, head->oh_nname);
85 register struct outname *name = base;
88 if ((name->on_type & S_TYP) == S_CRS) {
92 s = address(ALLOGCHR, (ind_t) name->on_valu);
93 p = searchname(s, hash(s));
95 if (flagword & RFLAG) {
96 name->on_valu = NLocals + (p -
98 address(ALLOGLOB, (ind_t) 0));
101 name->on_valu = p->on_valu;
102 name->on_type &= ~S_TYP;
103 name->on_type |= (p->on_type & S_TYP);
111 * If all sections are in core, we can access them randomly, so we need only
112 * scan the relocation table once. Otherwise we must for each section scan
113 * the relocation table again, because the relocation entries of one section
114 * need not be consecutive.
117 handle_relos(head, sects, names)
118 struct outhead *head;
119 struct outsect *sects;
120 struct outname *names;
122 register struct outrelo *relo;
123 register int sectindex;
126 extern char *getemit();
127 extern struct outrelo *nextrelo();
128 static long zeros[MAXSECT];
131 nrelo = head->oh_nrelo; sectindex = -1;
132 startrelo(head); relo = nextrelo();
134 if (sectindex != relo->or_sect - S_MIN) {
135 sectindex = relo->or_sect - S_MIN;
136 emit = getemit(head, sects, sectindex);
138 relocate(head, emit, names, relo, 0L);
142 for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) {
143 if (sects[sectindex].os_flen) {
144 wrt_nulls(sectindex, zeros[sectindex]);
145 zeros[sectindex] = 0;
146 emit = getemit(head, sects, sectindex);
148 nrelo = head->oh_nrelo; startrelo(head);
151 if (relo->or_sect - S_MIN == sectindex) {
152 relocate(head,emit,names,relo,0L);
154 * Write out the (probably changed)
155 * relocation information.
157 if (flagword & (RFLAG|CFLAG))
161 wrt_emit(emit, sectindex,
162 sects[sectindex].os_flen);
165 long sz = sects[sectindex].os_flen;
170 emit = getblk(sz, &blksz, sectindex);
172 long sz2 = sz > blksz ? blksz : sz;
175 nrelo = head->oh_nrelo; startrelo(head);
178 if (relo->or_sect-S_MIN==sectindex
182 relo->or_addr < sf + sz2){
183 relocate(head,emit,names,relo,
186 * Write out the (probably changed)
187 * relocation information.
189 if (flagword & (RFLAG|CFLAG))
193 wrt_emit(emit, sectindex, sz2);
200 zeros[sectindex] += sects[sectindex].os_size -
201 sects[sectindex].os_flen;
207 * Write out the local names that must be saved.
210 put_locals(name, nnames)
211 struct outname *name;
212 register unsigned nnames;
214 register struct outname *oname = name;
215 register struct outname *iname = oname;
218 if ((iname->on_type & S_EXT) == 0 && mustsavelocal(iname)) {
226 wr_name(name, (unsigned int) (oname - name));
230 * Add all flen's and all (size - flen == zero)'s of preceding sections
231 * with the same number.
234 compute_origins(sect, nsect)
235 register struct outsect *sect;
236 register unsigned nsect;
238 extern struct orig relorig[];
239 register struct orig *orig = relorig;
243 orig->org_size += sect->os_size;
250 * Write out what is after the string area. This is likely to be
251 * debugging information.
259 register long dbugsize;
260 extern long objectsize;
262 dbugsize = objectsize - offdbug;
264 nbytes = dbugsize > 512 ? 512 : dbugsize;
265 rd_dbug(buf, (long)nbytes);
266 wr_dbug(buf, (long) nbytes);