1 /* $Id: comm6.c,v 2.23 1994/06/24 13:22:11 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
8 * implement pseudo instructions
22 else if ((typ & S_VAR) && (typ & S_TYP) != S_ABS)
25 else if (pass == PASS_1 && typ == S_UND)
27 else if (pass == PASS_2 && (ip->i_type & S_TYP) == S_UND)
29 #endif /* THREE_PASS */
31 serror("illegal equate");
33 assert((ip->i_type & S_TYP) == (typ & S_TYP));
42 static char genlab[] = GENLAB;
46 /* printf("declare %s: %o\n", ip->i_name, typ); */
47 if (ip->i_type & ~S_EXT)
48 serror("multiple declared");
56 if (ip->i_type & S_EXT)
61 flag = SYM_EXT|SYM_LOC; /* S_EXT not stable in PASS_1 */
62 #endif /* THREE_PASS */
64 if (!(flag & SYM_EXT) &&
65 strncmp(ip->i_name, genlab, sizeof(genlab)-1) == 0)
71 ip->i_type & (S_EXT|S_TYP),
82 register ADDR_T oldval = ip->i_valu;
90 if (store(ip, (valu_t) DOTVAL) == 0)
93 assert(pass != PASS_2 || oldval - (ADDR_T) ip->i_valu == DOTGAIN);
101 register sect_t *sp = NULL;
103 typ = ip->i_type & S_TYP;
108 assert(pass == PASS_1);
110 typ = outhead.oh_nsect + S_MIN;
112 if (outhead.oh_nsect > SECTMAX || typ > S_MAX)
113 fatal("too many sections");
114 sp = §[typ - S_MIN];
116 sp->s_lign = ALIGNSECT;
120 ip->i_type = typ | S_EXT;
123 } else if (typ >= S_MIN) {
124 sp = §[typ - S_MIN];
125 if (sp->s_item != ip)
129 serror("multiple declared");
141 if ((sp = DOTSCT) == NULL)
143 if (sp->s_flag & BASED)
144 serror("already based");
149 warning(".base ignored");
154 * NOTE: A rather different solution is used for ASLD and not ASLD:
155 * ASLD, or local commons:
156 * - maximum length of .comm is recorded in i_valu during PASS_1
157 * - address of .comm is recorded in i_valu in later passes:
158 * assigned at end of PASS_1, corrected for s_gain at end of PASS_2
160 * - maximum length of .comm is recorded in i_valu during PASS_1
161 * - i_valu is used for relocation info during PASS_3
167 if (pass == PASS_1) {
172 /* printf("declare %s: %o\n", ip->i_name, DOTTYP); */
173 if ((ip->i_type & ~S_EXT) == S_UND) {
175 ip->i_type = S_COM|DOTTYP|(ip->i_type&S_EXT);
178 } else if (ip->i_type == (S_COM|DOTTYP|(ip->i_type&S_EXT))) {
179 if (ip->i_valu < val)
182 serror("multiple declared");
192 sp->s_size = DOTVAL - sp->s_base;
193 if (newtyp == S_UND) {
198 assert(newtyp >= S_MIN);
199 sp = §[newtyp - S_MIN];
200 DOTVAL = sp->s_size + sp->s_base;
211 if ((sp = DOTSCT) == NULL)
215 if (sp->s_lign % bytes)
216 if (bytes % sp->s_lign)
217 serror("illegal alignment");
222 * be pessimistic: biggest gap possible
227 * calculate gap correctly;
228 * will be the same in PASS_2 and PASS_3
230 if ((gap = DOTVAL % bytes) != 0)
235 * keep track of gain with respect to PASS_1
237 DOTGAIN += (bytes - 1) - gap;
248 struct outrelo outrelo;
255 assert((s & ~(S_COM|S_VAR|S_TYP)) == 0);
259 serror("bad relocation");
263 * always relocation info if S_VAR to solve problems with:
267 * but no relocation info if S_VAR is set, but type is S_ABS.
271 if ((n & RELPC) == 0 && ((s & ~S_VAR) == S_ABS))
273 if ((n & RELPC) != 0 && s == DOTTYP
279 if (pass != PASS_3) {
284 outrelo.or_type = (char)n;
285 outrelo.or_sect = (char)DOTTYP;
287 if (s == S_UND || iscomm) {
288 assert(relonami != 0);
289 outrelo.or_nami = relonami-1;
296 * use first non existing entry (argh)
298 outrelo.or_nami = outhead.oh_nname;
301 * section symbols are at the end
303 outrelo.or_nami = outhead.oh_nname
308 outrelo.or_addr = (long)DOTVAL;
309 wr_relo(&outrelo, 1);
320 long len = strlen(s) + 1;
322 r = outhead.oh_nchar;
323 if (pass == PASS_3) wr_string(s, len);
324 outhead.oh_nchar += len;
329 newsymb(name, type, desc, valu)
333 struct outname outname;
335 if (name && *name == 0)
338 if (pass != PASS_3) {
344 outname.on_foff = new_string(name);
345 outname.on_type = type;
346 outname.on_desc = desc;
347 outname.on_valu = valu;
348 if (sizeof(valu) != sizeof(long))
349 outname.on_valu &= ~(((0xFFFFFFFF)<<(4*sizeof(valu_t)))<<(4*sizeof(valu_t)));
350 wr_name(&outname, 1);
356 register struct common_t *cp;
358 static struct common_t *next;
361 next = (struct common_t *) malloc(MEMINCR);
363 fatal("out of memory");
365 nleft += (MEMINCR / sizeof (struct common_t));
368 cp->c_next = commons;