|
|
1.1 ! root 1: /* frags.c - manage frags - ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GAS, the GNU Assembler. ! 5: ! 6: GAS is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GAS is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GAS; see the file COPYING. If not, write to ! 18: the 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: ! 27: struct obstack frags = { 0 }; /* All, and only, frags live here. */ ! 28: ! 29: fragS *frag_now = NULL; /* -> current frag we are building. */ ! 30: ! 31: fragS zero_address_frag = { ! 32: 0, /* fr_address */ ! 33: NULL, /* fr_next */ ! 34: 0, /* fr_fix */ ! 35: 0, /* fr_var */ ! 36: 0, /* fr_symbol */ ! 37: 0, /* fr_offset */ ! 38: NULL, /* fr_opcode */ ! 39: rs_fill, /* fr_type */ ! 40: 0, /* fr_subtype */ ! 41: 0 /* fr_literal [0] */ ! 42: }; ! 43: ! 44: ! 45: /* ! 46: * frag_grow() ! 47: * ! 48: * Internal. ! 49: * Try to augment current frag by nchars chars. ! 50: * If there is no room, close of the current frag with a ".fill 0" ! 51: * and begin a new frag. Unless the new frag has nchars chars available ! 52: * do not return. Do not set up any fields of *now_frag. ! 53: */ ! 54: static ! 55: void ! 56: frag_grow( ! 57: int nchars) ! 58: { ! 59: if(frags.chunk_size == 0){ ! 60: know(flagseen['n']); ! 61: as_fatal("with -n a section directive must be seen before assembly " ! 62: "can begin"); ! 63: } ! 64: if (obstack_room (&frags) < nchars) { ! 65: unsigned int n,oldn; ! 66: long oldc; ! 67: ! 68: frag_wane (frag_now); ! 69: frag_new (0); ! 70: oldn=(unsigned)-1; ! 71: oldc=frags.chunk_size; ! 72: frags.chunk_size=2*nchars; ! 73: while((n=obstack_room(&frags))<nchars && n<oldn) { ! 74: frag_wane(frag_now); ! 75: frag_new(0); ! 76: oldn=n; ! 77: } ! 78: frags.chunk_size=oldc; ! 79: } ! 80: if (obstack_room (&frags) < nchars) ! 81: as_fatal ("Can't extend frag %d. chars", nchars); ! 82: } ! 83: ! 84: /* ! 85: * frag_new() ! 86: * ! 87: * Call this to close off a completed frag, and start up a new (empty) ! 88: * frag, in the same subsegment as the old frag. ! 89: * [frchain_now remains the same but frag_now is updated.] ! 90: * Because this calculates the correct value of fr_fix by ! 91: * looking at the obstack 'frags', it needs to know how many ! 92: * characters at the end of the old frag belong to (the maximal) ! 93: * fr_var: the rest must belong to fr_fix. ! 94: * It doesn't actually set up the old frag's fr_var: you may have ! 95: * set fr_var == 1, but allocated 10 chars to the end of the frag: ! 96: * in this case you pass old_frags_var_max_size == 10. ! 97: * ! 98: * Make a new frag, initialising some components. Link new frag at end ! 99: * of frchain_now. ! 100: */ ! 101: void ! 102: frag_new( ! 103: int old_frags_var_max_size) /* Number of chars (already allocated on obstack ! 104: frags) in variable_length part of frag. */ ! 105: { ! 106: register fragS * former_last_fragP; ! 107: /* char *throw_away_pointer; JF unused */ ! 108: register frchainS * frchP; ! 109: long tmp; /* JF */ ! 110: ! 111: if(frags.chunk_size == 0){ ! 112: know(flagseen['n']); ! 113: as_fatal("with -n a section directive must be seen before assembly " ! 114: "can begin"); ! 115: } ! 116: ! 117: frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - ! 118: (frag_now->fr_literal) - old_frags_var_max_size; ! 119: /* Fix up old frag's fr_fix. */ ! 120: ! 121: obstack_finish (&frags); ! 122: /* This will align the obstack so the */ ! 123: /* next struct we allocate on it will */ ! 124: /* begin at a correct boundary. */ ! 125: frchP = frchain_now; ! 126: know (frchP); ! 127: former_last_fragP = frchP->frch_last; ! 128: know (former_last_fragP); ! 129: know (former_last_fragP == frag_now); ! 130: obstack_blank (&frags, SIZEOF_STRUCT_FRAG); ! 131: /* We expect this will begin at a correct */ ! 132: /* boundary for a struct. */ ! 133: tmp=obstack_alignment_mask(&frags); ! 134: obstack_alignment_mask(&frags)=0; /* Turn off alignment */ ! 135: /* If we ever hit a machine ! 136: where strings must be ! 137: aligned, we Lose Big */ ! 138: frag_now=(fragS *)obstack_finish(&frags); ! 139: obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ ! 140: ! 141: /* Just in case we don't get zero'd bytes */ ! 142: memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); ! 143: ! 144: /* obstack_unaligned_done (&frags, &frag_now); */ ! 145: /* know (frags.obstack_c_next_free == frag_now->fr_literal); */ ! 146: /* Generally, frag_now->points to an */ ! 147: /* address rounded up to next alignment. */ ! 148: /* However, characters will add to obstack */ ! 149: /* frags IMMEDIATELY after the struct frag, */ ! 150: /* even if they are not starting at an */ ! 151: /* alignment address. */ ! 152: former_last_fragP->fr_next = frag_now; ! 153: frchP->frch_last = frag_now; ! 154: frag_now->fr_next = NULL; ! 155: } /* frag_new() */ ! 156: ! 157: /* ! 158: * frag_more() ! 159: * ! 160: * Start a new frag unless we have n more chars of room in the current frag. ! 161: * Close off the old frag with a .fill 0. ! 162: * ! 163: * Return the address of the 1st char to write into. Advance ! 164: * frag_now_growth past the new chars. ! 165: */ ! 166: char * ! 167: frag_more( ! 168: int nchars) ! 169: { ! 170: register char *retval; ! 171: ! 172: frag_grow (nchars); ! 173: retval = obstack_next_free (&frags); ! 174: obstack_blank_fast (&frags, nchars); ! 175: return (retval); ! 176: } /* frag_more() */ ! 177: ! 178: /* ! 179: * frag_var() ! 180: * ! 181: * Start a new frag unless we have max_chars more chars of room in the current frag. ! 182: * Close off the old frag with a .fill 0. ! 183: * ! 184: * Set up a machine_dependent relaxable frag, then start a new frag. ! 185: * Return the address of the 1st char of the var part of the old frag ! 186: * to write into. ! 187: */ ! 188: char * ! 189: frag_var( ! 190: relax_stateT type, ! 191: int max_chars, ! 192: int var, ! 193: relax_substateT subtype, ! 194: symbolS *symbol, ! 195: long offset, ! 196: char *opcode) ! 197: { ! 198: register char *retval; ! 199: ! 200: frag_grow (max_chars); ! 201: retval = obstack_next_free (&frags); ! 202: obstack_blank_fast (&frags, max_chars); ! 203: frag_now->fr_var = var; ! 204: frag_now->fr_type = type; ! 205: frag_now->fr_subtype = subtype; ! 206: frag_now->fr_symbol = symbol; ! 207: frag_now->fr_offset = offset; ! 208: frag_now->fr_opcode = opcode; ! 209: frag_new (max_chars); ! 210: return (retval); ! 211: } /* frag_var() */ ! 212: ! 213: /* ! 214: * frag_wane() ! 215: * ! 216: * Reduce the variable end of a frag to a harmless state. ! 217: */ ! 218: void ! 219: frag_wane( ! 220: fragS *fragP) ! 221: { ! 222: fragP->fr_type = rs_fill; ! 223: fragP->fr_offset = 0; ! 224: fragP->fr_var = 0; ! 225: } ! 226: ! 227: /* ! 228: * frag_align() ! 229: * ! 230: * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);". ! 231: * Foo & bar are absolute integers. ! 232: * ! 233: * Call to close off the current frag with a ".align", then start a new ! 234: * (so far empty) frag, in the same subsegment as the last frag. ! 235: */ ! 236: void ! 237: frag_align( ! 238: int alignment, ! 239: int fill_character) ! 240: { ! 241: *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0, ! 242: (long)alignment, (char *)0)) = fill_character; ! 243: } ! 244: ! 245: /* end: frags.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.