Annotation of GNUtools/cctools/as/frags.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.