Home | History | Annotate | Line # | Download | only in gas
frags.c revision 1.1.1.8.2.1
      1 /* frags.c - manage frags -
      2    Copyright (C) 1987-2024 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 3, 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 the Free
     18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19    02110-1301, USA.  */
     20 
     21 #include "as.h"
     22 #include "subsegs.h"
     23 #include "obstack.h"
     24 
     25 extern fragS zero_address_frag;
     26 extern fragS predefined_address_frag;
     27 
     28 static int totalfrags;
     29 
     30 int
     31 get_frag_count (void)
     32 {
     33   return totalfrags;
     34 }
     35 
     36 void
     37 clear_frag_count (void)
     38 {
     39   totalfrags = 0;
     40 }
     41 
     42 /* Initialization for frag routines.  */
     44 
     45 void
     46 frag_init (void)
     47 {
     48   zero_address_frag.fr_type = rs_fill;
     49   predefined_address_frag.fr_type = rs_fill;
     50 }
     51 
     52 /* Check that we're not trying to assemble into a section that can't
     54    allocate frags (currently, this is only possible in the absolute
     55    section), or into an mri common.  */
     56 
     57 static void
     58 frag_alloc_check (const struct obstack *ob)
     59 {
     60   if (ob->chunk_size == 0)
     61     {
     62       as_bad (_("attempt to allocate data in absolute section"));
     63       subseg_set (text_section, 0);
     64     }
     65 
     66   if (mri_common_symbol != NULL)
     67     {
     68       as_bad (_("attempt to allocate data in common section"));
     69       mri_common_symbol = NULL;
     70     }
     71 }
     72 
     73 /* Allocate a frag on the specified obstack.
     74    Call this routine from everywhere else, so that all the weird alignment
     75    hackery can be done in just one place.  */
     76 
     77 fragS *
     78 frag_alloc (struct obstack *ob)
     79 {
     80   fragS *ptr;
     81   int oalign;
     82 
     83   (void) obstack_alloc (ob, 0);
     84   oalign = obstack_alignment_mask (ob);
     85   obstack_alignment_mask (ob) = 0;
     86   ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
     87   obstack_alignment_mask (ob) = oalign;
     88   memset (ptr, 0, SIZEOF_STRUCT_FRAG);
     89   totalfrags++;
     90   return ptr;
     91 }
     92 
     93 /* Try to augment current frag by nchars chars.
     95    If there is no room, close off the current frag with a ".fill 0"
     96    and begin a new frag.  Then loop until the new frag has at least
     97    nchars chars available.  Does not set up any fields in frag_now.  */
     98 
     99 void
    100 frag_grow (size_t nchars)
    101 {
    102   if (obstack_room (&frchain_now->frch_obstack) < nchars)
    103     {
    104       size_t oldc;
    105       size_t newc;
    106 
    107       /* Try to allocate a bit more than needed right now.  But don't do
    108          this if we would waste too much memory.  Especially necessary
    109          for extremely big (like 2GB initialized) frags.  */
    110       if (nchars < 0x10000)
    111         newc = 2 * nchars;
    112       else
    113         newc = nchars + 0x10000;
    114       newc += SIZEOF_STRUCT_FRAG;
    115 
    116       /* Check for possible overflow.  */
    117       if (newc < nchars)
    118 	as_fatal (ngettext ("can't extend frag %lu char",
    119 			    "can't extend frag %lu chars",
    120 			    (unsigned long) nchars),
    121 		  (unsigned long) nchars);
    122 
    123       /* Force to allocate at least NEWC bytes, but not less than the
    124          default.  */
    125       oldc = obstack_chunk_size (&frchain_now->frch_obstack);
    126       if (newc > oldc)
    127 	obstack_chunk_size (&frchain_now->frch_obstack) = newc;
    128 
    129       while (obstack_room (&frchain_now->frch_obstack) < nchars)
    130         {
    131           /* Not enough room in this frag.  Close it and start a new one.
    132              This must be done in a loop because the created frag may not
    133              be big enough if the current obstack chunk is used.  */
    134           frag_wane (frag_now);
    135           frag_new (0);
    136         }
    137 
    138       /* Restore the old chunk size.  */
    139       obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
    140     }
    141 }
    142 
    143 /* Call this to close off a completed frag, and start up a new (empty)
    145    frag, in the same subsegment as the old frag.
    146    [frchain_now remains the same but frag_now is updated.]
    147    Because this calculates the correct value of fr_fix by
    148    looking at the obstack 'frags', it needs to know how many
    149    characters at the end of the old frag belong to the maximal
    150    variable part;  The rest must belong to fr_fix.
    151    It doesn't actually set up the old frag's fr_var.  You may have
    152    set fr_var == 1, but allocated 10 chars to the end of the frag;
    153    In this case you pass old_frags_var_max_size == 10.
    154    In fact, you may use fr_var for something totally unrelated to the
    155    size of the variable part of the frag;  None of the generic frag
    156    handling code makes use of fr_var.
    157 
    158    Make a new frag, initialising some components. Link new frag at end
    159    of frchain_now.  */
    160 
    161 void
    162 frag_new (size_t old_frags_var_max_size
    163 	  /* Number of chars (already allocated on obstack frags) in
    164 	     variable_length part of frag.  */)
    165 {
    166   fragS *former_last_fragP;
    167   frchainS *frchP;
    168 
    169   gas_assert (frchain_now->frch_last == frag_now);
    170 
    171   /* Fix up old frag's fr_fix.  */
    172   frag_now->fr_fix = frag_now_fix_octets ();
    173   gas_assert (frag_now->fr_fix >= old_frags_var_max_size
    174 	      || now_seg == absolute_section);
    175   frag_now->fr_fix -= old_frags_var_max_size;
    176   /* Make sure its type is valid.  */
    177   gas_assert (frag_now->fr_type != 0);
    178 
    179   /* This will align the obstack so the next struct we allocate on it
    180      will begin at a correct boundary.  */
    181   obstack_finish (&frchain_now->frch_obstack);
    182   frchP = frchain_now;
    183   know (frchP);
    184   former_last_fragP = frchP->frch_last;
    185   gas_assert (former_last_fragP != 0);
    186   gas_assert (former_last_fragP == frag_now);
    187   frag_now = frag_alloc (&frchP->frch_obstack);
    188 
    189   frag_now->fr_file = as_where (&frag_now->fr_line);
    190 
    191   /* Generally, frag_now->points to an address rounded up to next
    192      alignment.  However, characters will add to obstack frags
    193      IMMEDIATELY after the struct frag, even if they are not starting
    194      at an alignment address.  */
    195   former_last_fragP->fr_next = frag_now;
    196   frchP->frch_last = frag_now;
    197 
    198 #ifndef NO_LISTING
    199   {
    200     extern struct list_info_struct *listing_tail;
    201     frag_now->line = listing_tail;
    202   }
    203 #endif
    204 
    205   gas_assert (frchain_now->frch_last == frag_now);
    206 
    207   frag_now->fr_next = NULL;
    208 }
    209 
    210 /* Start a new frag unless we have n more chars of room in the current frag.
    212    Close off the old frag with a .fill 0.
    213 
    214    Return the address of the 1st char to write into. Advance
    215    frag_now_growth past the new chars.  */
    216 
    217 char *
    218 frag_more (size_t nchars)
    219 {
    220   char *retval;
    221 
    222   frag_alloc_check (&frchain_now->frch_obstack);
    223   frag_grow (nchars);
    224   retval = obstack_next_free (&frchain_now->frch_obstack);
    225   obstack_blank_fast (&frchain_now->frch_obstack, nchars);
    226   return retval;
    227 }
    228 
    229 /* Close the current frag, setting its fields for a relaxable frag.  Start a
    231    new frag.  */
    232 
    233 static void
    234 frag_var_init (relax_stateT type, size_t max_chars, size_t var,
    235 	       relax_substateT subtype, symbolS *symbol, offsetT offset,
    236                char *opcode)
    237 {
    238   frag_now->fr_var = var;
    239   frag_now->fr_type = type;
    240   frag_now->fr_subtype = subtype;
    241   frag_now->fr_symbol = symbol;
    242   frag_now->fr_offset = offset;
    243   frag_now->fr_opcode = opcode;
    244 #ifdef USING_CGEN
    245   frag_now->fr_cgen.insn = 0;
    246   frag_now->fr_cgen.opindex = 0;
    247   frag_now->fr_cgen.opinfo = 0;
    248 #endif
    249 #ifdef TC_FRAG_INIT
    250   TC_FRAG_INIT (frag_now, max_chars);
    251 #endif
    252   frag_now->fr_file = as_where (&frag_now->fr_line);
    253 
    254   frag_new (max_chars);
    255 }
    256 
    257 /* Start a new frag unless we have max_chars more chars of room in the
    258    current frag.  Close off the old frag with a .fill 0.
    259 
    260    Set up a machine_dependent relaxable frag, then start a new frag.
    261    Return the address of the 1st char of the var part of the old frag
    262    to write into.  */
    263 
    264 char *
    265 frag_var (relax_stateT type, size_t max_chars, size_t var,
    266 	  relax_substateT subtype, symbolS *symbol, offsetT offset,
    267 	  char *opcode)
    268 {
    269   char *retval;
    270 
    271   frag_grow (max_chars);
    272   retval = obstack_next_free (&frchain_now->frch_obstack);
    273   obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
    274   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
    275   return retval;
    276 }
    277 
    278 /* OVE: This variant of frag_var assumes that space for the tail has been
    280 	allocated by caller.
    281 	No call to frag_grow is done.  */
    282 
    283 char *
    284 frag_variant (relax_stateT type, size_t max_chars, size_t var,
    285 	      relax_substateT subtype, symbolS *symbol, offsetT offset,
    286 	      char *opcode)
    287 {
    288   char *retval;
    289 
    290   retval = obstack_next_free (&frchain_now->frch_obstack);
    291   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
    292 
    293   return retval;
    294 }
    295 
    296 /* Reduce the variable end of a frag to a harmless state.  */
    298 
    299 void
    300 frag_wane (fragS *fragP)
    301 {
    302   fragP->fr_type = rs_fill;
    303   fragP->fr_offset = 0;
    304   fragP->fr_var = 0;
    305 }
    306 
    307 /* Return the number of bytes by which the current frag can be grown.  */
    309 
    310 size_t
    311 frag_room (void)
    312 {
    313   return obstack_room (&frchain_now->frch_obstack);
    314 }
    315 
    316 /* Make an alignment frag.  The size of this frag will be adjusted to
    318    force the next frag to have the appropriate alignment.  ALIGNMENT
    319    is the power of two to which to align.  FILL_CHARACTER is the
    320    character to use to fill in any bytes which are skipped.  MAX is
    321    the maximum number of characters to skip when doing the alignment,
    322    or 0 if there is no maximum.  */
    323 
    324 void
    325 frag_align (int alignment, int fill_character, int max)
    326 {
    327   if (now_seg == absolute_section)
    328     {
    329       addressT new_off;
    330       addressT mask;
    331 
    332       mask = (~(addressT) 0) << alignment;
    333       new_off = (abs_section_offset + ~mask) & mask;
    334       if (max == 0 || new_off - abs_section_offset <= (addressT) max)
    335 	abs_section_offset = new_off;
    336     }
    337   else
    338     {
    339       char *p;
    340 
    341       p = frag_var (rs_align, 1, 1, (relax_substateT) max,
    342 		    (symbolS *) 0, (offsetT) alignment, (char *) 0);
    343       *p = fill_character;
    344     }
    345 }
    346 
    347 /* Make an alignment frag like frag_align, but fill with a repeating
    348    pattern rather than a single byte.  ALIGNMENT is the power of two
    349    to which to align.  FILL_PATTERN is the fill pattern to repeat in
    350    the bytes which are skipped.  N_FILL is the number of bytes in
    351    FILL_PATTERN.  MAX is the maximum number of characters to skip when
    352    doing the alignment, or 0 if there is no maximum.  */
    353 
    354 void
    355 frag_align_pattern (int alignment, const char *fill_pattern,
    356 		    size_t n_fill, int max)
    357 {
    358   char *p;
    359 
    360   p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
    361 		(symbolS *) 0, (offsetT) alignment, (char *) 0);
    362   memcpy (p, fill_pattern, n_fill);
    363 }
    364 
    365 /* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
    366    instruction so that the disassembler does not choke on it.  */
    367 #ifndef NOP_OPCODE
    368 #define NOP_OPCODE 0x00
    369 #endif
    370 
    371 /* Use this to restrict the amount of memory allocated for representing
    372    the alignment code.  Needs to be large enough to hold any fixed sized
    373    prologue plus the replicating portion.  */
    374 #ifndef MAX_MEM_FOR_RS_ALIGN_CODE
    375   /* Assume that if HANDLE_ALIGN is not defined then no special action
    376      is required to code fill, which means that we get just repeat the
    377      one NOP_OPCODE byte.  */
    378 # ifndef HANDLE_ALIGN
    379 #  define MAX_MEM_FOR_RS_ALIGN_CODE  1
    380 # else
    381 #  define MAX_MEM_FOR_RS_ALIGN_CODE  (((size_t) 1 << alignment) - 1)
    382 # endif
    383 #endif
    384 
    385 void
    386 frag_align_code (int alignment, int max)
    387 {
    388   char *p;
    389 
    390   p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
    391 		(relax_substateT) max, (symbolS *) 0,
    392 		(offsetT) alignment, (char *) 0);
    393   *p = NOP_OPCODE;
    394 }
    395 
    396 addressT
    397 frag_now_fix_octets (void)
    398 {
    399   if (now_seg == absolute_section)
    400     return abs_section_offset;
    401 
    402   return ((char *) obstack_next_free (&frchain_now->frch_obstack)
    403 	  - frag_now->fr_literal);
    404 }
    405 
    406 addressT
    407 frag_now_fix (void)
    408 {
    409   /* Symbols whose section has SEC_ELF_OCTETS set,
    410      resolve to octets instead of target bytes.  */
    411   if (now_seg->flags & SEC_OCTETS)
    412     return frag_now_fix_octets ();
    413   else
    414     return frag_now_fix_octets () / OCTETS_PER_BYTE;
    415 }
    416 
    417 void
    418 frag_append_1_char (int datum)
    419 {
    420   frag_alloc_check (&frchain_now->frch_obstack);
    421   if (obstack_room (&frchain_now->frch_obstack) <= 1)
    422     {
    423       frag_wane (frag_now);
    424       frag_new (0);
    425     }
    426   obstack_1grow (&frchain_now->frch_obstack, datum);
    427 }
    428 
    429 /* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
    430    their start addresses.  Set OFFSET to the difference in address
    431    not already accounted for in the frag FR_ADDRESS.  */
    432 
    433 bool
    434 frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
    435 {
    436   const fragS *frag;
    437   offsetT off;
    438 
    439   /* Start with offset initialised to difference between the two frags.
    440      Prior to assigning frag addresses this will be zero.  */
    441   off = frag1->fr_address - frag2->fr_address;
    442   if (frag1 == frag2)
    443     {
    444       *offset = off;
    445       return true;
    446     }
    447 
    448   /* Maybe frag2 is after frag1.  */
    449   frag = frag1;
    450   while (frag->fr_type == rs_fill)
    451     {
    452       off += frag->fr_fix + frag->fr_offset * frag->fr_var;
    453       frag = frag->fr_next;
    454       if (frag == NULL)
    455 	break;
    456       if (frag == frag2)
    457 	{
    458 	  *offset = off;
    459 	  return true;
    460 	}
    461     }
    462 
    463   /* Maybe frag1 is after frag2.  */
    464   off = frag1->fr_address - frag2->fr_address;
    465   frag = frag2;
    466   while (frag->fr_type == rs_fill)
    467     {
    468       off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
    469       frag = frag->fr_next;
    470       if (frag == NULL)
    471 	break;
    472       if (frag == frag1)
    473 	{
    474 	  *offset = off;
    475 	  return true;
    476 	}
    477     }
    478 
    479   return false;
    480 }
    481 
    482 /* Return TRUE if FRAG2 follows FRAG1 with a fixed relationship
    483    between the two assuming alignment frags do nothing.  Set OFFSET to
    484    the difference in address not already accounted for in the frag
    485    FR_ADDRESS.  */
    486 
    487 bool
    488 frag_offset_ignore_align_p (const fragS *frag1, const fragS *frag2,
    489 			    offsetT *offset)
    490 {
    491   const fragS *frag;
    492   offsetT off;
    493 
    494   /* Start with offset initialised to difference between the two frags.
    495      Prior to assigning frag addresses this will be zero.  */
    496   off = frag1->fr_address - frag2->fr_address;
    497   if (frag1 == frag2)
    498     {
    499       *offset = off;
    500       return true;
    501     }
    502 
    503   frag = frag1;
    504   while (frag->fr_type == rs_fill
    505 	 || frag->fr_type == rs_align
    506 	 || frag->fr_type == rs_align_code
    507 	 || frag->fr_type == rs_align_test)
    508     {
    509       if (frag->fr_type == rs_fill)
    510 	off += frag->fr_fix + frag->fr_offset * frag->fr_var;
    511       frag = frag->fr_next;
    512       if (frag == NULL)
    513 	break;
    514       if (frag == frag2)
    515 	{
    516 	  *offset = off;
    517 	  return true;
    518 	}
    519     }
    520 
    521   return false;
    522 }
    523 
    524 /* Return TRUE if we can determine whether FRAG2 OFF2 appears after
    525    (strict >, not >=) FRAG1 OFF1, assuming it is not before.  Set
    526    *OFFSET so that resolve_expression will resolve an O_gt operation
    527    between them to false (0) if they are guaranteed to be at the same
    528    location, or to true (-1) if they are guaranteed to be at different
    529    locations.  Return FALSE conservatively, e.g. if neither result can
    530    be guaranteed (yet).
    531 
    532    They are known to be in the same segment, and not the same frag
    533    (this is a fallback for frag_offset_fixed_p, that always takes care
    534    of this case), and it is expected (from the uses this is designed
    535    to simplify, namely location view increments) that frag2 is
    536    reachable from frag1 following the fr_next links, rather than the
    537    other way round.  */
    538 
    539 bool
    540 frag_gtoffset_p (valueT off2, const fragS *frag2,
    541 		 valueT off1, const fragS *frag1, offsetT *offset)
    542 {
    543   /* Insanity check.  */
    544   if (frag2 == frag1 || off1 > frag1->fr_fix)
    545     return false;
    546 
    547   /* If the first symbol offset is at the end of the first frag and
    548      the second symbol offset at the beginning of the second frag then
    549      it is possible they are at the same address.  Go looking for a
    550      non-zero fr_fix in any frag between these frags.  If found then
    551      we can say the O_gt result will be true.  If no such frag is
    552      found we assume that frag1 or any of the following frags might
    553      have a variable tail and thus the answer is unknown.  This isn't
    554      strictly true; some frags don't have a variable tail, but it
    555      doesn't seem worth optimizing for those cases.  */
    556   const fragS *frag = frag1;
    557   offsetT delta = off2 - off1;
    558   for (;;)
    559     {
    560       delta += frag->fr_fix;
    561       frag = frag->fr_next;
    562       if (frag == frag2)
    563 	{
    564 	  if (delta == 0)
    565 	    return false;
    566 	  break;
    567 	}
    568       /* If we run off the end of the frag chain then we have a case
    569 	 where frag2 is not after frag1, ie. an O_gt expression not
    570 	 created for .loc view.  */
    571       if (frag == NULL)
    572 	return false;
    573     }
    574 
    575   *offset = (off2 - off1 - delta) * OCTETS_PER_BYTE;
    576   return true;
    577 }
    578