|
|
1.1 root 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.