home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / frags.c < prev    next >
C/C++ Source or Header  |  1997-01-24  |  7KB  |  246 lines

  1. /* frags.c - manage frags -
  2.    Copyright (C) 1987 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 1, 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
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <string.h>
  21. #include "as.h"
  22. #include "sections.h"
  23. #include "obstack.h"
  24. #include "frags.h"
  25. #include "messages.h"
  26.  
  27. struct obstack frags = { 0 };    /* All, and only, frags live here. */
  28.  
  29. fragS *frag_now = NULL;    /* -> current frag we are building. */
  30.  
  31. fragS zero_address_frag = {
  32.     0,            /* fr_address */
  33.     NULL,            /* fr_next */
  34.     0,            /* fr_fix */
  35.     0,            /* fr_var */
  36.     0,            /* fr_symbol */
  37.     0,            /* fr_offset */
  38.     NULL,            /* fr_opcode */
  39.     rs_fill,        /* fr_type */
  40.     0,            /* fr_subtype */
  41.     {0}            /* fr_literal [0] */
  42. };
  43.  
  44.  
  45. /*
  46.  *            frag_grow()
  47.  *
  48.  * Internal.
  49.  * Try to augment current frag by nchars chars.
  50.  * If there is no room, close of the current frag with a ".fill 0"
  51.  * and begin a new frag. Unless the new frag has nchars chars available
  52.  * do not return. Do not set up any fields of *now_frag.
  53.  */
  54. static
  55. void
  56. frag_grow(
  57. int nchars)
  58. {
  59.     if(frags.chunk_size == 0){
  60.        know(flagseen['n']);
  61.        as_fatal("with -n a section directive must be seen before assembly "
  62.         "can begin");
  63.     }
  64.     if (obstack_room (&frags) < nchars) {
  65.     unsigned int n,oldn;
  66.     long oldc;
  67.  
  68.     frag_wane (frag_now);
  69.     frag_new (0);
  70.     oldn=(unsigned)-1;
  71.     oldc=frags.chunk_size;
  72.     frags.chunk_size=2*nchars;
  73.     while((n=obstack_room(&frags))<nchars && n<oldn) {
  74.         frag_wane(frag_now);
  75.         frag_new(0);
  76.         oldn=n;
  77.     }
  78.     frags.chunk_size=oldc;
  79.     }
  80.     if (obstack_room (&frags) < nchars)
  81.     as_fatal ("Can't extend frag %d. chars", nchars);
  82. }
  83.  
  84. /*
  85.  *            frag_new()
  86.  *
  87.  * Call this to close off a completed frag, and start up a new (empty)
  88.  * frag, in the same subsegment as the old frag.
  89.  * [frchain_now remains the same but frag_now is updated.]
  90.  * Because this calculates the correct value of fr_fix by
  91.  * looking at the obstack 'frags', it needs to know how many
  92.  * characters at the end of the old frag belong to (the maximal)
  93.  * fr_var: the rest must belong to fr_fix.
  94.  * It doesn't actually set up the old frag's fr_var: you may have
  95.  * set fr_var == 1, but allocated 10 chars to the end of the frag:
  96.  * in this case you pass old_frags_var_max_size == 10.
  97.  *
  98.  * Make a new frag, initialising some components. Link new frag at end
  99.  * of frchain_now.
  100.  */
  101. void
  102. frag_new(
  103. int old_frags_var_max_size)    /* Number of chars (already allocated on obstack
  104.                    frags) in variable_length part of frag. */
  105. {
  106.     register    fragS * former_last_fragP;
  107. /*    char   *throw_away_pointer; JF unused */
  108.     register    frchainS * frchP;
  109.     long    tmp;        /* JF */
  110.  
  111.     if(frags.chunk_size == 0){
  112.        know(flagseen['n']);
  113.        as_fatal("with -n a section directive must be seen before assembly "
  114.         "can begin");
  115.     }
  116.  
  117.     frag_now->fr_fix = (char *) (obstack_next_free (&frags)) -
  118.     (frag_now->fr_literal) - old_frags_var_max_size;
  119.  /* Fix up old frag's fr_fix. */
  120.  
  121.     obstack_finish (&frags);
  122.  /* This will align the obstack so the */
  123.  /* next struct we allocate on it will */
  124.  /* begin at a correct boundary. */
  125.     frchP = frchain_now;
  126.     know (frchP);
  127.     former_last_fragP = frchP->frch_last;
  128.     know (former_last_fragP);
  129.     know (former_last_fragP == frag_now);
  130.     obstack_blank (&frags, SIZEOF_STRUCT_FRAG);
  131.  /* We expect this will begin at a correct */
  132.  /* boundary for a struct. */
  133.     tmp=obstack_alignment_mask(&frags);
  134.     obstack_alignment_mask(&frags)=0;        /* Turn off alignment */
  135.                             /* If we ever hit a machine
  136.                            where strings must be
  137.                            aligned, we Lose Big */
  138.  frag_now=(fragS *)obstack_finish(&frags);
  139.     obstack_alignment_mask(&frags)=tmp;        /* Restore alignment */
  140.  
  141.  /* Just in case we don't get zero'd bytes */
  142.  memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
  143.  
  144. /*    obstack_unaligned_done (&frags, &frag_now); */
  145. /*    know (frags.obstack_c_next_free == frag_now->fr_literal); */
  146.  /* Generally, frag_now->points to an */
  147.  /* address rounded up to next alignment. */
  148.  /* However, characters will add to obstack */
  149.  /* frags IMMEDIATELY after the struct frag, */
  150.  /* even if they are not starting at an */
  151.  /* alignment address. */
  152.     former_last_fragP->fr_next = frag_now;
  153.     frchP->frch_last = frag_now;
  154.     frag_now->fr_next = NULL;
  155. }                /* frag_new() */
  156.  
  157. /*
  158.  *            frag_more()
  159.  *
  160.  * Start a new frag unless we have n more chars of room in the current frag.
  161.  * Close off the old frag with a .fill 0.
  162.  *
  163.  * Return the address of the 1st char to write into. Advance
  164.  * frag_now_growth past the new chars.
  165.  */
  166. char *
  167. frag_more(
  168. int nchars)
  169. {
  170.     register char  *retval;
  171.  
  172.     frag_grow (nchars);
  173.     retval = obstack_next_free (&frags);
  174.     obstack_blank_fast (&frags, nchars);
  175.     return (retval);
  176. }                /* frag_more() */
  177.  
  178. /*
  179.  *            frag_var()
  180.  *
  181.  * Start a new frag unless we have max_chars more chars of room in the current frag.
  182.  * Close off the old frag with a .fill 0.
  183.  *
  184.  * Set up a machine_dependent relaxable frag, then start a new frag.
  185.  * Return the address of the 1st char of the var part of the old frag
  186.  * to write into.
  187.  */
  188. char *
  189. frag_var(
  190. relax_stateT type,
  191. int max_chars,
  192. int var,
  193. relax_substateT subtype,
  194. symbolS *symbol,
  195. long offset,
  196. char *opcode)
  197. {
  198.     register char  *retval;
  199.  
  200.     frag_grow (max_chars);
  201.     retval = obstack_next_free (&frags);
  202.     obstack_blank_fast (&frags, max_chars);
  203.     frag_now->fr_var = var;
  204.     frag_now->fr_type = type;
  205.     frag_now->fr_subtype = subtype;
  206.     frag_now->fr_symbol = symbol;
  207.     frag_now->fr_offset = offset;
  208.     frag_now->fr_opcode = opcode;
  209.     frag_new (max_chars);
  210.     return (retval);
  211. }                /* frag_var() */
  212.  
  213. /*
  214.  *            frag_wane()
  215.  *
  216.  * Reduce the variable end of a frag to a harmless state.
  217.  */
  218. void
  219. frag_wane(
  220. fragS *fragP)
  221. {
  222.     fragP->fr_type = rs_fill;
  223.     fragP->fr_offset = 0;
  224.     fragP->fr_var = 0;
  225. }
  226.  
  227. /*
  228.  *            frag_align()
  229.  *
  230.  * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);".
  231.  * Foo & bar are absolute integers.
  232.  *
  233.  * Call to close off the current frag with a ".align", then start a new
  234.  * (so far empty) frag, in the same subsegment as the last frag.
  235.  */
  236. void
  237. frag_align(
  238. int alignment,
  239. int fill_character)
  240. {
  241.     *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0,
  242.  (long)alignment, (char *)0)) = fill_character;
  243. }
  244.  
  245. /* end: frags.c */
  246.