xref: /dflybsd-src/contrib/binutils-2.27/gas/frags.c (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj /* frags.c - manage frags -
2*a9fa9459Szrj    Copyright (C) 1987-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj 
4*a9fa9459Szrj    This file is part of GAS, the GNU Assembler.
5*a9fa9459Szrj 
6*a9fa9459Szrj    GAS is free software; you can redistribute it and/or modify
7*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
8*a9fa9459Szrj    the Free Software Foundation; either version 3, or (at your option)
9*a9fa9459Szrj    any later version.
10*a9fa9459Szrj 
11*a9fa9459Szrj    GAS is distributed in the hope that it will be useful,
12*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a9fa9459Szrj    GNU General Public License for more details.
15*a9fa9459Szrj 
16*a9fa9459Szrj    You should have received a copy of the GNU General Public License
17*a9fa9459Szrj    along with GAS; see the file COPYING.  If not, write to the Free
18*a9fa9459Szrj    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19*a9fa9459Szrj    02110-1301, USA.  */
20*a9fa9459Szrj 
21*a9fa9459Szrj #include "as.h"
22*a9fa9459Szrj #include "subsegs.h"
23*a9fa9459Szrj #include "obstack.h"
24*a9fa9459Szrj 
25*a9fa9459Szrj extern fragS zero_address_frag;
26*a9fa9459Szrj extern fragS predefined_address_frag;
27*a9fa9459Szrj 
28*a9fa9459Szrj static int totalfrags;
29*a9fa9459Szrj 
30*a9fa9459Szrj int
get_frag_count(void)31*a9fa9459Szrj get_frag_count (void)
32*a9fa9459Szrj {
33*a9fa9459Szrj   return totalfrags;
34*a9fa9459Szrj }
35*a9fa9459Szrj 
36*a9fa9459Szrj void
clear_frag_count(void)37*a9fa9459Szrj clear_frag_count (void)
38*a9fa9459Szrj {
39*a9fa9459Szrj   totalfrags = 0;
40*a9fa9459Szrj }
41*a9fa9459Szrj 
42*a9fa9459Szrj /* Initialization for frag routines.  */
43*a9fa9459Szrj 
44*a9fa9459Szrj void
frag_init(void)45*a9fa9459Szrj frag_init (void)
46*a9fa9459Szrj {
47*a9fa9459Szrj   zero_address_frag.fr_type = rs_fill;
48*a9fa9459Szrj   predefined_address_frag.fr_type = rs_fill;
49*a9fa9459Szrj }
50*a9fa9459Szrj 
51*a9fa9459Szrj /* Check that we're not trying to assemble into a section that can't
52*a9fa9459Szrj    allocate frags (currently, this is only possible in the absolute
53*a9fa9459Szrj    section), or into an mri common.  */
54*a9fa9459Szrj 
55*a9fa9459Szrj static void
frag_alloc_check(const struct obstack * ob)56*a9fa9459Szrj frag_alloc_check (const struct obstack *ob)
57*a9fa9459Szrj {
58*a9fa9459Szrj   if (ob->chunk_size == 0)
59*a9fa9459Szrj     {
60*a9fa9459Szrj       as_bad (_("attempt to allocate data in absolute section"));
61*a9fa9459Szrj       subseg_set (text_section, 0);
62*a9fa9459Szrj     }
63*a9fa9459Szrj 
64*a9fa9459Szrj   if (mri_common_symbol != NULL)
65*a9fa9459Szrj     {
66*a9fa9459Szrj       as_bad (_("attempt to allocate data in common section"));
67*a9fa9459Szrj       mri_common_symbol = NULL;
68*a9fa9459Szrj     }
69*a9fa9459Szrj }
70*a9fa9459Szrj 
71*a9fa9459Szrj /* Allocate a frag on the specified obstack.
72*a9fa9459Szrj    Call this routine from everywhere else, so that all the weird alignment
73*a9fa9459Szrj    hackery can be done in just one place.  */
74*a9fa9459Szrj 
75*a9fa9459Szrj fragS *
frag_alloc(struct obstack * ob)76*a9fa9459Szrj frag_alloc (struct obstack *ob)
77*a9fa9459Szrj {
78*a9fa9459Szrj   fragS *ptr;
79*a9fa9459Szrj   int oalign;
80*a9fa9459Szrj 
81*a9fa9459Szrj   (void) obstack_alloc (ob, 0);
82*a9fa9459Szrj   oalign = obstack_alignment_mask (ob);
83*a9fa9459Szrj   obstack_alignment_mask (ob) = 0;
84*a9fa9459Szrj   ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
85*a9fa9459Szrj   obstack_alignment_mask (ob) = oalign;
86*a9fa9459Szrj   memset (ptr, 0, SIZEOF_STRUCT_FRAG);
87*a9fa9459Szrj   totalfrags++;
88*a9fa9459Szrj   return ptr;
89*a9fa9459Szrj }
90*a9fa9459Szrj 
91*a9fa9459Szrj /* Try to augment current frag by nchars chars.
92*a9fa9459Szrj    If there is no room, close of the current frag with a ".fill 0"
93*a9fa9459Szrj    and begin a new frag. Unless the new frag has nchars chars available
94*a9fa9459Szrj    do not return. Do not set up any fields of *now_frag.  */
95*a9fa9459Szrj 
96*a9fa9459Szrj void
frag_grow(size_t nchars)97*a9fa9459Szrj frag_grow (size_t nchars)
98*a9fa9459Szrj {
99*a9fa9459Szrj   if (obstack_room (&frchain_now->frch_obstack) < nchars)
100*a9fa9459Szrj     {
101*a9fa9459Szrj       size_t oldc;
102*a9fa9459Szrj       size_t newc;
103*a9fa9459Szrj 
104*a9fa9459Szrj       /* Try to allocate a bit more than needed right now.  But don't do
105*a9fa9459Szrj          this if we would waste too much memory.  Especially necessary
106*a9fa9459Szrj          for extremely big (like 2GB initialized) frags.  */
107*a9fa9459Szrj       if (nchars < 0x10000)
108*a9fa9459Szrj         newc = 2 * nchars;
109*a9fa9459Szrj       else
110*a9fa9459Szrj         newc = nchars + 0x10000;
111*a9fa9459Szrj       newc += SIZEOF_STRUCT_FRAG;
112*a9fa9459Szrj 
113*a9fa9459Szrj       /* Check for possible overflow.  */
114*a9fa9459Szrj       if (newc < nchars)
115*a9fa9459Szrj         as_fatal (_("can't extend frag %lu chars"), (unsigned long) nchars);
116*a9fa9459Szrj 
117*a9fa9459Szrj       /* Force to allocate at least NEWC bytes, but not less than the
118*a9fa9459Szrj          default.  */
119*a9fa9459Szrj       oldc = obstack_chunk_size (&frchain_now->frch_obstack);
120*a9fa9459Szrj       if (newc > oldc)
121*a9fa9459Szrj 	obstack_chunk_size (&frchain_now->frch_obstack) = newc;
122*a9fa9459Szrj 
123*a9fa9459Szrj       while (obstack_room (&frchain_now->frch_obstack) < nchars)
124*a9fa9459Szrj         {
125*a9fa9459Szrj           /* Not enough room in this frag.  Close it and start a new one.
126*a9fa9459Szrj              This must be done in a loop because the created frag may not
127*a9fa9459Szrj              be big enough if the current obstack chunk is used.  */
128*a9fa9459Szrj           frag_wane (frag_now);
129*a9fa9459Szrj           frag_new (0);
130*a9fa9459Szrj         }
131*a9fa9459Szrj 
132*a9fa9459Szrj       /* Restore the old chunk size.  */
133*a9fa9459Szrj       obstack_chunk_size (&frchain_now->frch_obstack) = oldc;
134*a9fa9459Szrj     }
135*a9fa9459Szrj }
136*a9fa9459Szrj 
137*a9fa9459Szrj /* Call this to close off a completed frag, and start up a new (empty)
138*a9fa9459Szrj    frag, in the same subsegment as the old frag.
139*a9fa9459Szrj    [frchain_now remains the same but frag_now is updated.]
140*a9fa9459Szrj    Because this calculates the correct value of fr_fix by
141*a9fa9459Szrj    looking at the obstack 'frags', it needs to know how many
142*a9fa9459Szrj    characters at the end of the old frag belong to the maximal
143*a9fa9459Szrj    variable part;  The rest must belong to fr_fix.
144*a9fa9459Szrj    It doesn't actually set up the old frag's fr_var.  You may have
145*a9fa9459Szrj    set fr_var == 1, but allocated 10 chars to the end of the frag;
146*a9fa9459Szrj    In this case you pass old_frags_var_max_size == 10.
147*a9fa9459Szrj    In fact, you may use fr_var for something totally unrelated to the
148*a9fa9459Szrj    size of the variable part of the frag;  None of the generic frag
149*a9fa9459Szrj    handling code makes use of fr_var.
150*a9fa9459Szrj 
151*a9fa9459Szrj    Make a new frag, initialising some components. Link new frag at end
152*a9fa9459Szrj    of frchain_now.  */
153*a9fa9459Szrj 
154*a9fa9459Szrj void
frag_new(size_t old_frags_var_max_size)155*a9fa9459Szrj frag_new (size_t old_frags_var_max_size
156*a9fa9459Szrj 	  /* Number of chars (already allocated on obstack frags) in
157*a9fa9459Szrj 	     variable_length part of frag.  */)
158*a9fa9459Szrj {
159*a9fa9459Szrj   fragS *former_last_fragP;
160*a9fa9459Szrj   frchainS *frchP;
161*a9fa9459Szrj 
162*a9fa9459Szrj   gas_assert (frchain_now->frch_last == frag_now);
163*a9fa9459Szrj 
164*a9fa9459Szrj   /* Fix up old frag's fr_fix.  */
165*a9fa9459Szrj   frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
166*a9fa9459Szrj   /* Make sure its type is valid.  */
167*a9fa9459Szrj   gas_assert (frag_now->fr_type != 0);
168*a9fa9459Szrj 
169*a9fa9459Szrj   /* This will align the obstack so the next struct we allocate on it
170*a9fa9459Szrj      will begin at a correct boundary.  */
171*a9fa9459Szrj   obstack_finish (&frchain_now->frch_obstack);
172*a9fa9459Szrj   frchP = frchain_now;
173*a9fa9459Szrj   know (frchP);
174*a9fa9459Szrj   former_last_fragP = frchP->frch_last;
175*a9fa9459Szrj   gas_assert (former_last_fragP != 0);
176*a9fa9459Szrj   gas_assert (former_last_fragP == frag_now);
177*a9fa9459Szrj   frag_now = frag_alloc (&frchP->frch_obstack);
178*a9fa9459Szrj 
179*a9fa9459Szrj   frag_now->fr_file = as_where (&frag_now->fr_line);
180*a9fa9459Szrj 
181*a9fa9459Szrj   /* Generally, frag_now->points to an address rounded up to next
182*a9fa9459Szrj      alignment.  However, characters will add to obstack frags
183*a9fa9459Szrj      IMMEDIATELY after the struct frag, even if they are not starting
184*a9fa9459Szrj      at an alignment address.  */
185*a9fa9459Szrj   former_last_fragP->fr_next = frag_now;
186*a9fa9459Szrj   frchP->frch_last = frag_now;
187*a9fa9459Szrj 
188*a9fa9459Szrj #ifndef NO_LISTING
189*a9fa9459Szrj   {
190*a9fa9459Szrj     extern struct list_info_struct *listing_tail;
191*a9fa9459Szrj     frag_now->line = listing_tail;
192*a9fa9459Szrj   }
193*a9fa9459Szrj #endif
194*a9fa9459Szrj 
195*a9fa9459Szrj   gas_assert (frchain_now->frch_last == frag_now);
196*a9fa9459Szrj 
197*a9fa9459Szrj   frag_now->fr_next = NULL;
198*a9fa9459Szrj }
199*a9fa9459Szrj 
200*a9fa9459Szrj /* Start a new frag unless we have n more chars of room in the current frag.
201*a9fa9459Szrj    Close off the old frag with a .fill 0.
202*a9fa9459Szrj 
203*a9fa9459Szrj    Return the address of the 1st char to write into. Advance
204*a9fa9459Szrj    frag_now_growth past the new chars.  */
205*a9fa9459Szrj 
206*a9fa9459Szrj char *
frag_more(size_t nchars)207*a9fa9459Szrj frag_more (size_t nchars)
208*a9fa9459Szrj {
209*a9fa9459Szrj   char *retval;
210*a9fa9459Szrj 
211*a9fa9459Szrj   frag_alloc_check (&frchain_now->frch_obstack);
212*a9fa9459Szrj   frag_grow (nchars);
213*a9fa9459Szrj   retval = obstack_next_free (&frchain_now->frch_obstack);
214*a9fa9459Szrj   obstack_blank_fast (&frchain_now->frch_obstack, nchars);
215*a9fa9459Szrj   return retval;
216*a9fa9459Szrj }
217*a9fa9459Szrj 
218*a9fa9459Szrj /* Close the current frag, setting its fields for a relaxable frag.  Start a
219*a9fa9459Szrj    new frag.  */
220*a9fa9459Szrj 
221*a9fa9459Szrj static void
frag_var_init(relax_stateT type,size_t max_chars,size_t var,relax_substateT subtype,symbolS * symbol,offsetT offset,char * opcode)222*a9fa9459Szrj frag_var_init (relax_stateT type, size_t max_chars, size_t var,
223*a9fa9459Szrj 	       relax_substateT subtype, symbolS *symbol, offsetT offset,
224*a9fa9459Szrj                char *opcode)
225*a9fa9459Szrj {
226*a9fa9459Szrj   frag_now->fr_var = var;
227*a9fa9459Szrj   frag_now->fr_type = type;
228*a9fa9459Szrj   frag_now->fr_subtype = subtype;
229*a9fa9459Szrj   frag_now->fr_symbol = symbol;
230*a9fa9459Szrj   frag_now->fr_offset = offset;
231*a9fa9459Szrj   frag_now->fr_opcode = opcode;
232*a9fa9459Szrj #ifdef USING_CGEN
233*a9fa9459Szrj   frag_now->fr_cgen.insn = 0;
234*a9fa9459Szrj   frag_now->fr_cgen.opindex = 0;
235*a9fa9459Szrj   frag_now->fr_cgen.opinfo = 0;
236*a9fa9459Szrj #endif
237*a9fa9459Szrj #ifdef TC_FRAG_INIT
238*a9fa9459Szrj   TC_FRAG_INIT (frag_now);
239*a9fa9459Szrj #endif
240*a9fa9459Szrj   frag_now->fr_file = as_where (&frag_now->fr_line);
241*a9fa9459Szrj 
242*a9fa9459Szrj   frag_new (max_chars);
243*a9fa9459Szrj }
244*a9fa9459Szrj 
245*a9fa9459Szrj /* Start a new frag unless we have max_chars more chars of room in the
246*a9fa9459Szrj    current frag.  Close off the old frag with a .fill 0.
247*a9fa9459Szrj 
248*a9fa9459Szrj    Set up a machine_dependent relaxable frag, then start a new frag.
249*a9fa9459Szrj    Return the address of the 1st char of the var part of the old frag
250*a9fa9459Szrj    to write into.  */
251*a9fa9459Szrj 
252*a9fa9459Szrj char *
frag_var(relax_stateT type,size_t max_chars,size_t var,relax_substateT subtype,symbolS * symbol,offsetT offset,char * opcode)253*a9fa9459Szrj frag_var (relax_stateT type, size_t max_chars, size_t var,
254*a9fa9459Szrj 	  relax_substateT subtype, symbolS *symbol, offsetT offset,
255*a9fa9459Szrj 	  char *opcode)
256*a9fa9459Szrj {
257*a9fa9459Szrj   char *retval;
258*a9fa9459Szrj 
259*a9fa9459Szrj   frag_grow (max_chars);
260*a9fa9459Szrj   retval = obstack_next_free (&frchain_now->frch_obstack);
261*a9fa9459Szrj   obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
262*a9fa9459Szrj   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
263*a9fa9459Szrj   return retval;
264*a9fa9459Szrj }
265*a9fa9459Szrj 
266*a9fa9459Szrj /* OVE: This variant of frag_var assumes that space for the tail has been
267*a9fa9459Szrj 	allocated by caller.
268*a9fa9459Szrj 	No call to frag_grow is done.  */
269*a9fa9459Szrj 
270*a9fa9459Szrj char *
frag_variant(relax_stateT type,size_t max_chars,size_t var,relax_substateT subtype,symbolS * symbol,offsetT offset,char * opcode)271*a9fa9459Szrj frag_variant (relax_stateT type, size_t max_chars, size_t var,
272*a9fa9459Szrj 	      relax_substateT subtype, symbolS *symbol, offsetT offset,
273*a9fa9459Szrj 	      char *opcode)
274*a9fa9459Szrj {
275*a9fa9459Szrj   char *retval;
276*a9fa9459Szrj 
277*a9fa9459Szrj   retval = obstack_next_free (&frchain_now->frch_obstack);
278*a9fa9459Szrj   frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode);
279*a9fa9459Szrj 
280*a9fa9459Szrj   return retval;
281*a9fa9459Szrj }
282*a9fa9459Szrj 
283*a9fa9459Szrj /* Reduce the variable end of a frag to a harmless state.  */
284*a9fa9459Szrj 
285*a9fa9459Szrj void
frag_wane(fragS * fragP)286*a9fa9459Szrj frag_wane (fragS *fragP)
287*a9fa9459Szrj {
288*a9fa9459Szrj   fragP->fr_type = rs_fill;
289*a9fa9459Szrj   fragP->fr_offset = 0;
290*a9fa9459Szrj   fragP->fr_var = 0;
291*a9fa9459Szrj }
292*a9fa9459Szrj 
293*a9fa9459Szrj /* Return the number of bytes by which the current frag can be grown.  */
294*a9fa9459Szrj 
295*a9fa9459Szrj size_t
frag_room(void)296*a9fa9459Szrj frag_room (void)
297*a9fa9459Szrj {
298*a9fa9459Szrj   return obstack_room (&frchain_now->frch_obstack);
299*a9fa9459Szrj }
300*a9fa9459Szrj 
301*a9fa9459Szrj /* Make an alignment frag.  The size of this frag will be adjusted to
302*a9fa9459Szrj    force the next frag to have the appropriate alignment.  ALIGNMENT
303*a9fa9459Szrj    is the power of two to which to align.  FILL_CHARACTER is the
304*a9fa9459Szrj    character to use to fill in any bytes which are skipped.  MAX is
305*a9fa9459Szrj    the maximum number of characters to skip when doing the alignment,
306*a9fa9459Szrj    or 0 if there is no maximum.  */
307*a9fa9459Szrj 
308*a9fa9459Szrj void
frag_align(int alignment,int fill_character,int max)309*a9fa9459Szrj frag_align (int alignment, int fill_character, int max)
310*a9fa9459Szrj {
311*a9fa9459Szrj   if (now_seg == absolute_section)
312*a9fa9459Szrj     {
313*a9fa9459Szrj       addressT new_off;
314*a9fa9459Szrj       addressT mask;
315*a9fa9459Szrj 
316*a9fa9459Szrj       mask = (~(addressT) 0) << alignment;
317*a9fa9459Szrj       new_off = (abs_section_offset + ~mask) & mask;
318*a9fa9459Szrj       if (max == 0 || new_off - abs_section_offset <= (addressT) max)
319*a9fa9459Szrj 	abs_section_offset = new_off;
320*a9fa9459Szrj     }
321*a9fa9459Szrj   else
322*a9fa9459Szrj     {
323*a9fa9459Szrj       char *p;
324*a9fa9459Szrj 
325*a9fa9459Szrj       p = frag_var (rs_align, 1, 1, (relax_substateT) max,
326*a9fa9459Szrj 		    (symbolS *) 0, (offsetT) alignment, (char *) 0);
327*a9fa9459Szrj       *p = fill_character;
328*a9fa9459Szrj     }
329*a9fa9459Szrj }
330*a9fa9459Szrj 
331*a9fa9459Szrj /* Make an alignment frag like frag_align, but fill with a repeating
332*a9fa9459Szrj    pattern rather than a single byte.  ALIGNMENT is the power of two
333*a9fa9459Szrj    to which to align.  FILL_PATTERN is the fill pattern to repeat in
334*a9fa9459Szrj    the bytes which are skipped.  N_FILL is the number of bytes in
335*a9fa9459Szrj    FILL_PATTERN.  MAX is the maximum number of characters to skip when
336*a9fa9459Szrj    doing the alignment, or 0 if there is no maximum.  */
337*a9fa9459Szrj 
338*a9fa9459Szrj void
frag_align_pattern(int alignment,const char * fill_pattern,size_t n_fill,int max)339*a9fa9459Szrj frag_align_pattern (int alignment, const char *fill_pattern,
340*a9fa9459Szrj 		    size_t n_fill, int max)
341*a9fa9459Szrj {
342*a9fa9459Szrj   char *p;
343*a9fa9459Szrj 
344*a9fa9459Szrj   p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
345*a9fa9459Szrj 		(symbolS *) 0, (offsetT) alignment, (char *) 0);
346*a9fa9459Szrj   memcpy (p, fill_pattern, n_fill);
347*a9fa9459Szrj }
348*a9fa9459Szrj 
349*a9fa9459Szrj /* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
350*a9fa9459Szrj    instruction so that the disassembler does not choke on it.  */
351*a9fa9459Szrj #ifndef NOP_OPCODE
352*a9fa9459Szrj #define NOP_OPCODE 0x00
353*a9fa9459Szrj #endif
354*a9fa9459Szrj 
355*a9fa9459Szrj /* Use this to restrict the amount of memory allocated for representing
356*a9fa9459Szrj    the alignment code.  Needs to be large enough to hold any fixed sized
357*a9fa9459Szrj    prologue plus the replicating portion.  */
358*a9fa9459Szrj #ifndef MAX_MEM_FOR_RS_ALIGN_CODE
359*a9fa9459Szrj   /* Assume that if HANDLE_ALIGN is not defined then no special action
360*a9fa9459Szrj      is required to code fill, which means that we get just repeat the
361*a9fa9459Szrj      one NOP_OPCODE byte.  */
362*a9fa9459Szrj # ifndef HANDLE_ALIGN
363*a9fa9459Szrj #  define MAX_MEM_FOR_RS_ALIGN_CODE  1
364*a9fa9459Szrj # else
365*a9fa9459Szrj #  define MAX_MEM_FOR_RS_ALIGN_CODE  ((1 << alignment) - 1)
366*a9fa9459Szrj # endif
367*a9fa9459Szrj #endif
368*a9fa9459Szrj 
369*a9fa9459Szrj void
frag_align_code(int alignment,int max)370*a9fa9459Szrj frag_align_code (int alignment, int max)
371*a9fa9459Szrj {
372*a9fa9459Szrj   char *p;
373*a9fa9459Szrj 
374*a9fa9459Szrj   p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
375*a9fa9459Szrj 		(relax_substateT) max, (symbolS *) 0,
376*a9fa9459Szrj 		(offsetT) alignment, (char *) 0);
377*a9fa9459Szrj   *p = NOP_OPCODE;
378*a9fa9459Szrj }
379*a9fa9459Szrj 
380*a9fa9459Szrj addressT
frag_now_fix_octets(void)381*a9fa9459Szrj frag_now_fix_octets (void)
382*a9fa9459Szrj {
383*a9fa9459Szrj   if (now_seg == absolute_section)
384*a9fa9459Szrj     return abs_section_offset;
385*a9fa9459Szrj 
386*a9fa9459Szrj   return ((char *) obstack_next_free (&frchain_now->frch_obstack)
387*a9fa9459Szrj 	  - frag_now->fr_literal);
388*a9fa9459Szrj }
389*a9fa9459Szrj 
390*a9fa9459Szrj addressT
frag_now_fix(void)391*a9fa9459Szrj frag_now_fix (void)
392*a9fa9459Szrj {
393*a9fa9459Szrj   return frag_now_fix_octets () / OCTETS_PER_BYTE;
394*a9fa9459Szrj }
395*a9fa9459Szrj 
396*a9fa9459Szrj void
frag_append_1_char(int datum)397*a9fa9459Szrj frag_append_1_char (int datum)
398*a9fa9459Szrj {
399*a9fa9459Szrj   frag_alloc_check (&frchain_now->frch_obstack);
400*a9fa9459Szrj   if (obstack_room (&frchain_now->frch_obstack) <= 1)
401*a9fa9459Szrj     {
402*a9fa9459Szrj       frag_wane (frag_now);
403*a9fa9459Szrj       frag_new (0);
404*a9fa9459Szrj     }
405*a9fa9459Szrj   obstack_1grow (&frchain_now->frch_obstack, datum);
406*a9fa9459Szrj }
407*a9fa9459Szrj 
408*a9fa9459Szrj /* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
409*a9fa9459Szrj    their start addresses.  Set OFFSET to the difference in address
410*a9fa9459Szrj    not already accounted for in the frag FR_ADDRESS.  */
411*a9fa9459Szrj 
412*a9fa9459Szrj bfd_boolean
frag_offset_fixed_p(const fragS * frag1,const fragS * frag2,offsetT * offset)413*a9fa9459Szrj frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
414*a9fa9459Szrj {
415*a9fa9459Szrj   const fragS *frag;
416*a9fa9459Szrj   offsetT off;
417*a9fa9459Szrj 
418*a9fa9459Szrj   /* Start with offset initialised to difference between the two frags.
419*a9fa9459Szrj      Prior to assigning frag addresses this will be zero.  */
420*a9fa9459Szrj   off = frag1->fr_address - frag2->fr_address;
421*a9fa9459Szrj   if (frag1 == frag2)
422*a9fa9459Szrj     {
423*a9fa9459Szrj       *offset = off;
424*a9fa9459Szrj       return TRUE;
425*a9fa9459Szrj     }
426*a9fa9459Szrj 
427*a9fa9459Szrj   /* Maybe frag2 is after frag1.  */
428*a9fa9459Szrj   frag = frag1;
429*a9fa9459Szrj   while (frag->fr_type == rs_fill)
430*a9fa9459Szrj     {
431*a9fa9459Szrj       off += frag->fr_fix + frag->fr_offset * frag->fr_var;
432*a9fa9459Szrj       frag = frag->fr_next;
433*a9fa9459Szrj       if (frag == NULL)
434*a9fa9459Szrj 	break;
435*a9fa9459Szrj       if (frag == frag2)
436*a9fa9459Szrj 	{
437*a9fa9459Szrj 	  *offset = off;
438*a9fa9459Szrj 	  return TRUE;
439*a9fa9459Szrj 	}
440*a9fa9459Szrj     }
441*a9fa9459Szrj 
442*a9fa9459Szrj   /* Maybe frag1 is after frag2.  */
443*a9fa9459Szrj   off = frag1->fr_address - frag2->fr_address;
444*a9fa9459Szrj   frag = frag2;
445*a9fa9459Szrj   while (frag->fr_type == rs_fill)
446*a9fa9459Szrj     {
447*a9fa9459Szrj       off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
448*a9fa9459Szrj       frag = frag->fr_next;
449*a9fa9459Szrj       if (frag == NULL)
450*a9fa9459Szrj 	break;
451*a9fa9459Szrj       if (frag == frag1)
452*a9fa9459Szrj 	{
453*a9fa9459Szrj 	  *offset = off;
454*a9fa9459Szrj 	  return TRUE;
455*a9fa9459Szrj 	}
456*a9fa9459Szrj     }
457*a9fa9459Szrj 
458*a9fa9459Szrj   return FALSE;
459*a9fa9459Szrj }
460