* struc-symbol.h (struct symbol): Add sy_mri_common bit.
[deliverable/binutils-gdb.git] / gas / frags.c
1 /* frags.c - manage frags -
2
3 Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "as.h"
22 #include "subsegs.h"
23 #include "obstack.h"
24
25 struct obstack frags; /* All, and only, frags live here. */
26
27 extern fragS zero_address_frag;
28 extern fragS bss_address_frag;
29 \f
30 /* Initialization for frag routines. */
31 void
32 frag_init ()
33 {
34 zero_address_frag.fr_type = rs_fill;
35 bss_address_frag.fr_type = rs_fill;
36 obstack_begin (&frags, 5000);
37 }
38 \f
39 /*
40 * frag_grow()
41 *
42 * Try to augment current frag by nchars chars.
43 * If there is no room, close of the current frag with a ".fill 0"
44 * and begin a new frag. Unless the new frag has nchars chars available
45 * do not return. Do not set up any fields of *now_frag.
46 */
47 void
48 frag_grow (nchars)
49 unsigned int nchars;
50 {
51 if (obstack_room (&frags) < nchars)
52 {
53 unsigned int n, oldn;
54 long oldc;
55
56 frag_wane (frag_now);
57 frag_new (0);
58 oldn = (unsigned) -1;
59 oldc = frags.chunk_size;
60 frags.chunk_size = 2 * nchars;
61 while ((n = obstack_room (&frags)) < nchars && n < oldn)
62 {
63 frag_wane (frag_now);
64 frag_new (0);
65 oldn = n;
66 }
67 frags.chunk_size = oldc;
68 }
69 if (obstack_room (&frags) < nchars)
70 as_fatal ("Can't extend frag %d. chars", nchars);
71 } /* frag_grow() */
72 \f
73 /*
74 * frag_new()
75 *
76 * Call this to close off a completed frag, and start up a new (empty)
77 * frag, in the same subsegment as the old frag.
78 * [frchain_now remains the same but frag_now is updated.]
79 * Because this calculates the correct value of fr_fix by
80 * looking at the obstack 'frags', it needs to know how many
81 * characters at the end of the old frag belong to (the maximal)
82 * fr_var: the rest must belong to fr_fix.
83 * It doesn't actually set up the old frag's fr_var: you may have
84 * set fr_var == 1, but allocated 10 chars to the end of the frag:
85 * in this case you pass old_frags_var_max_size == 10.
86 *
87 * Make a new frag, initialising some components. Link new frag at end
88 * of frchain_now.
89 */
90 void
91 frag_new (old_frags_var_max_size)
92 int old_frags_var_max_size;/* Number of chars (already allocated on
93 obstack frags) */
94 /* in variable_length part of frag. */
95 {
96 register fragS *former_last_fragP;
97 register frchainS *frchP;
98 long tmp;
99
100 frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
101 /* Fix up old frag's fr_fix. */
102
103 obstack_finish (&frags);
104 /* This will align the obstack so the next struct we allocate on it
105 will begin at a correct boundary. */
106 frchP = frchain_now;
107 know (frchP);
108 former_last_fragP = frchP->frch_last;
109 know (former_last_fragP);
110 know (former_last_fragP == frag_now);
111 obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
112 /* We expect this will begin at a correct boundary for a struct. */
113 tmp = obstack_alignment_mask (&frags);
114 obstack_alignment_mask (&frags) = 0; /* Turn off alignment */
115 /* If we ever hit a machine where strings must be aligned, we Lose
116 Big. */
117 frag_now = (fragS *) obstack_finish (&frags);
118 obstack_alignment_mask (&frags) = tmp; /* Restore alignment */
119
120 /* Just in case we don't get zero'd bytes */
121 memset (frag_now, '\0', SIZEOF_STRUCT_FRAG);
122
123 /* Generally, frag_now->points to an address rounded up to next
124 alignment. However, characters will add to obstack frags
125 IMMEDIATELY after the struct frag, even if they are not starting
126 at an alignment address. */
127 former_last_fragP->fr_next = frag_now;
128 frchP->frch_last = frag_now;
129
130 #ifndef NO_LISTING
131 {
132 extern struct list_info_struct *listing_tail;
133 frag_now->line = listing_tail;
134 }
135 #endif
136
137 frag_now->fr_next = NULL;
138 } /* frag_new() */
139 \f
140 /*
141 * frag_more()
142 *
143 * Start a new frag unless we have n more chars of room in the current frag.
144 * Close off the old frag with a .fill 0.
145 *
146 * Return the address of the 1st char to write into. Advance
147 * frag_now_growth past the new chars.
148 */
149
150 char *
151 frag_more (nchars)
152 int nchars;
153 {
154 register char *retval;
155
156 if (mri_common_symbol != NULL)
157 {
158 as_bad ("attempt to allocate data in common section");
159 mri_common_symbol = NULL;
160 }
161
162 frag_grow (nchars);
163 retval = obstack_next_free (&frags);
164 obstack_blank_fast (&frags, nchars);
165 return (retval);
166 } /* frag_more() */
167 \f
168 /*
169 * frag_var()
170 *
171 * Start a new frag unless we have max_chars more chars of room in the current frag.
172 * Close off the old frag with a .fill 0.
173 *
174 * Set up a machine_dependent relaxable frag, then start a new frag.
175 * Return the address of the 1st char of the var part of the old frag
176 * to write into.
177 */
178
179 char *
180 frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
181 relax_stateT type;
182 int max_chars;
183 int var;
184 relax_substateT subtype;
185 symbolS *symbol;
186 long offset;
187 char *opcode;
188 {
189 register char *retval;
190
191 frag_grow (max_chars);
192 retval = obstack_next_free (&frags);
193 obstack_blank_fast (&frags, max_chars);
194 frag_now->fr_var = var;
195 frag_now->fr_type = type;
196 frag_now->fr_subtype = subtype;
197 frag_now->fr_symbol = symbol;
198 frag_now->fr_offset = offset;
199 frag_now->fr_opcode = opcode;
200 /* default these to zero. */
201 frag_now->fr_pcrel_adjust = 0;
202 frag_now->fr_bsr = 0;
203 frag_new (max_chars);
204 return (retval);
205 }
206 \f
207 /*
208 * frag_variant()
209 *
210 * OVE: This variant of frag_var assumes that space for the tail has been
211 * allocated by caller.
212 * No call to frag_grow is done.
213 * Two new arguments have been added.
214 */
215
216 char *
217 frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
218 relax_stateT type;
219 int max_chars;
220 int var;
221 relax_substateT subtype;
222 symbolS *symbol;
223 long offset;
224 char *opcode;
225 {
226 register char *retval;
227
228 retval = obstack_next_free (&frags);
229 frag_now->fr_var = var;
230 frag_now->fr_type = type;
231 frag_now->fr_subtype = subtype;
232 frag_now->fr_symbol = symbol;
233 frag_now->fr_offset = offset;
234 frag_now->fr_opcode = opcode;
235 frag_now->fr_pcrel_adjust = 0;
236 frag_now->fr_bsr = 0;
237 frag_new (max_chars);
238 return (retval);
239 } /* frag_variant() */
240 \f
241 /*
242 * frag_wane()
243 *
244 * Reduce the variable end of a frag to a harmless state.
245 */
246 void
247 frag_wane (fragP)
248 register fragS *fragP;
249 {
250 fragP->fr_type = rs_fill;
251 fragP->fr_offset = 0;
252 fragP->fr_var = 0;
253 }
254 \f
255 /*
256 * frag_align()
257 *
258 * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);".
259 * Foo & bar are absolute integers.
260 *
261 * Call to close off the current frag with a ".align", then start a new
262 * (so far empty) frag, in the same subsegment as the last frag.
263 */
264
265 void
266 frag_align (alignment, fill_character)
267 int alignment;
268 int fill_character;
269 {
270 char *p;
271 p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
272 (symbolS *) 0, (long) alignment, (char *) 0);
273 *p = fill_character;
274 }
275
276 void
277 frag_align_pattern (alignment, fill_pattern, n_fill)
278 int alignment;
279 const char *fill_pattern;
280 int n_fill;
281 {
282 char *p;
283 p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) 0,
284 (symbolS *) 0, (long) alignment, (char *) 0);
285 memcpy (p, fill_pattern, n_fill);
286 }
287
288 int
289 frag_now_fix ()
290 {
291 return (char*)obstack_next_free (&frags) - frag_now->fr_literal;
292 }
293
294 void
295 frag_append_1_char (datum)
296 int datum;
297 {
298 if (obstack_room (&frags) <= 1)
299 {
300 frag_wane (frag_now);
301 frag_new (0);
302 }
303 obstack_1grow (&frags, datum);
304 }
305
306 /* end of frags.c */
This page took 0.040213 seconds and 5 git commands to generate.