133965Sjdp/* frags.c - manage frags -
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3218822Sdim   1999, 2000, 2001, 2003, 2004, 2005, 2006
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GAS, the GNU Assembler.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
2333965Sjdp#include "as.h"
2433965Sjdp#include "subsegs.h"
2533965Sjdp#include "obstack.h"
2633965Sjdp
2733965Sjdpextern fragS zero_address_frag;
2833965Sjdpextern fragS bss_address_frag;
2933965Sjdp
3033965Sjdp/* Initialization for frag routines.  */
3177298Sobrien
3233965Sjdpvoid
33130561Sobrienfrag_init (void)
3433965Sjdp{
3533965Sjdp  zero_address_frag.fr_type = rs_fill;
3633965Sjdp  bss_address_frag.fr_type = rs_fill;
3733965Sjdp}
3833965Sjdp
39130561Sobrien/* Check that we're not trying to assemble into a section that can't
40130561Sobrien   allocate frags (currently, this is only possible in the absolute
41130561Sobrien   section), or into an mri common.  */
42130561Sobrien
43130561Sobrienstatic void
44130561Sobrienfrag_alloc_check (const struct obstack *ob)
45130561Sobrien{
46130561Sobrien  if (ob->chunk_size == 0)
47130561Sobrien    {
48130561Sobrien      as_bad (_("attempt to allocate data in absolute section"));
49130561Sobrien      subseg_set (text_section, 0);
50130561Sobrien    }
51130561Sobrien
52130561Sobrien  if (mri_common_symbol != NULL)
53130561Sobrien    {
54130561Sobrien      as_bad (_("attempt to allocate data in common section"));
55130561Sobrien      mri_common_symbol = NULL;
56130561Sobrien    }
57130561Sobrien}
58130561Sobrien
5933965Sjdp/* Allocate a frag on the specified obstack.
6033965Sjdp   Call this routine from everywhere else, so that all the weird alignment
6133965Sjdp   hackery can be done in just one place.  */
6277298Sobrien
6333965SjdpfragS *
64130561Sobrienfrag_alloc (struct obstack *ob)
6533965Sjdp{
6633965Sjdp  fragS *ptr;
6733965Sjdp  int oalign;
6833965Sjdp
6933965Sjdp  (void) obstack_alloc (ob, 0);
7033965Sjdp  oalign = obstack_alignment_mask (ob);
7133965Sjdp  obstack_alignment_mask (ob) = 0;
7233965Sjdp  ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
7333965Sjdp  obstack_alignment_mask (ob) = oalign;
7433965Sjdp  memset (ptr, 0, SIZEOF_STRUCT_FRAG);
7533965Sjdp  return ptr;
7633965Sjdp}
7733965Sjdp
7877298Sobrien/* Try to augment current frag by nchars chars.
7977298Sobrien   If there is no room, close of the current frag with a ".fill 0"
8077298Sobrien   and begin a new frag. Unless the new frag has nchars chars available
8177298Sobrien   do not return. Do not set up any fields of *now_frag.  */
8277298Sobrien
8377298Sobrienvoid
84130561Sobrienfrag_grow (unsigned int nchars)
8533965Sjdp{
8633965Sjdp  if (obstack_room (&frchain_now->frch_obstack) < nchars)
8733965Sjdp    {
8860484Sobrien      unsigned int n;
8933965Sjdp      long oldc;
9033965Sjdp
9133965Sjdp      frag_wane (frag_now);
9233965Sjdp      frag_new (0);
9333965Sjdp      oldc = frchain_now->frch_obstack.chunk_size;
94218822Sdim      /* Try to allocate a bit more than needed right now.  But don't do
95218822Sdim         this if we would waste too much memory.  Especially necessary
96218822Sdim	 for extremely big (like 2GB initialized) frags.  */
97218822Sdim      if (nchars < 0x10000)
98218822Sdim	frchain_now->frch_obstack.chunk_size = 2 * nchars;
99218822Sdim      else
100218822Sdim        frchain_now->frch_obstack.chunk_size = nchars + 0x10000;
101218822Sdim      frchain_now->frch_obstack.chunk_size += SIZEOF_STRUCT_FRAG;
10277298Sobrien      if (frchain_now->frch_obstack.chunk_size > 0)
10377298Sobrien	while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars
10477298Sobrien	       && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars)
10577298Sobrien	  {
10677298Sobrien	    frag_wane (frag_now);
10777298Sobrien	    frag_new (0);
10877298Sobrien	  }
10933965Sjdp      frchain_now->frch_obstack.chunk_size = oldc;
11033965Sjdp    }
11133965Sjdp  if (obstack_room (&frchain_now->frch_obstack) < nchars)
11289857Sobrien    as_fatal (_("can't extend frag %u chars"), nchars);
11333965Sjdp}
11433965Sjdp
11577298Sobrien/* Call this to close off a completed frag, and start up a new (empty)
11677298Sobrien   frag, in the same subsegment as the old frag.
11777298Sobrien   [frchain_now remains the same but frag_now is updated.]
11877298Sobrien   Because this calculates the correct value of fr_fix by
11977298Sobrien   looking at the obstack 'frags', it needs to know how many
12077298Sobrien   characters at the end of the old frag belong to the maximal
12177298Sobrien   variable part;  The rest must belong to fr_fix.
12277298Sobrien   It doesn't actually set up the old frag's fr_var.  You may have
12377298Sobrien   set fr_var == 1, but allocated 10 chars to the end of the frag;
12477298Sobrien   In this case you pass old_frags_var_max_size == 10.
12577298Sobrien   In fact, you may use fr_var for something totally unrelated to the
12677298Sobrien   size of the variable part of the frag;  None of the generic frag
12777298Sobrien   handling code makes use of fr_var.
12877298Sobrien
12977298Sobrien   Make a new frag, initialising some components. Link new frag at end
13077298Sobrien   of frchain_now.  */
13177298Sobrien
13277298Sobrienvoid
133130561Sobrienfrag_new (int old_frags_var_max_size
134130561Sobrien	  /* Number of chars (already allocated on obstack frags) in
135130561Sobrien	     variable_length part of frag.  */)
13633965Sjdp{
13733965Sjdp  fragS *former_last_fragP;
13833965Sjdp  frchainS *frchP;
13933965Sjdp
14033965Sjdp  assert (frchain_now->frch_last == frag_now);
14133965Sjdp
14233965Sjdp  /* Fix up old frag's fr_fix.  */
14360484Sobrien  frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
14433965Sjdp  /* Make sure its type is valid.  */
14533965Sjdp  assert (frag_now->fr_type != 0);
14633965Sjdp
14733965Sjdp  /* This will align the obstack so the next struct we allocate on it
14877298Sobrien     will begin at a correct boundary.  */
149223262Sbenl  (void) obstack_finish (&frchain_now->frch_obstack);
15033965Sjdp  frchP = frchain_now;
15133965Sjdp  know (frchP);
15233965Sjdp  former_last_fragP = frchP->frch_last;
15333965Sjdp  assert (former_last_fragP != 0);
15433965Sjdp  assert (former_last_fragP == frag_now);
15533965Sjdp  frag_now = frag_alloc (&frchP->frch_obstack);
15633965Sjdp
15733965Sjdp  as_where (&frag_now->fr_file, &frag_now->fr_line);
15833965Sjdp
15933965Sjdp  /* Generally, frag_now->points to an address rounded up to next
16033965Sjdp     alignment.  However, characters will add to obstack frags
16133965Sjdp     IMMEDIATELY after the struct frag, even if they are not starting
16277298Sobrien     at an alignment address.  */
16333965Sjdp  former_last_fragP->fr_next = frag_now;
16433965Sjdp  frchP->frch_last = frag_now;
16533965Sjdp
16633965Sjdp#ifndef NO_LISTING
16733965Sjdp  {
16833965Sjdp    extern struct list_info_struct *listing_tail;
16933965Sjdp    frag_now->line = listing_tail;
17033965Sjdp  }
17133965Sjdp#endif
17233965Sjdp
17333965Sjdp  assert (frchain_now->frch_last == frag_now);
17433965Sjdp
17533965Sjdp  frag_now->fr_next = NULL;
17677298Sobrien}
17733965Sjdp
17877298Sobrien/* Start a new frag unless we have n more chars of room in the current frag.
17977298Sobrien   Close off the old frag with a .fill 0.
18033965Sjdp
18177298Sobrien   Return the address of the 1st char to write into. Advance
18277298Sobrien   frag_now_growth past the new chars.  */
18377298Sobrien
18433965Sjdpchar *
185130561Sobrienfrag_more (int nchars)
18633965Sjdp{
18733965Sjdp  register char *retval;
18833965Sjdp
189130561Sobrien  frag_alloc_check (&frchain_now->frch_obstack);
19033965Sjdp  frag_grow (nchars);
19133965Sjdp  retval = obstack_next_free (&frchain_now->frch_obstack);
19233965Sjdp  obstack_blank_fast (&frchain_now->frch_obstack, nchars);
19333965Sjdp  return (retval);
19477298Sobrien}
19533965Sjdp
19677298Sobrien/* Start a new frag unless we have max_chars more chars of room in the
19777298Sobrien   current frag.  Close off the old frag with a .fill 0.
19833965Sjdp
19977298Sobrien   Set up a machine_dependent relaxable frag, then start a new frag.
20077298Sobrien   Return the address of the 1st char of the var part of the old frag
20177298Sobrien   to write into.  */
20277298Sobrien
20333965Sjdpchar *
204130561Sobrienfrag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype,
205130561Sobrien	  symbolS *symbol, offsetT offset, char *opcode)
20633965Sjdp{
20733965Sjdp  register char *retval;
20833965Sjdp
20933965Sjdp  frag_grow (max_chars);
21033965Sjdp  retval = obstack_next_free (&frchain_now->frch_obstack);
21133965Sjdp  obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
21233965Sjdp  frag_now->fr_var = var;
21333965Sjdp  frag_now->fr_type = type;
21433965Sjdp  frag_now->fr_subtype = subtype;
21533965Sjdp  frag_now->fr_symbol = symbol;
21633965Sjdp  frag_now->fr_offset = offset;
21733965Sjdp  frag_now->fr_opcode = opcode;
21860484Sobrien#ifdef USING_CGEN
21960484Sobrien  frag_now->fr_cgen.insn = 0;
22060484Sobrien  frag_now->fr_cgen.opindex = 0;
22160484Sobrien  frag_now->fr_cgen.opinfo = 0;
22260484Sobrien#endif
22338889Sjdp#ifdef TC_FRAG_INIT
22438889Sjdp  TC_FRAG_INIT (frag_now);
22538889Sjdp#endif
22633965Sjdp  as_where (&frag_now->fr_file, &frag_now->fr_line);
22733965Sjdp  frag_new (max_chars);
22833965Sjdp  return (retval);
22933965Sjdp}
23033965Sjdp
23177298Sobrien/* OVE: This variant of frag_var assumes that space for the tail has been
23277298Sobrien	allocated by caller.
23377298Sobrien	No call to frag_grow is done.  */
23433965Sjdp
23533965Sjdpchar *
236130561Sobrienfrag_variant (relax_stateT type, int max_chars, int var,
237130561Sobrien	      relax_substateT subtype, symbolS *symbol, offsetT offset,
238130561Sobrien	      char *opcode)
23933965Sjdp{
24033965Sjdp  register char *retval;
24133965Sjdp
24233965Sjdp  retval = obstack_next_free (&frchain_now->frch_obstack);
24333965Sjdp  frag_now->fr_var = var;
24433965Sjdp  frag_now->fr_type = type;
24533965Sjdp  frag_now->fr_subtype = subtype;
24633965Sjdp  frag_now->fr_symbol = symbol;
24733965Sjdp  frag_now->fr_offset = offset;
24833965Sjdp  frag_now->fr_opcode = opcode;
24960484Sobrien#ifdef USING_CGEN
25060484Sobrien  frag_now->fr_cgen.insn = 0;
25160484Sobrien  frag_now->fr_cgen.opindex = 0;
25260484Sobrien  frag_now->fr_cgen.opinfo = 0;
25360484Sobrien#endif
25438889Sjdp#ifdef TC_FRAG_INIT
25538889Sjdp  TC_FRAG_INIT (frag_now);
25638889Sjdp#endif
25733965Sjdp  as_where (&frag_now->fr_file, &frag_now->fr_line);
25833965Sjdp  frag_new (max_chars);
25933965Sjdp  return (retval);
26077298Sobrien}
26133965Sjdp
26277298Sobrien/* Reduce the variable end of a frag to a harmless state.  */
26377298Sobrien
26477298Sobrienvoid
265130561Sobrienfrag_wane (register fragS *fragP)
26633965Sjdp{
26733965Sjdp  fragP->fr_type = rs_fill;
26833965Sjdp  fragP->fr_offset = 0;
26933965Sjdp  fragP->fr_var = 0;
27033965Sjdp}
27133965Sjdp
272130561Sobrien/* Return the number of bytes by which the current frag can be grown.  */
273130561Sobrien
274130561Sobrienint
275130561Sobrienfrag_room (void)
276130561Sobrien{
277130561Sobrien  return obstack_room (&frchain_now->frch_obstack);
278130561Sobrien}
279130561Sobrien
28033965Sjdp/* Make an alignment frag.  The size of this frag will be adjusted to
28133965Sjdp   force the next frag to have the appropriate alignment.  ALIGNMENT
28233965Sjdp   is the power of two to which to align.  FILL_CHARACTER is the
28333965Sjdp   character to use to fill in any bytes which are skipped.  MAX is
28433965Sjdp   the maximum number of characters to skip when doing the alignment,
28533965Sjdp   or 0 if there is no maximum.  */
28633965Sjdp
28777298Sobrienvoid
288130561Sobrienfrag_align (int alignment, int fill_character, int max)
28933965Sjdp{
29033965Sjdp  if (now_seg == absolute_section)
29133965Sjdp    {
29233965Sjdp      addressT new_off;
29377298Sobrien      addressT mask;
29433965Sjdp
29577298Sobrien      mask = (~(addressT) 0) << alignment;
29677298Sobrien      new_off = (abs_section_offset + ~mask) & mask;
29738889Sjdp      if (max == 0 || new_off - abs_section_offset <= (addressT) max)
29833965Sjdp	abs_section_offset = new_off;
29933965Sjdp    }
30033965Sjdp  else
30133965Sjdp    {
30233965Sjdp      char *p;
30333965Sjdp
30433965Sjdp      p = frag_var (rs_align, 1, 1, (relax_substateT) max,
30533965Sjdp		    (symbolS *) 0, (offsetT) alignment, (char *) 0);
30633965Sjdp      *p = fill_character;
30733965Sjdp    }
30833965Sjdp}
30933965Sjdp
31033965Sjdp/* Make an alignment frag like frag_align, but fill with a repeating
31133965Sjdp   pattern rather than a single byte.  ALIGNMENT is the power of two
31233965Sjdp   to which to align.  FILL_PATTERN is the fill pattern to repeat in
31333965Sjdp   the bytes which are skipped.  N_FILL is the number of bytes in
31433965Sjdp   FILL_PATTERN.  MAX is the maximum number of characters to skip when
31533965Sjdp   doing the alignment, or 0 if there is no maximum.  */
31633965Sjdp
31777298Sobrienvoid
318130561Sobrienfrag_align_pattern (int alignment, const char *fill_pattern,
319130561Sobrien		    int n_fill, int max)
32033965Sjdp{
32133965Sjdp  char *p;
32233965Sjdp
32333965Sjdp  p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
32433965Sjdp		(symbolS *) 0, (offsetT) alignment, (char *) 0);
32533965Sjdp  memcpy (p, fill_pattern, n_fill);
32633965Sjdp}
32733965Sjdp
32877298Sobrien/* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
32977298Sobrien   instruction so that the disassembler does not choke on it.  */
33077298Sobrien#ifndef NOP_OPCODE
33177298Sobrien#define NOP_OPCODE 0x00
33277298Sobrien#endif
33377298Sobrien
33477298Sobrien/* Use this to restrict the amount of memory allocated for representing
33577298Sobrien   the alignment code.  Needs to be large enough to hold any fixed sized
33677298Sobrien   prologue plus the replicating portion.  */
33777298Sobrien#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
33877298Sobrien  /* Assume that if HANDLE_ALIGN is not defined then no special action
33977298Sobrien     is required to code fill, which means that we get just repeat the
34077298Sobrien     one NOP_OPCODE byte.  */
34177298Sobrien# ifndef HANDLE_ALIGN
34277298Sobrien#  define MAX_MEM_FOR_RS_ALIGN_CODE  1
34377298Sobrien# else
34477298Sobrien#  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
34577298Sobrien# endif
34677298Sobrien#endif
34777298Sobrien
34877298Sobrienvoid
349130561Sobrienfrag_align_code (int alignment, int max)
35077298Sobrien{
35177298Sobrien  char *p;
35277298Sobrien
35377298Sobrien  p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
35477298Sobrien		(relax_substateT) max, (symbolS *) 0,
35577298Sobrien		(offsetT) alignment, (char *) 0);
35677298Sobrien  *p = NOP_OPCODE;
35777298Sobrien}
35877298Sobrien
35938889SjdpaddressT
360130561Sobrienfrag_now_fix_octets (void)
36133965Sjdp{
36233965Sjdp  if (now_seg == absolute_section)
36333965Sjdp    return abs_section_offset;
36460484Sobrien
36577298Sobrien  return ((char *) obstack_next_free (&frchain_now->frch_obstack)
36677298Sobrien	  - frag_now->fr_literal);
36733965Sjdp}
36833965Sjdp
36960484SobrienaddressT
370130561Sobrienfrag_now_fix (void)
37160484Sobrien{
37277298Sobrien  return frag_now_fix_octets () / OCTETS_PER_BYTE;
37360484Sobrien}
37460484Sobrien
37533965Sjdpvoid
376130561Sobrienfrag_append_1_char (int datum)
37733965Sjdp{
378130561Sobrien  frag_alloc_check (&frchain_now->frch_obstack);
37933965Sjdp  if (obstack_room (&frchain_now->frch_obstack) <= 1)
38033965Sjdp    {
38133965Sjdp      frag_wane (frag_now);
38233965Sjdp      frag_new (0);
38333965Sjdp    }
38433965Sjdp  obstack_1grow (&frchain_now->frch_obstack, datum);
38533965Sjdp}
386218822Sdim
387218822Sdim/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
388218822Sdim   their start addresses.  Set OFFSET to the difference in address
389218822Sdim   not already accounted for in the frag FR_ADDRESS.  */
390218822Sdim
391218822Sdimbfd_boolean
392218822Sdimfrag_offset_fixed_p (const fragS *frag1, const fragS *frag2, bfd_vma *offset)
393218822Sdim{
394218822Sdim  const fragS *frag;
395218822Sdim  bfd_vma off;
396218822Sdim
397218822Sdim  /* Start with offset initialised to difference between the two frags.
398218822Sdim     Prior to assigning frag addresses this will be zero.  */
399218822Sdim  off = frag1->fr_address - frag2->fr_address;
400218822Sdim  if (frag1 == frag2)
401218822Sdim    {
402218822Sdim      *offset = off;
403218822Sdim      return TRUE;
404218822Sdim    }
405218822Sdim
406218822Sdim  /* Maybe frag2 is after frag1.  */
407218822Sdim  frag = frag1;
408218822Sdim  while (frag->fr_type == rs_fill)
409218822Sdim    {
410218822Sdim      off += frag->fr_fix + frag->fr_offset * frag->fr_var;
411218822Sdim      frag = frag->fr_next;
412218822Sdim      if (frag == NULL)
413218822Sdim	break;
414218822Sdim      if (frag == frag2)
415218822Sdim	{
416218822Sdim	  *offset = off;
417218822Sdim	  return TRUE;
418218822Sdim	}
419218822Sdim    }
420218822Sdim
421218822Sdim  /* Maybe frag1 is after frag2.  */
422218822Sdim  off = frag1->fr_address - frag2->fr_address;
423218822Sdim  frag = frag2;
424218822Sdim  while (frag->fr_type == rs_fill)
425218822Sdim    {
426218822Sdim      off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
427218822Sdim      frag = frag->fr_next;
428218822Sdim      if (frag == NULL)
429218822Sdim	break;
430218822Sdim      if (frag == frag1)
431218822Sdim	{
432218822Sdim	  *offset = off;
433218822Sdim	  return TRUE;
434218822Sdim	}
435218822Sdim    }
436218822Sdim
437218822Sdim  return FALSE;
438218822Sdim}
439