X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Ffrags.c;h=8d7ed2f58ab455b9aa8a19f7666fd4dcf0fe2c48;hb=3c1bae7f0bd139bca8cdcbaebd633e1909b7c815;hp=240b2ee63a01f5671ac90d6cca308715a647791a;hpb=252b5132c753830d5fd56823373aed85f2a0db63;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/frags.c b/gas/frags.c index 240b2ee63a..8d7ed2f58a 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -1,5 +1,6 @@ /* frags.c - manage frags - - Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998 + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -27,6 +28,7 @@ extern fragS zero_address_frag; extern fragS bss_address_frag; /* Initialization for frag routines. */ + void frag_init () { @@ -37,6 +39,7 @@ frag_init () /* Allocate a frag on the specified obstack. Call this routine from everywhere else, so that all the weird alignment hackery can be done in just one place. */ + fragS * frag_alloc (ob) struct obstack *ob; @@ -53,15 +56,12 @@ frag_alloc (ob) return ptr; } -/* - * frag_grow() - * - * Try to augment current frag by nchars chars. - * If there is no room, close of the current frag with a ".fill 0" - * and begin a new frag. Unless the new frag has nchars chars available - * do not return. Do not set up any fields of *now_frag. - */ -void +/* Try to augment current frag by nchars chars. + If there is no room, close of the current frag with a ".fill 0" + and begin a new frag. Unless the new frag has nchars chars available + do not return. Do not set up any fields of *now_frag. */ + +void frag_grow (nchars) unsigned int nchars; { @@ -74,38 +74,40 @@ frag_grow (nchars) frag_new (0); oldc = frchain_now->frch_obstack.chunk_size; frchain_now->frch_obstack.chunk_size = 2 * nchars + SIZEOF_STRUCT_FRAG; - while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars) - { - frag_wane (frag_now); - frag_new (0); - } + if (frchain_now->frch_obstack.chunk_size > 0) + while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars + && (unsigned long) frchain_now->frch_obstack.chunk_size > nchars) + { + frag_wane (frag_now); + frag_new (0); + } frchain_now->frch_obstack.chunk_size = oldc; } if (obstack_room (&frchain_now->frch_obstack) < nchars) - as_fatal (_("Can't extend frag %d. chars"), nchars); + as_fatal (_("can't extend frag %u chars"), nchars); } -/* - * frag_new() - * - * Call this to close off a completed frag, and start up a new (empty) - * frag, in the same subsegment as the old frag. - * [frchain_now remains the same but frag_now is updated.] - * Because this calculates the correct value of fr_fix by - * looking at the obstack 'frags', it needs to know how many - * characters at the end of the old frag belong to (the maximal) - * fr_var: the rest must belong to fr_fix. - * It doesn't actually set up the old frag's fr_var: you may have - * set fr_var == 1, but allocated 10 chars to the end of the frag: - * in this case you pass old_frags_var_max_size == 10. - * - * Make a new frag, initialising some components. Link new frag at end - * of frchain_now. - */ -void +/* Call this to close off a completed frag, and start up a new (empty) + frag, in the same subsegment as the old frag. + [frchain_now remains the same but frag_now is updated.] + Because this calculates the correct value of fr_fix by + looking at the obstack 'frags', it needs to know how many + characters at the end of the old frag belong to the maximal + variable part; The rest must belong to fr_fix. + It doesn't actually set up the old frag's fr_var. You may have + set fr_var == 1, but allocated 10 chars to the end of the frag; + In this case you pass old_frags_var_max_size == 10. + In fact, you may use fr_var for something totally unrelated to the + size of the variable part of the frag; None of the generic frag + handling code makes use of fr_var. + + Make a new frag, initialising some components. Link new frag at end + of frchain_now. */ + +void frag_new (old_frags_var_max_size) /* Number of chars (already allocated on obstack frags) in - variable_length part of frag. */ + variable_length part of frag. */ int old_frags_var_max_size; { fragS *former_last_fragP; @@ -114,12 +116,12 @@ frag_new (old_frags_var_max_size) assert (frchain_now->frch_last == frag_now); /* Fix up old frag's fr_fix. */ - frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size; + frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size; /* Make sure its type is valid. */ assert (frag_now->fr_type != 0); /* This will align the obstack so the next struct we allocate on it - will begin at a correct boundary. */ + will begin at a correct boundary. */ obstack_finish (&frchain_now->frch_obstack); frchP = frchain_now; know (frchP); @@ -133,7 +135,7 @@ frag_new (old_frags_var_max_size) /* Generally, frag_now->points to an address rounded up to next alignment. However, characters will add to obstack frags IMMEDIATELY after the struct frag, even if they are not starting - at an alignment address. */ + at an alignment address. */ former_last_fragP->fr_next = frag_now; frchP->frch_last = frag_now; @@ -147,17 +149,13 @@ frag_new (old_frags_var_max_size) assert (frchain_now->frch_last == frag_now); frag_now->fr_next = NULL; -} /* frag_new() */ +} -/* - * frag_more() - * - * Start a new frag unless we have n more chars of room in the current frag. - * Close off the old frag with a .fill 0. - * - * Return the address of the 1st char to write into. Advance - * frag_now_growth past the new chars. - */ +/* Start a new frag unless we have n more chars of room in the current frag. + Close off the old frag with a .fill 0. + + Return the address of the 1st char to write into. Advance + frag_now_growth past the new chars. */ char * frag_more (nchars) @@ -181,18 +179,14 @@ frag_more (nchars) retval = obstack_next_free (&frchain_now->frch_obstack); obstack_blank_fast (&frchain_now->frch_obstack, nchars); return (retval); -} /* frag_more() */ +} -/* - * frag_var() - * - * Start a new frag unless we have max_chars more chars of room in the current frag. - * Close off the old frag with a .fill 0. - * - * Set up a machine_dependent relaxable frag, then start a new frag. - * Return the address of the 1st char of the var part of the old frag - * to write into. - */ +/* Start a new frag unless we have max_chars more chars of room in the + current frag. Close off the old frag with a .fill 0. + + Set up a machine_dependent relaxable frag, then start a new frag. + Return the address of the 1st char of the var part of the old frag + to write into. */ char * frag_var (type, max_chars, var, subtype, symbol, offset, opcode) @@ -228,13 +222,9 @@ frag_var (type, max_chars, var, subtype, symbol, offset, opcode) return (retval); } -/* - * frag_variant() - * - * OVE: This variant of frag_var assumes that space for the tail has been - * allocated by caller. - * No call to frag_grow is done. - */ +/* OVE: This variant of frag_var assumes that space for the tail has been + allocated by caller. + No call to frag_grow is done. */ char * frag_variant (type, max_chars, var, subtype, symbol, offset, opcode) @@ -266,14 +256,11 @@ frag_variant (type, max_chars, var, subtype, symbol, offset, opcode) as_where (&frag_now->fr_file, &frag_now->fr_line); frag_new (max_chars); return (retval); -} /* frag_variant() */ +} -/* - * frag_wane() - * - * Reduce the variable end of a frag to a harmless state. - */ -void +/* Reduce the variable end of a frag to a harmless state. */ + +void frag_wane (fragP) register fragS *fragP; { @@ -289,7 +276,7 @@ frag_wane (fragP) the maximum number of characters to skip when doing the alignment, or 0 if there is no maximum. */ -void +void frag_align (alignment, fill_character, max) int alignment; int fill_character; @@ -298,9 +285,10 @@ frag_align (alignment, fill_character, max) if (now_seg == absolute_section) { addressT new_off; + addressT mask; - new_off = ((abs_section_offset + alignment - 1) - &~ ((1 << alignment) - 1)); + mask = (~(addressT) 0) << alignment; + new_off = (abs_section_offset + ~mask) & mask; if (max == 0 || new_off - abs_section_offset <= (addressT) max) abs_section_offset = new_off; } @@ -321,7 +309,7 @@ frag_align (alignment, fill_character, max) FILL_PATTERN. MAX is the maximum number of characters to skip when doing the alignment, or 0 if there is no maximum. */ -void +void frag_align_pattern (alignment, fill_pattern, n_fill, max) int alignment; const char *fill_pattern; @@ -335,13 +323,53 @@ frag_align_pattern (alignment, fill_pattern, n_fill, max) memcpy (p, fill_pattern, n_fill); } +/* The NOP_OPCODE is for the alignment fill value. Fill it with a nop + instruction so that the disassembler does not choke on it. */ +#ifndef NOP_OPCODE +#define NOP_OPCODE 0x00 +#endif + +/* Use this to restrict the amount of memory allocated for representing + the alignment code. Needs to be large enough to hold any fixed sized + prologue plus the replicating portion. */ +#ifndef MAX_MEM_FOR_RS_ALIGN_CODE + /* Assume that if HANDLE_ALIGN is not defined then no special action + is required to code fill, which means that we get just repeat the + one NOP_OPCODE byte. */ +# ifndef HANDLE_ALIGN +# define MAX_MEM_FOR_RS_ALIGN_CODE 1 +# else +# define MAX_MEM_FOR_RS_ALIGN_CODE ((1 << alignment) - 1) +# endif +#endif + +void +frag_align_code (alignment, max) + int alignment; + int max; +{ + char *p; + + p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1, + (relax_substateT) max, (symbolS *) 0, + (offsetT) alignment, (char *) 0); + *p = NOP_OPCODE; +} + addressT -frag_now_fix () +frag_now_fix_octets () { if (now_seg == absolute_section) return abs_section_offset; - return (addressT) ((char*) obstack_next_free (&frchain_now->frch_obstack) - - frag_now->fr_literal); + + return ((char *) obstack_next_free (&frchain_now->frch_obstack) + - frag_now->fr_literal); +} + +addressT +frag_now_fix () +{ + return frag_now_fix_octets () / OCTETS_PER_BYTE; } void @@ -355,5 +383,3 @@ frag_append_1_char (datum) } obstack_1grow (&frchain_now->frch_obstack, datum); } - -/* end of frags.c */