1/* frags.c - manage frags - 2 Copyright (C) 1987 Free Software Foundation, Inc. 3 4This file is part of GAS, the GNU Assembler. 5 6GAS is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 1, or (at your option) 9any later version. 10 11GAS is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GAS; see the file COPYING. If not, write to 18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20#include <string.h> 21#include "as.h" 22#include "sections.h" 23#include "obstack.h" 24#include "frags.h" 25#include "messages.h" 26#include "input-scrub.h" 27 28struct obstack frags = { 0 }; /* All, and only, frags live here. */ 29 30fragS *frag_now = NULL; /* -> current frag we are building. */ 31 32fragS zero_address_frag = { 33 0, /* fr_address */ 34 0, /* last_fr_address */ 35 NULL, /* fr_next */ 36 0, /* fr_fix */ 37 0, /* fr_var */ 38 0, /* fr_symbol */ 39 0, /* fr_offset */ 40 NULL, /* fr_opcode */ 41 rs_fill, /* fr_type */ 42 0, /* fr_subtype */ 43#ifdef ARM 44 0 /* fr_literal [0] */ 45#else 46 {0} /* fr_literal [0] */ 47#endif 48}; 49 50 51/* 52 * frag_grow() 53 * 54 * Try to augment current frag by nchars chars. 55 * If there is no room, close of the current frag with a ".fill 0" 56 * and begin a new frag. Unless the new frag has nchars chars available 57 * do not return. Do not set up any fields of *now_frag. 58 */ 59void 60frag_grow( 61unsigned int nchars) 62{ 63 if(frags.chunk_size == 0){ 64 know(flagseen['n']); 65 as_fatal("with -n a section directive must be seen before assembly " 66 "can begin"); 67 } 68 if ((int)(obstack_room(&frags)) < nchars) { 69 unsigned int n,oldn; 70 int32_t oldc; 71 72 frag_wane (frag_now); 73 frag_new (0); 74 oldn=(unsigned)-1; 75 oldc=frags.chunk_size; 76 if(2*nchars > oldc) 77 frags.chunk_size=2*nchars; 78 while((int)(n=obstack_room(&frags)) < nchars && n < oldn) { 79 frag_wane(frag_now); 80 frag_new(0); 81 oldn=n; 82 } 83 frags.chunk_size=oldc; 84 } 85 if ((int)(obstack_room(&frags)) < nchars) 86 as_fatal ("Can't extend frag %d. chars", nchars); 87} 88 89/* 90 * frag_new() 91 * 92 * Call this to close off a completed frag, and start up a new (empty) 93 * frag, in the same subsegment as the old frag. 94 * [frchain_now remains the same but frag_now is updated.] 95 * Because this calculates the correct value of fr_fix by 96 * looking at the obstack 'frags', it needs to know how many 97 * characters at the end of the old frag belong to (the maximal) 98 * fr_var: the rest must belong to fr_fix. 99 * It doesn't actually set up the old frag's fr_var: you may have 100 * set fr_var == 1, but allocated 10 chars to the end of the frag: 101 * in this case you pass old_frags_var_max_size == 10. 102 * 103 * Make a new frag, initialising some components. Link new frag at end 104 * of frchain_now. 105 */ 106void 107frag_new( 108int old_frags_var_max_size) /* Number of chars (already allocated on obstack 109 frags) in variable_length part of frag. */ 110{ 111 register fragS * former_last_fragP; 112/* char *throw_away_pointer; JF unused */ 113 register frchainS * frchP; 114 int32_t tmp; /* JF */ 115 116 if(frags.chunk_size == 0){ 117 know(flagseen['n']); 118 as_fatal("with -n a section directive must be seen before assembly " 119 "can begin"); 120 } 121 122 frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - 123 (frag_now->fr_literal) - old_frags_var_max_size; 124 /* Fix up old frag's fr_fix. */ 125 126 (void)obstack_finish (&frags); 127 /* This will align the obstack so the */ 128 /* next struct we allocate on it will */ 129 /* begin at a correct boundary. */ 130 frchP = frchain_now; 131 know (frchP); 132 former_last_fragP = frchP->frch_last; 133 know (former_last_fragP); 134 know (former_last_fragP == frag_now); 135 obstack_blank (&frags, SIZEOF_STRUCT_FRAG); 136 /* We expect this will begin at a correct */ 137 /* boundary for a struct. */ 138 tmp=obstack_alignment_mask(&frags); 139 obstack_alignment_mask(&frags)=0; /* Turn off alignment */ 140 /* If we ever hit a machine 141 where strings must be 142 aligned, we Lose Big */ 143 frag_now=(fragS *)obstack_finish(&frags); 144 obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ 145 146 /* Just in case we don't get zero'd bytes */ 147 memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); 148 149/* obstack_unaligned_done (&frags, &frag_now); */ 150/* know (frags.obstack_c_next_free == frag_now->fr_literal); */ 151 /* Generally, frag_now->points to an */ 152 /* address rounded up to next alignment. */ 153 /* However, characters will add to obstack */ 154 /* frags IMMEDIATELY after the struct frag, */ 155 /* even if they are not starting at an */ 156 /* alignment address. */ 157 former_last_fragP->fr_next = frag_now; 158 frchP->frch_last = frag_now; 159 frag_now->fr_next = NULL; 160} /* frag_new() */ 161 162/* 163 * frag_more() 164 * 165 * Start a new frag unless we have n more chars of room in the current frag. 166 * Close off the old frag with a .fill 0. 167 * 168 * Return the address of the 1st char to write into. Advance 169 * frag_now_growth past the new chars. 170 */ 171char * 172frag_more( 173int nchars) 174{ 175 register char *retval; 176 177 frag_grow (nchars); 178 retval = obstack_next_free (&frags); 179 obstack_blank_fast (&frags, nchars); 180 return (retval); 181} /* frag_more() */ 182 183/* 184 * frag_var() 185 * 186 * Start a new frag unless we have max_chars more chars of room in the current frag. 187 * Close off the old frag with a .fill 0. 188 * 189 * Set up a machine_dependent relaxable frag, then start a new frag. 190 * Return the address of the 1st char of the var part of the old frag 191 * to write into. 192 */ 193char * 194frag_var( 195relax_stateT type, 196int max_chars, 197int var, 198relax_substateT subtype, 199symbolS *symbol, 200int32_t offset, 201char *opcode) 202{ 203 register char *retval; 204 205#ifdef ARM 206 as_file_and_line (&frag_now->fr_file, &frag_now->fr_line); 207#endif /* ARM */ 208 frag_grow (max_chars); 209 retval = obstack_next_free (&frags); 210 obstack_blank_fast (&frags, max_chars); 211 frag_now->fr_var = var; 212 frag_now->fr_type = type; 213 frag_now->fr_subtype = subtype; 214 frag_now->fr_symbol = symbol; 215 frag_now->fr_offset = offset; 216 frag_now->fr_opcode = opcode; 217 frag_new (max_chars); 218#ifdef ARM 219 as_file_and_line (&frag_now->fr_file, &frag_now->fr_line); 220#endif /* ARM */ 221 return (retval); 222} /* frag_var() */ 223 224/* 225 * frag_wane() 226 * 227 * Reduce the variable end of a frag to a harmless state. 228 */ 229void 230frag_wane( 231fragS *fragP) 232{ 233 fragP->fr_type = rs_fill; 234 fragP->fr_offset = 0; 235 fragP->fr_var = 0; 236} 237 238/* 239 * frag_align() 240 * 241 * Make an rs_align frag for: 242 * .align power_of_2_alignment, fill_expression, fill_size, max_bytes_to_fill 243 * the fill_size must be 1, 2 or 4. An rs_align frag stores the 244 * power_of_2_alignment in the fr_offset field of the frag, the fill_expression 245 * in the fr_literal bytes, the fill_size in the fr_var field and the 246 * max_bytes_to_fill in the fr_subtype field. We call frag_var() with max_chars 247 * parameter large enough to hold the fill_expression of fill_size plus the 248 * maximum number of partial bytes that may be needed to be zeroed before the 249 * fill. 250 * 251 * Call to close off the current frag with a ".align", then start a new 252 * (so far empty) frag, in the same subsegment as the last frag. 253 */ 254void 255frag_align( 256int power_of_2_alignment, 257char *fill, 258int fill_size, 259int max_bytes_to_fill) 260{ 261 void *fr_literal; 262 int max_chars; 263#ifdef I386 264 /* 265 * For x86 architecures in sections containing only instuctions being 266 * padded with nops that are aligned to 16 bytes or less and are 267 * assembled -dynamic we will actually end up padding with the optimal 268 * nop sequence. So for that make sure there is the maximum number of 269 * bytes allocated in the frag to use for this. 270 */ 271 if((frchain_now->frch_section.flags & S_ATTR_PURE_INSTRUCTIONS) != 0 && 272 fill_size == 1 && *fill == (char)0x90 && flagseen['k'] == TRUE){ 273 if(power_of_2_alignment > 4) 274 max_chars = 15; 275 else 276 max_chars = (1 << power_of_2_alignment) - 1; 277 } 278 else 279#endif /* 386 */ 280 max_chars = fill_size + (fill_size - 1); 281 282 fr_literal = (void *) 283 frag_var(rs_align, /* type */ 284 max_chars, /* max_chars */ 285 fill_size, /* var */ 286 (relax_substateT)max_bytes_to_fill,/* subtype */ 287 (symbolS *)0, /* symbol */ 288 (int32_t)power_of_2_alignment, /* offset */ 289 (char *)0); /* opcode */ 290 if(fill_size == 1 || fill_size == 2 || fill_size == 4) 291 memcpy(fr_literal, fill, fill_size); 292 else 293 as_bad("Invalid width for fill expression."); 294} 295 296addressT 297frag_now_fix_octets (void) 298{ 299#ifdef NeXT_MOD 300 return ((char *) obstack_next_free (&frags) 301 - frag_now->fr_literal); 302#else 303 if (now_seg == absolute_section) 304 return abs_section_offset; 305 306 return ((char *) obstack_next_free (&frchain_now->frch_obstack) 307 - frag_now->fr_literal); 308#endif 309} 310 311addressT 312frag_now_fix (void) 313{ 314 return frag_now_fix_octets () / OCTETS_PER_BYTE; 315} 316 317/* end: frags.c */ 318