File: | src/gnu/usr.bin/binutils-2.17/gas/frags.c |
Warning: | line 103, column 10 Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* frags.c - manage frags - |
2 | Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3 | 1999, 2000, 2001, 2003, 2004, 2005, 2006 |
4 | Free Software Foundation, Inc. |
5 | |
6 | This file is part of GAS, the GNU Assembler. |
7 | |
8 | GAS is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2, or (at your option) |
11 | any later version. |
12 | |
13 | GAS is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with GAS; see the file COPYING. If not, write to the Free |
20 | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
21 | 02110-1301, USA. */ |
22 | |
23 | #include "as.h" |
24 | #include "subsegs.h" |
25 | #include "obstack.h" |
26 | |
27 | extern fragS zero_address_frag; |
28 | extern fragS bss_address_frag; |
29 | |
30 | /* Initialization for frag routines. */ |
31 | |
32 | void |
33 | frag_init (void) |
34 | { |
35 | zero_address_frag.fr_type = rs_fill; |
36 | bss_address_frag.fr_type = rs_fill; |
37 | } |
38 | |
39 | /* Check that we're not trying to assemble into a section that can't |
40 | allocate frags (currently, this is only possible in the absolute |
41 | section), or into an mri common. */ |
42 | |
43 | static void |
44 | frag_alloc_check (const struct obstack *ob) |
45 | { |
46 | if (ob->chunk_size == 0) |
47 | { |
48 | as_bad (_("attempt to allocate data in absolute section")("attempt to allocate data in absolute section")); |
49 | subseg_set (text_section, 0); |
50 | } |
51 | |
52 | if (mri_common_symbol != NULL((void*)0)) |
53 | { |
54 | as_bad (_("attempt to allocate data in common section")("attempt to allocate data in common section")); |
55 | mri_common_symbol = NULL((void*)0); |
56 | } |
57 | } |
58 | |
59 | /* Allocate a frag on the specified obstack. |
60 | Call this routine from everywhere else, so that all the weird alignment |
61 | hackery can be done in just one place. */ |
62 | |
63 | fragS * |
64 | frag_alloc (struct obstack *ob) |
65 | { |
66 | fragS *ptr; |
67 | int oalign; |
68 | |
69 | (void) obstack_alloc (ob, 0)__extension__ ({ struct obstack *__h = (ob); __extension__ ({ struct obstack *__o = (__h); int __len = ((0)); if (__o-> chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }); |
70 | oalign = obstack_alignment_mask (ob)((ob)->alignment_mask); |
71 | obstack_alignment_mask (ob)((ob)->alignment_mask) = 0; |
72 | ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG)__extension__ ({ struct obstack *__h = (ob); __extension__ ({ struct obstack *__o = (__h); int __len = ((((char *) zero_address_frag .fr_literal - (char *) &zero_address_frag))); if (__o-> chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }); |
73 | obstack_alignment_mask (ob)((ob)->alignment_mask) = oalign; |
74 | memset (ptr, 0, SIZEOF_STRUCT_FRAG((char *) zero_address_frag.fr_literal - (char *) &zero_address_frag )); |
75 | return ptr; |
76 | } |
77 | |
78 | /* Try to augment current frag by nchars chars. |
79 | If there is no room, close of the current frag with a ".fill 0" |
80 | and begin a new frag. Unless the new frag has nchars chars available |
81 | do not return. Do not set up any fields of *now_frag. */ |
82 | |
83 | void |
84 | frag_grow (unsigned int nchars) |
85 | { |
86 | if (obstack_room (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); (unsigned) (__o->chunk_limit - __o->next_free ); }) < nchars) |
87 | { |
88 | unsigned int n; |
89 | long oldc; |
90 | |
91 | frag_wane (frag_now); |
92 | frag_new (0); |
93 | oldc = frchain_now->frch_obstack.chunk_size; |
94 | /* Try to allocate a bit more than needed right now. But don't do |
95 | this if we would waste too much memory. Especially necessary |
96 | for extremely big (like 2GB initialized) frags. */ |
97 | if (nchars < 0x10000) |
98 | frchain_now->frch_obstack.chunk_size = 2 * nchars; |
99 | else |
100 | frchain_now->frch_obstack.chunk_size = nchars + 0x10000; |
101 | frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG((char *) zero_address_frag.fr_literal - (char *) &zero_address_frag ); |
102 | if (frchain_now->frch_obstack.chunk_size > 0) |
103 | while ((n = obstack_room (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); (unsigned) (__o->chunk_limit - __o->next_free ); })) < nchars |
Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n' | |
104 | && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars) |
105 | { |
106 | frag_wane (frag_now); |
107 | frag_new (0); |
108 | } |
109 | frchain_now->frch_obstack.chunk_size = oldc; |
110 | } |
111 | if (obstack_room (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); (unsigned) (__o->chunk_limit - __o->next_free ); }) < nchars) |
112 | as_fatal (_("can't extend frag %u chars")("can't extend frag %u chars"), nchars); |
113 | } |
114 | |
115 | /* Call this to close off a completed frag, and start up a new (empty) |
116 | frag, in the same subsegment as the old frag. |
117 | [frchain_now remains the same but frag_now is updated.] |
118 | Because this calculates the correct value of fr_fix by |
119 | looking at the obstack 'frags', it needs to know how many |
120 | characters at the end of the old frag belong to the maximal |
121 | variable part; The rest must belong to fr_fix. |
122 | It doesn't actually set up the old frag's fr_var. You may have |
123 | set fr_var == 1, but allocated 10 chars to the end of the frag; |
124 | In this case you pass old_frags_var_max_size == 10. |
125 | In fact, you may use fr_var for something totally unrelated to the |
126 | size of the variable part of the frag; None of the generic frag |
127 | handling code makes use of fr_var. |
128 | |
129 | Make a new frag, initialising some components. Link new frag at end |
130 | of frchain_now. */ |
131 | |
132 | void |
133 | frag_new (int old_frags_var_max_size |
134 | /* Number of chars (already allocated on obstack frags) in |
135 | variable_length part of frag. */) |
136 | { |
137 | fragS *former_last_fragP; |
138 | frchainS *frchP; |
139 | |
140 | assert (frchain_now->frch_last == frag_now)((void) ((frchain_now->frch_last == frag_now) ? 0 : (as_assert ("/usr/src/gnu/usr.bin/binutils-2.17/gas/frags.c", 140, __PRETTY_FUNCTION__ ), 0))); |
141 | |
142 | /* Fix up old frag's fr_fix. */ |
143 | frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size; |
144 | /* Make sure its type is valid. */ |
145 | assert (frag_now->fr_type != 0)((void) ((frag_now->fr_type != 0) ? 0 : (as_assert ("/usr/src/gnu/usr.bin/binutils-2.17/gas/frags.c" , 145, __PRETTY_FUNCTION__), 0))); |
146 | |
147 | /* This will align the obstack so the next struct we allocate on it |
148 | will begin at a correct boundary. */ |
149 | obstack_finish (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o1 = (&frchain_now-> frch_obstack); void *value; value = (void *) __o1->object_base ; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char * ) 0)+__o1->alignment_mask) & ~ (__o1->alignment_mask )) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; value; }); |
150 | frchP = frchain_now; |
151 | know (frchP); |
152 | former_last_fragP = frchP->frch_last; |
153 | assert (former_last_fragP != 0)((void) ((former_last_fragP != 0) ? 0 : (as_assert ("/usr/src/gnu/usr.bin/binutils-2.17/gas/frags.c" , 153, __PRETTY_FUNCTION__), 0))); |
154 | assert (former_last_fragP == frag_now)((void) ((former_last_fragP == frag_now) ? 0 : (as_assert ("/usr/src/gnu/usr.bin/binutils-2.17/gas/frags.c" , 154, __PRETTY_FUNCTION__), 0))); |
155 | frag_now = frag_alloc (&frchP->frch_obstack); |
156 | |
157 | as_where (&frag_now->fr_file, &frag_now->fr_line); |
158 | |
159 | /* Generally, frag_now->points to an address rounded up to next |
160 | alignment. However, characters will add to obstack frags |
161 | IMMEDIATELY after the struct frag, even if they are not starting |
162 | at an alignment address. */ |
163 | former_last_fragP->fr_next = frag_now; |
164 | frchP->frch_last = frag_now; |
165 | |
166 | #ifndef NO_LISTING |
167 | { |
168 | extern struct list_info_struct *listing_tail; |
169 | frag_now->line = listing_tail; |
170 | } |
171 | #endif |
172 | |
173 | assert (frchain_now->frch_last == frag_now)((void) ((frchain_now->frch_last == frag_now) ? 0 : (as_assert ("/usr/src/gnu/usr.bin/binutils-2.17/gas/frags.c", 173, __PRETTY_FUNCTION__ ), 0))); |
174 | |
175 | frag_now->fr_next = NULL((void*)0); |
176 | } |
177 | |
178 | /* Start a new frag unless we have n more chars of room in the current frag. |
179 | Close off the old frag with a .fill 0. |
180 | |
181 | Return the address of the 1st char to write into. Advance |
182 | frag_now_growth past the new chars. */ |
183 | |
184 | char * |
185 | frag_more (int nchars) |
186 | { |
187 | register char *retval; |
188 | |
189 | frag_alloc_check (&frchain_now->frch_obstack); |
190 | frag_grow (nchars); |
191 | retval = obstack_next_free (&frchain_now->frch_obstack)((&frchain_now->frch_obstack)->next_free); |
192 | obstack_blank_fast (&frchain_now->frch_obstack, nchars)((&frchain_now->frch_obstack)->next_free += (nchars )); |
193 | return (retval); |
194 | } |
195 | |
196 | /* Start a new frag unless we have max_chars more chars of room in the |
197 | current frag. Close off the old frag with a .fill 0. |
198 | |
199 | Set up a machine_dependent relaxable frag, then start a new frag. |
200 | Return the address of the 1st char of the var part of the old frag |
201 | to write into. */ |
202 | |
203 | char * |
204 | frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype, |
205 | symbolS *symbol, offsetT offset, char *opcode) |
206 | { |
207 | register char *retval; |
208 | |
209 | frag_grow (max_chars); |
210 | retval = obstack_next_free (&frchain_now->frch_obstack)((&frchain_now->frch_obstack)->next_free); |
211 | obstack_blank_fast (&frchain_now->frch_obstack, max_chars)((&frchain_now->frch_obstack)->next_free += (max_chars )); |
212 | frag_now->fr_var = var; |
213 | frag_now->fr_type = type; |
214 | frag_now->fr_subtype = subtype; |
215 | frag_now->fr_symbol = symbol; |
216 | frag_now->fr_offset = offset; |
217 | frag_now->fr_opcode = opcode; |
218 | #ifdef USING_CGEN |
219 | frag_now->fr_cgen.insn = 0; |
220 | frag_now->fr_cgen.opindex = 0; |
221 | frag_now->fr_cgen.opinfo = 0; |
222 | #endif |
223 | #ifdef TC_FRAG_INIT |
224 | TC_FRAG_INIT (frag_now); |
225 | #endif |
226 | as_where (&frag_now->fr_file, &frag_now->fr_line); |
227 | frag_new (max_chars); |
228 | return (retval); |
229 | } |
230 | |
231 | /* OVE: This variant of frag_var assumes that space for the tail has been |
232 | allocated by caller. |
233 | No call to frag_grow is done. */ |
234 | |
235 | char * |
236 | frag_variant (relax_stateT type, int max_chars, int var, |
237 | relax_substateT subtype, symbolS *symbol, offsetT offset, |
238 | char *opcode) |
239 | { |
240 | register char *retval; |
241 | |
242 | retval = obstack_next_free (&frchain_now->frch_obstack)((&frchain_now->frch_obstack)->next_free); |
243 | frag_now->fr_var = var; |
244 | frag_now->fr_type = type; |
245 | frag_now->fr_subtype = subtype; |
246 | frag_now->fr_symbol = symbol; |
247 | frag_now->fr_offset = offset; |
248 | frag_now->fr_opcode = opcode; |
249 | #ifdef USING_CGEN |
250 | frag_now->fr_cgen.insn = 0; |
251 | frag_now->fr_cgen.opindex = 0; |
252 | frag_now->fr_cgen.opinfo = 0; |
253 | #endif |
254 | #ifdef TC_FRAG_INIT |
255 | TC_FRAG_INIT (frag_now); |
256 | #endif |
257 | as_where (&frag_now->fr_file, &frag_now->fr_line); |
258 | frag_new (max_chars); |
259 | return (retval); |
260 | } |
261 | |
262 | /* Reduce the variable end of a frag to a harmless state. */ |
263 | |
264 | void |
265 | frag_wane (register fragS *fragP) |
266 | { |
267 | fragP->fr_type = rs_fill; |
268 | fragP->fr_offset = 0; |
269 | fragP->fr_var = 0; |
270 | } |
271 | |
272 | /* Return the number of bytes by which the current frag can be grown. */ |
273 | |
274 | int |
275 | frag_room (void) |
276 | { |
277 | return obstack_room (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); (unsigned) (__o->chunk_limit - __o->next_free ); }); |
278 | } |
279 | |
280 | /* Make an alignment frag. The size of this frag will be adjusted to |
281 | force the next frag to have the appropriate alignment. ALIGNMENT |
282 | is the power of two to which to align. FILL_CHARACTER is the |
283 | character to use to fill in any bytes which are skipped. MAX is |
284 | the maximum number of characters to skip when doing the alignment, |
285 | or 0 if there is no maximum. */ |
286 | |
287 | void |
288 | frag_align (int alignment, int fill_character, int max) |
289 | { |
290 | if (now_seg == absolute_section((asection *) &bfd_abs_section)) |
291 | { |
292 | addressT new_off; |
293 | addressT mask; |
294 | |
295 | mask = (~(addressT) 0) << alignment; |
296 | new_off = (abs_section_offset + ~mask) & mask; |
297 | if (max == 0 || new_off - abs_section_offset <= (addressT) max) |
298 | abs_section_offset = new_off; |
299 | } |
300 | else |
301 | { |
302 | char *p; |
303 | |
304 | p = frag_var (rs_align, 1, 1, (relax_substateT) max, |
305 | (symbolS *) 0, (offsetT) alignment, (char *) 0); |
306 | *p = fill_character; |
307 | } |
308 | } |
309 | |
310 | /* Make an alignment frag like frag_align, but fill with a repeating |
311 | pattern rather than a single byte. ALIGNMENT is the power of two |
312 | to which to align. FILL_PATTERN is the fill pattern to repeat in |
313 | the bytes which are skipped. N_FILL is the number of bytes in |
314 | FILL_PATTERN. MAX is the maximum number of characters to skip when |
315 | doing the alignment, or 0 if there is no maximum. */ |
316 | |
317 | void |
318 | frag_align_pattern (int alignment, const char *fill_pattern, |
319 | int n_fill, int max) |
320 | { |
321 | char *p; |
322 | |
323 | p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max, |
324 | (symbolS *) 0, (offsetT) alignment, (char *) 0); |
325 | memcpy (p, fill_pattern, n_fill); |
326 | } |
327 | |
328 | /* The NOP_OPCODE is for the alignment fill value. Fill it with a nop |
329 | instruction so that the disassembler does not choke on it. */ |
330 | #ifndef NOP_OPCODE(char) 0x90 |
331 | #define NOP_OPCODE(char) 0x90 0x00 |
332 | #endif |
333 | |
334 | /* Use this to restrict the amount of memory allocated for representing |
335 | the alignment code. Needs to be large enough to hold any fixed sized |
336 | prologue plus the replicating portion. */ |
337 | #ifndef MAX_MEM_FOR_RS_ALIGN_CODE15 |
338 | /* Assume that if HANDLE_ALIGN is not defined then no special action |
339 | is required to code fill, which means that we get just repeat the |
340 | one NOP_OPCODE byte. */ |
341 | # ifndef HANDLE_ALIGN |
342 | # define MAX_MEM_FOR_RS_ALIGN_CODE15 1 |
343 | # else |
344 | # define MAX_MEM_FOR_RS_ALIGN_CODE15 ((1 << alignment) - 1) |
345 | # endif |
346 | #endif |
347 | |
348 | void |
349 | frag_align_code (int alignment, int max) |
350 | { |
351 | char *p; |
352 | |
353 | p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE15, 1, |
354 | (relax_substateT) max, (symbolS *) 0, |
355 | (offsetT) alignment, (char *) 0); |
356 | *p = NOP_OPCODE(char) 0x90; |
357 | } |
358 | |
359 | addressT |
360 | frag_now_fix_octets (void) |
361 | { |
362 | if (now_seg == absolute_section((asection *) &bfd_abs_section)) |
363 | return abs_section_offset; |
364 | |
365 | return ((char *) obstack_next_free (&frchain_now->frch_obstack)((&frchain_now->frch_obstack)->next_free) |
366 | - frag_now->fr_literal); |
367 | } |
368 | |
369 | addressT |
370 | frag_now_fix (void) |
371 | { |
372 | return frag_now_fix_octets () / OCTETS_PER_BYTE(1<<0); |
373 | } |
374 | |
375 | void |
376 | frag_append_1_char (int datum) |
377 | { |
378 | frag_alloc_check (&frchain_now->frch_obstack); |
379 | if (obstack_room (&frchain_now->frch_obstack)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); (unsigned) (__o->chunk_limit - __o->next_free ); }) <= 1) |
380 | { |
381 | frag_wane (frag_now); |
382 | frag_new (0); |
383 | } |
384 | obstack_1grow (&frchain_now->frch_obstack, datum)__extension__ ({ struct obstack *__o = (&frchain_now-> frch_obstack); if (__o->next_free + 1 > __o->chunk_limit ) _obstack_newchunk (__o, 1); (*((__o)->next_free)++ = (datum )); (void) 0; }); |
385 | } |
386 | |
387 | /* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between |
388 | their start addresses. Set OFFSET to the difference in address |
389 | not already accounted for in the frag FR_ADDRESS. */ |
390 | |
391 | bfd_boolean |
392 | frag_offset_fixed_p (fragS *frag1, fragS *frag2, bfd_vma *offset) |
393 | { |
394 | fragS *frag; |
395 | bfd_vma off; |
396 | |
397 | /* Start with offset initialised to difference between the two frags. |
398 | Prior to assigning frag addresses this will be zero. */ |
399 | off = frag1->fr_address - frag2->fr_address; |
400 | if (frag1 == frag2) |
401 | { |
402 | *offset = off; |
403 | return TRUE1; |
404 | } |
405 | |
406 | /* Maybe frag2 is after frag1. */ |
407 | frag = frag1; |
408 | while (frag->fr_type == rs_fill) |
409 | { |
410 | off += frag->fr_fix + frag->fr_offset * frag->fr_var; |
411 | frag = frag->fr_next; |
412 | if (frag == NULL((void*)0)) |
413 | break; |
414 | if (frag == frag2) |
415 | { |
416 | *offset = off; |
417 | return TRUE1; |
418 | } |
419 | } |
420 | |
421 | /* Maybe frag1 is after frag2. */ |
422 | off = frag1->fr_address - frag2->fr_address; |
423 | frag = frag2; |
424 | while (frag->fr_type == rs_fill) |
425 | { |
426 | off -= frag->fr_fix + frag->fr_offset * frag->fr_var; |
427 | frag = frag->fr_next; |
428 | if (frag == NULL((void*)0)) |
429 | break; |
430 | if (frag == frag1) |
431 | { |
432 | *offset = off; |
433 | return TRUE1; |
434 | } |
435 | } |
436 | |
437 | return FALSE0; |
438 | } |