Home | History | Annotate | Line # | Download | only in gas
frags.c revision 1.1.1.8
      1 /* frags.c - manage frags -
      2    Copyright (C) 1987-2022 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   frag_now->fr_fix -= old_frags_var_max_size;
    175   /* Make sure its type is valid.  */
    176   gas_assert (frag_now->fr_type != 0);
    177 
    178   /* This will align the obstack so the next struct we allocate on it
    179      will begin at a correct boundary.  */
    180   obstack_finish (&frchain_now->frch_obstack);
    181   frchP = frchain_now;
    182   know (frchP);
    183   former_last_fragP = frchP->frch_last;
    184   gas_assert (former_last_fragP != 0);
    185   gas_assert (former_last_fragP == frag_now);
    186   frag_now = frag_alloc (&frchP->frch_obstack);
    187 
    188   frag_now->fr_file = as_where (&frag_now->fr_line);
    189 
    190   /* Generally, frag_now->points to an address rounded up to next
    191      alignment.  However, characters will add to obstack frags
    192      IMMEDIATELY after the struct frag, even if they are not starting
    193      at an alignment address.  */
    194   former_last_fragP->fr_next = frag_now;
    195   frchP->frch_last = frag_now;
    196 
    197 #ifndef NO_LISTING
    198   {
    199     extern struct list_info_struct *listing_tail;
    200     frag_now->line = listing_tail;
    201   }
    202 #endif
    203 
    204   gas_assert (frchain_now->frch_last == frag_now);
    205 
    206   frag_now->fr_next = NULL;
    207 }
    208 
    209 /* Start a new frag unless we have n more chars of room in the current frag.
    211    Close off the old frag with a .fill 0.
    212 
    213    Return the address of the 1st char to write into. Advance
    214    frag_now_growth past the new chars.  */
    215 
    216 char *
    217 frag_more (size_t nchars)
    218 {
    219   char *retval;
    220 
    221   frag_alloc_check (&frchain_now->frch_obstack);
    222   frag_grow (nchars);
    223   retval = obstack_next_free (&frchain_now->frch_obstack);
    224   obstack_blank_fast (&frchain_now->frch_obstack, nchars);
    225   return retval;
    226 }
    227 
    228 /* Close the current frag, setting its fields for a relaxable frag.  Start a
    230    new frag.  */
    231 
    232 static void
    233 frag_var_init (relax_stateT type, size_t max_chars, size_t var,
    234 	       relax_substateT subtype, symbolS *symbol, offsetT offset,
    235                char *opcode)
    236 {
    237   frag_now->fr_var = var;
    238   frag_now->fr_type = type;
    239   frag_now->fr_subtype = subtype;
    240   frag_now->fr_symbol = symbol;
    241   frag_now->fr_offset = offset;
    242   frag_now->fr_opcode = opcode;
    243 #ifdef USING_CGEN
    244   frag_now->fr_cgen.insn = 0;
    245   frag_now->fr_cgen.opindex = 0;
    246   frag_now->fr_cgen.opinfo = 0;
    247 #endif
    248 #ifdef TC_FRAG_INIT
    249   TC_FRAG_INIT (frag_now, max_chars);
    250 #endif
    251   frag_now->fr_file = as_where (&frag_now->fr_line);
    252 
    253   frag_new (max_chars);
    254 }
    255 
    256 /* Start a new frag unless we have max_chars more chars of room in the
    257    current frag.  Close off the old frag with a .fill 0.
    258 
    259    Set up a machine_dependent relaxable frag, then start a new frag.
    260    Return the address of the 1st char of the var part of the old frag
    261    to write into.  */
    262 
    263 char *
    264 frag_var (relax_stateT type, size_t max_chars, size_t var,
    265 	  relax_substateT subtype, symbolS *symbol, offsetT offset,
    266 	  char *opcode)
    267 {
    268   char *retval;
    269 
    270   frag_grow (max_chars);
    271   retval = obstack_next_free (&frchain_now->frch_obstack);
    272   obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
    273   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
    274   return retval;
    275 }
    276 
    277 /* OVE: This variant of frag_var assumes that space for the tail has been
    279 	allocated by caller.
    280 	No call to frag_grow is done.  */
    281 
    282 char *
    283 frag_variant (relax_stateT type, size_t max_chars, size_t var,
    284 	      relax_substateT subtype, symbolS *symbol, offsetT offset,
    285 	      char *opcode)
    286 {
    287   char *retval;
    288 
    289   retval = obstack_next_free (&frchain_now->frch_obstack);
    290   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
    291 
    292   return retval;
    293 }
    294 
    295 /* Reduce the variable end of a frag to a harmless state.  */
    297 
    298 void
    299 frag_wane (fragS *fragP)
    300 {
    301   fragP->fr_type = rs_fill;
    302   fragP->fr_offset = 0;
    303   fragP->fr_var = 0;
    304 }
    305 
    306 /* Return the number of bytes by which the current frag can be grown.  */
    308 
    309 size_t
    310 frag_room (void)
    311 {
    312   return obstack_room (&frchain_now->frch_obstack);
    313 }
    314 
    315 /* Make an alignment frag.  The size of this frag will be adjusted to
    317    force the next frag to have the appropriate alignment.  ALIGNMENT
    318    is the power of two to which to align.  FILL_CHARACTER is the
    319    character to use to fill in any bytes which are skipped.  MAX is
    320    the maximum number of characters to skip when doing the alignment,
    321    or 0 if there is no maximum.  */
    322 
    323 void
    324 frag_align (int alignment, int fill_character, int max)
    325 {
    326   if (now_seg == absolute_section)
    327     {
    328       addressT new_off;
    329       addressT mask;
    330 
    331       mask = (~(addressT) 0) << alignment;
    332       new_off = (abs_section_offset + ~mask) & mask;
    333       if (max == 0 || new_off - abs_section_offset <= (addressT) max)
    334 	abs_section_offset = new_off;
    335     }
    336   else
    337     {
    338       char *p;
    339 
    340       p = frag_var (rs_align, 1, 1, (relax_substateT) max,
    341 		    (symbolS *) 0, (offsetT) alignment, (char *) 0);
    342       *p = fill_character;
    343     }
    344 }
    345 
    346 /* Make an alignment frag like frag_align, but fill with a repeating
    347    pattern rather than a single byte.  ALIGNMENT is the power of two
    348    to which to align.  FILL_PATTERN is the fill pattern to repeat in
    349    the bytes which are skipped.  N_FILL is the number of bytes in
    350    FILL_PATTERN.  MAX is the maximum number of characters to skip when
    351    doing the alignment, or 0 if there is no maximum.  */
    352 
    353 void
    354 frag_align_pattern (int alignment, const char *fill_pattern,
    355 		    size_t n_fill, int max)
    356 {
    357   char *p;
    358 
    359   p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
    360 		(symbolS *) 0, (offsetT) alignment, (char *) 0);
    361   memcpy (p, fill_pattern, n_fill);
    362 }
    363 
    364 /* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
    365    instruction so that the disassembler does not choke on it.  */
    366 #ifndef NOP_OPCODE
    367 #define NOP_OPCODE 0x00
    368 #endif
    369 
    370 /* Use this to restrict the amount of memory allocated for representing
    371    the alignment code.  Needs to be large enough to hold any fixed sized
    372    prologue plus the replicating portion.  */
    373 #ifndef MAX_MEM_FOR_RS_ALIGN_CODE
    374   /* Assume that if HANDLE_ALIGN is not defined then no special action
    375      is required to code fill, which means that we get just repeat the
    376      one NOP_OPCODE byte.  */
    377 # ifndef HANDLE_ALIGN
    378 #  define MAX_MEM_FOR_RS_ALIGN_CODE  1
    379 # else
    380 #  define MAX_MEM_FOR_RS_ALIGN_CODE  (((size_t) 1 << alignment) - 1)
    381 # endif
    382 #endif
    383 
    384 void
    385 frag_align_code (int alignment, int max)
    386 {
    387   char *p;
    388 
    389   p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
    390 		(relax_substateT) max, (symbolS *) 0,
    391 		(offsetT) alignment, (char *) 0);
    392   *p = NOP_OPCODE;
    393 }
    394 
    395 addressT
    396 frag_now_fix_octets (void)
    397 {
    398   if (now_seg == absolute_section)
    399     return abs_section_offset;
    400 
    401   return ((char *) obstack_next_free (&frchain_now->frch_obstack)
    402 	  - frag_now->fr_literal);
    403 }
    404 
    405 addressT
    406 frag_now_fix (void)
    407 {
    408   /* Symbols whose section has SEC_ELF_OCTETS set,
    409      resolve to octets instead of target bytes.  */
    410   if (now_seg->flags & SEC_OCTETS)
    411     return frag_now_fix_octets ();
    412   else
    413     return frag_now_fix_octets () / OCTETS_PER_BYTE;
    414 }
    415 
    416 void
    417 frag_append_1_char (int datum)
    418 {
    419   frag_alloc_check (&frchain_now->frch_obstack);
    420   if (obstack_room (&frchain_now->frch_obstack) <= 1)
    421     {
    422       frag_wane (frag_now);
    423       frag_new (0);
    424     }
    425   obstack_1grow (&frchain_now->frch_obstack, datum);
    426 }
    427 
    428 /* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
    429    their start addresses.  Set OFFSET to the difference in address
    430    not already accounted for in the frag FR_ADDRESS.  */
    431 
    432 bool
    433 frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
    434 {
    435   const fragS *frag;
    436   offsetT off;
    437 
    438   /* Start with offset initialised to difference between the two frags.
    439      Prior to assigning frag addresses this will be zero.  */
    440   off = frag1->fr_address - frag2->fr_address;
    441   if (frag1 == frag2)
    442     {
    443       *offset = off;
    444       return true;
    445     }
    446 
    447   /* Maybe frag2 is after frag1.  */
    448   frag = frag1;
    449   while (frag->fr_type == rs_fill)
    450     {
    451       off += frag->fr_fix + frag->fr_offset * frag->fr_var;
    452       frag = frag->fr_next;
    453       if (frag == NULL)
    454 	break;
    455       if (frag == frag2)
    456 	{
    457 	  *offset = off;
    458 	  return true;
    459 	}
    460     }
    461 
    462   /* Maybe frag1 is after frag2.  */
    463   off = frag1->fr_address - frag2->fr_address;
    464   frag = frag2;
    465   while (frag->fr_type == rs_fill)
    466     {
    467       off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
    468       frag = frag->fr_next;
    469       if (frag == NULL)
    470 	break;
    471       if (frag == frag1)
    472 	{
    473 	  *offset = off;
    474 	  return true;
    475 	}
    476     }
    477 
    478   return false;
    479 }
    480 
    481 /* Return TRUE if FRAG2 follows FRAG1 with a fixed relationship
    482    between the two assuming alignment frags do nothing.  Set OFFSET to
    483    the difference in address not already accounted for in the frag
    484    FR_ADDRESS.  */
    485 
    486 bool
    487 frag_offset_ignore_align_p (const fragS *frag1, const fragS *frag2,
    488 			    offsetT *offset)
    489 {
    490   const fragS *frag;
    491   offsetT off;
    492 
    493   /* Start with offset initialised to difference between the two frags.
    494      Prior to assigning frag addresses this will be zero.  */
    495   off = frag1->fr_address - frag2->fr_address;
    496   if (frag1 == frag2)
    497     {
    498       *offset = off;
    499       return true;
    500     }
    501 
    502   frag = frag1;
    503   while (frag->fr_type == rs_fill
    504 	 || frag->fr_type == rs_align
    505 	 || frag->fr_type == rs_align_code
    506 	 || frag->fr_type == rs_align_test)
    507     {
    508       if (frag->fr_type == rs_fill)
    509 	off += frag->fr_fix + frag->fr_offset * frag->fr_var;
    510       frag = frag->fr_next;
    511       if (frag == NULL)
    512 	break;
    513       if (frag == frag2)
    514 	{
    515 	  *offset = off;
    516 	  return true;
    517 	}
    518     }
    519 
    520   return false;
    521 }
    522 
    523 /* Return TRUE if we can determine whether FRAG2 OFF2 appears after
    524    (strict >, not >=) FRAG1 OFF1, assuming it is not before.  Set
    525    *OFFSET so that resolve_expression will resolve an O_gt operation
    526    between them to false (0) if they are guaranteed to be at the same
    527    location, or to true (-1) if they are guaranteed to be at different
    528    locations.  Return FALSE conservatively, e.g. if neither result can
    529    be guaranteed (yet).
    530 
    531    They are known to be in the same segment, and not the same frag
    532    (this is a fallback for frag_offset_fixed_p, that always takes care
    533    of this case), and it is expected (from the uses this is designed
    534    to simplify, namely location view increments) that frag2 is
    535    reachable from frag1 following the fr_next links, rather than the
    536    other way round.  */
    537 
    538 bool
    539 frag_gtoffset_p (valueT off2, const fragS *frag2,
    540 		 valueT off1, const fragS *frag1, offsetT *offset)
    541 {
    542   /* Insanity check.  */
    543   if (frag2 == frag1 || off1 > frag1->fr_fix)
    544     return false;
    545 
    546   /* If the first symbol offset is at the end of the first frag and
    547      the second symbol offset at the beginning of the second frag then
    548      it is possible they are at the same address.  Go looking for a
    549      non-zero fr_fix in any frag between these frags.  If found then
    550      we can say the O_gt result will be true.  If no such frag is
    551      found we assume that frag1 or any of the following frags might
    552      have a variable tail and thus the answer is unknown.  This isn't
    553      strictly true; some frags don't have a variable tail, but it
    554      doesn't seem worth optimizing for those cases.  */
    555   const fragS *frag = frag1;
    556   offsetT delta = off2 - off1;
    557   for (;;)
    558     {
    559       delta += frag->fr_fix;
    560       frag = frag->fr_next;
    561       if (frag == frag2)
    562 	{
    563 	  if (delta == 0)
    564 	    return false;
    565 	  break;
    566 	}
    567       /* If we run off the end of the frag chain then we have a case
    568 	 where frag2 is not after frag1, ie. an O_gt expression not
    569 	 created for .loc view.  */
    570       if (frag == NULL)
    571 	return false;
    572     }
    573 
    574   *offset = (off2 - off1 - delta) * OCTETS_PER_BYTE;
    575   return true;
    576 }
    577