Annotation of GNUtools/cctools/as/frags.c, revision 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.