Back to index

cell-binutils  2.17cvs20070401
frags.c
Go to the documentation of this file.
00001 /* frags.c - manage frags -
00002    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
00003    1999, 2000, 2001, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 #include "as.h"
00024 #include "subsegs.h"
00025 #include "obstack.h"
00026 
00027 extern fragS zero_address_frag;
00028 extern fragS bss_address_frag;
00029 
00030 /* Initialization for frag routines.  */
00031 
00032 void
00033 frag_init (void)
00034 {
00035   zero_address_frag.fr_type = rs_fill;
00036   bss_address_frag.fr_type = rs_fill;
00037 }
00038 
00039 /* Check that we're not trying to assemble into a section that can't
00040    allocate frags (currently, this is only possible in the absolute
00041    section), or into an mri common.  */
00042 
00043 static void
00044 frag_alloc_check (const struct obstack *ob)
00045 {
00046   if (ob->chunk_size == 0)
00047     {
00048       as_bad (_("attempt to allocate data in absolute section"));
00049       subseg_set (text_section, 0);
00050     }
00051 
00052   if (mri_common_symbol != NULL)
00053     {
00054       as_bad (_("attempt to allocate data in common section"));
00055       mri_common_symbol = NULL;
00056     }
00057 }
00058 
00059 /* Allocate a frag on the specified obstack.
00060    Call this routine from everywhere else, so that all the weird alignment
00061    hackery can be done in just one place.  */
00062 
00063 fragS *
00064 frag_alloc (struct obstack *ob)
00065 {
00066   fragS *ptr;
00067   int oalign;
00068 
00069   (void) obstack_alloc (ob, 0);
00070   oalign = obstack_alignment_mask (ob);
00071   obstack_alignment_mask (ob) = 0;
00072   ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
00073   obstack_alignment_mask (ob) = oalign;
00074   memset (ptr, 0, SIZEOF_STRUCT_FRAG);
00075   return ptr;
00076 }
00077 
00078 /* Try to augment current frag by nchars chars.
00079    If there is no room, close of the current frag with a ".fill 0"
00080    and begin a new frag. Unless the new frag has nchars chars available
00081    do not return. Do not set up any fields of *now_frag.  */
00082 
00083 void
00084 frag_grow (unsigned int nchars)
00085 {
00086   if (obstack_room (&frchain_now->frch_obstack) < nchars)
00087     {
00088       unsigned int n;
00089       long oldc;
00090 
00091       frag_wane (frag_now);
00092       frag_new (0);
00093       oldc = frchain_now->frch_obstack.chunk_size;
00094       /* Try to allocate a bit more than needed right now.  But don't do
00095          this if we would waste too much memory.  Especially necessary
00096         for extremely big (like 2GB initialized) frags.  */
00097       if (nchars < 0x10000)
00098        frchain_now->frch_obstack.chunk_size = 2 * nchars;
00099       else
00100         frchain_now->frch_obstack.chunk_size = nchars + 0x10000;
00101       frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG;
00102       if (frchain_now->frch_obstack.chunk_size > 0)
00103        while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
00104               && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
00105          {
00106            frag_wane (frag_now);
00107            frag_new (0);
00108          }
00109       frchain_now->frch_obstack.chunk_size = oldc;
00110     }
00111   if (obstack_room (&frchain_now->frch_obstack) < nchars)
00112     as_fatal (_("can't extend frag %u chars"), nchars);
00113 }
00114 
00115 /* Call this to close off a completed frag, and start up a new (empty)
00116    frag, in the same subsegment as the old frag.
00117    [frchain_now remains the same but frag_now is updated.]
00118    Because this calculates the correct value of fr_fix by
00119    looking at the obstack 'frags', it needs to know how many
00120    characters at the end of the old frag belong to the maximal
00121    variable part;  The rest must belong to fr_fix.
00122    It doesn't actually set up the old frag's fr_var.  You may have
00123    set fr_var == 1, but allocated 10 chars to the end of the frag;
00124    In this case you pass old_frags_var_max_size == 10.
00125    In fact, you may use fr_var for something totally unrelated to the
00126    size of the variable part of the frag;  None of the generic frag
00127    handling code makes use of fr_var.
00128 
00129    Make a new frag, initialising some components. Link new frag at end
00130    of frchain_now.  */
00131 
00132 void
00133 frag_new (int old_frags_var_max_size
00134          /* Number of chars (already allocated on obstack frags) in
00135             variable_length part of frag.  */)
00136 {
00137   fragS *former_last_fragP;
00138   frchainS *frchP;
00139 
00140   assert (frchain_now->frch_last == frag_now);
00141 
00142   /* Fix up old frag's fr_fix.  */
00143   frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
00144   /* Make sure its type is valid.  */
00145   assert (frag_now->fr_type != 0);
00146 
00147   /* This will align the obstack so the next struct we allocate on it
00148      will begin at a correct boundary.  */
00149   obstack_finish (&frchain_now->frch_obstack);
00150   frchP = frchain_now;
00151   know (frchP);
00152   former_last_fragP = frchP->frch_last;
00153   assert (former_last_fragP != 0);
00154   assert (former_last_fragP == frag_now);
00155   frag_now = frag_alloc (&frchP->frch_obstack);
00156 
00157   as_where (&frag_now->fr_file, &frag_now->fr_line);
00158 
00159   /* Generally, frag_now->points to an address rounded up to next
00160      alignment.  However, characters will add to obstack frags
00161      IMMEDIATELY after the struct frag, even if they are not starting
00162      at an alignment address.  */
00163   former_last_fragP->fr_next = frag_now;
00164   frchP->frch_last = frag_now;
00165 
00166 #ifndef NO_LISTING
00167   {
00168     extern struct list_info_struct *listing_tail;
00169     frag_now->line = listing_tail;
00170   }
00171 #endif
00172 
00173   assert (frchain_now->frch_last == frag_now);
00174 
00175   frag_now->fr_next = NULL;
00176 }
00177 
00178 /* Start a new frag unless we have n more chars of room in the current frag.
00179    Close off the old frag with a .fill 0.
00180 
00181    Return the address of the 1st char to write into. Advance
00182    frag_now_growth past the new chars.  */
00183 
00184 char *
00185 frag_more (int nchars)
00186 {
00187   register char *retval;
00188 
00189   frag_alloc_check (&frchain_now->frch_obstack);
00190   frag_grow (nchars);
00191   retval = obstack_next_free (&frchain_now->frch_obstack);
00192   obstack_blank_fast (&frchain_now->frch_obstack, nchars);
00193   return (retval);
00194 }
00195 
00196 /* Start a new frag unless we have max_chars more chars of room in the
00197    current frag.  Close off the old frag with a .fill 0.
00198 
00199    Set up a machine_dependent relaxable frag, then start a new frag.
00200    Return the address of the 1st char of the var part of the old frag
00201    to write into.  */
00202 
00203 char *
00204 frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype,
00205          symbolS *symbol, offsetT offset, char *opcode)
00206 {
00207   register char *retval;
00208 
00209   frag_grow (max_chars);
00210   retval = obstack_next_free (&frchain_now->frch_obstack);
00211   obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
00212   frag_now->fr_var = var;
00213   frag_now->fr_type = type;
00214   frag_now->fr_subtype = subtype;
00215   frag_now->fr_symbol = symbol;
00216   frag_now->fr_offset = offset;
00217   frag_now->fr_opcode = opcode;
00218 #ifdef USING_CGEN
00219   frag_now->fr_cgen.insn = 0;
00220   frag_now->fr_cgen.opindex = 0;
00221   frag_now->fr_cgen.opinfo = 0;
00222 #endif
00223 #ifdef TC_FRAG_INIT
00224   TC_FRAG_INIT (frag_now);
00225 #endif
00226   as_where (&frag_now->fr_file, &frag_now->fr_line);
00227   frag_new (max_chars);
00228   return (retval);
00229 }
00230 
00231 /* OVE: This variant of frag_var assumes that space for the tail has been
00232        allocated by caller.
00233        No call to frag_grow is done.  */
00234 
00235 char *
00236 frag_variant (relax_stateT type, int max_chars, int var,
00237              relax_substateT subtype, symbolS *symbol, offsetT offset,
00238              char *opcode)
00239 {
00240   register char *retval;
00241 
00242   retval = obstack_next_free (&frchain_now->frch_obstack);
00243   frag_now->fr_var = var;
00244   frag_now->fr_type = type;
00245   frag_now->fr_subtype = subtype;
00246   frag_now->fr_symbol = symbol;
00247   frag_now->fr_offset = offset;
00248   frag_now->fr_opcode = opcode;
00249 #ifdef USING_CGEN
00250   frag_now->fr_cgen.insn = 0;
00251   frag_now->fr_cgen.opindex = 0;
00252   frag_now->fr_cgen.opinfo = 0;
00253 #endif
00254 #ifdef TC_FRAG_INIT
00255   TC_FRAG_INIT (frag_now);
00256 #endif
00257   as_where (&frag_now->fr_file, &frag_now->fr_line);
00258   frag_new (max_chars);
00259   return (retval);
00260 }
00261 
00262 /* Reduce the variable end of a frag to a harmless state.  */
00263 
00264 void
00265 frag_wane (register fragS *fragP)
00266 {
00267   fragP->fr_type = rs_fill;
00268   fragP->fr_offset = 0;
00269   fragP->fr_var = 0;
00270 }
00271 
00272 /* Return the number of bytes by which the current frag can be grown.  */
00273 
00274 int
00275 frag_room (void)
00276 {
00277   return obstack_room (&frchain_now->frch_obstack);
00278 }
00279 
00280 /* Make an alignment frag.  The size of this frag will be adjusted to
00281    force the next frag to have the appropriate alignment.  ALIGNMENT
00282    is the power of two to which to align.  FILL_CHARACTER is the
00283    character to use to fill in any bytes which are skipped.  MAX is
00284    the maximum number of characters to skip when doing the alignment,
00285    or 0 if there is no maximum.  */
00286 
00287 void
00288 frag_align (int alignment, int fill_character, int max)
00289 {
00290   if (now_seg == absolute_section)
00291     {
00292       addressT new_off;
00293       addressT mask;
00294 
00295       mask = (~(addressT) 0) << alignment;
00296       new_off = (abs_section_offset + ~mask) & mask;
00297       if (max == 0 || new_off - abs_section_offset <= (addressT) max)
00298        abs_section_offset = new_off;
00299     }
00300   else
00301     {
00302       char *p;
00303 
00304       p = frag_var (rs_align, 1, 1, (relax_substateT) max,
00305                   (symbolS *) 0, (offsetT) alignment, (char *) 0);
00306       *p = fill_character;
00307     }
00308 }
00309 
00310 /* Make an alignment frag like frag_align, but fill with a repeating
00311    pattern rather than a single byte.  ALIGNMENT is the power of two
00312    to which to align.  FILL_PATTERN is the fill pattern to repeat in
00313    the bytes which are skipped.  N_FILL is the number of bytes in
00314    FILL_PATTERN.  MAX is the maximum number of characters to skip when
00315    doing the alignment, or 0 if there is no maximum.  */
00316 
00317 void
00318 frag_align_pattern (int alignment, const char *fill_pattern,
00319                   int n_fill, int max)
00320 {
00321   char *p;
00322 
00323   p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
00324               (symbolS *) 0, (offsetT) alignment, (char *) 0);
00325   memcpy (p, fill_pattern, n_fill);
00326 }
00327 
00328 /* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
00329    instruction so that the disassembler does not choke on it.  */
00330 #ifndef NOP_OPCODE
00331 #define NOP_OPCODE 0x00
00332 #endif
00333 
00334 /* Use this to restrict the amount of memory allocated for representing
00335    the alignment code.  Needs to be large enough to hold any fixed sized
00336    prologue plus the replicating portion.  */
00337 #ifndef MAX_MEM_FOR_RS_ALIGN_CODE
00338   /* Assume that if HANDLE_ALIGN is not defined then no special action
00339      is required to code fill, which means that we get just repeat the
00340      one NOP_OPCODE byte.  */
00341 # ifndef HANDLE_ALIGN
00342 #  define MAX_MEM_FOR_RS_ALIGN_CODE  1
00343 # else
00344 #  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
00345 # endif
00346 #endif
00347 
00348 void
00349 frag_align_code (int alignment, int max)
00350 {
00351   char *p;
00352 
00353   p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
00354               (relax_substateT) max, (symbolS *) 0,
00355               (offsetT) alignment, (char *) 0);
00356   *p = NOP_OPCODE;
00357 }
00358 
00359 addressT
00360 frag_now_fix_octets (void)
00361 {
00362   if (now_seg == absolute_section)
00363     return abs_section_offset;
00364 
00365   return ((char *) obstack_next_free (&frchain_now->frch_obstack)
00366          - frag_now->fr_literal);
00367 }
00368 
00369 addressT
00370 frag_now_fix (void)
00371 {
00372   return frag_now_fix_octets () / OCTETS_PER_BYTE;
00373 }
00374 
00375 void
00376 frag_append_1_char (int datum)
00377 {
00378   frag_alloc_check (&frchain_now->frch_obstack);
00379   if (obstack_room (&frchain_now->frch_obstack) <= 1)
00380     {
00381       frag_wane (frag_now);
00382       frag_new (0);
00383     }
00384   obstack_1grow (&frchain_now->frch_obstack, datum);
00385 }
00386 
00387 /* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
00388    their start addresses.  Set OFFSET to the difference in address
00389    not already accounted for in the frag FR_ADDRESS.  */
00390 
00391 bfd_boolean
00392 frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, bfd_vma *offset)
00393 {
00394   const fragS *frag;
00395   bfd_vma off;
00396 
00397   /* Start with offset initialised to difference between the two frags.
00398      Prior to assigning frag addresses this will be zero.  */
00399   off = frag1->fr_address - frag2->fr_address;
00400   if (frag1 == frag2)
00401     {
00402       *offset = off;
00403       return TRUE;
00404     }
00405 
00406   /* Maybe frag2 is after frag1.  */
00407   frag = frag1;
00408   while (frag->fr_type == rs_fill)
00409     {
00410       off += frag->fr_fix + frag->fr_offset * frag->fr_var;
00411       frag = frag->fr_next;
00412       if (frag == NULL)
00413        break;
00414       if (frag == frag2)
00415        {
00416          *offset = off;
00417          return TRUE;
00418        }
00419     }
00420 
00421   /* Maybe frag1 is after frag2.  */
00422   off = frag1->fr_address - frag2->fr_address;
00423   frag = frag2;
00424   while (frag->fr_type == rs_fill)
00425     {
00426       off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
00427       frag = frag->fr_next;
00428       if (frag == NULL)
00429        break;
00430       if (frag == frag1)
00431        {
00432          *offset = off;
00433          return TRUE;
00434        }
00435     }
00436 
00437   return FALSE;
00438 }