Subversion Repositories Kolibri OS

Rev

Rev 5222 | Details | Compare with Previous | Last modification | View Log | RSS feed

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