X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fsymbols.c;h=c177902d7656d94e5cba6f2b4180e8dd1477acd8;hb=69bb683c6d92c902ab614222712d4716c15e7758;hp=a140046e6827f0eb7ae3d6d2ee61debb4e46046d;hpb=6efd877de5ab683fc5d7c216049f9f888bf18828;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/symbols.c b/gas/symbols.c index a140046e68..c177902d76 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1,6 +1,5 @@ /* symbols.c -symbol table- - - Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -18,6 +17,8 @@ along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* #define DEBUG_SYMS / * to debug symbol list maintenance */ + #include #include "as.h" @@ -28,45 +29,18 @@ #ifndef WORKING_DOT_WORD extern int new_broken_words; #endif -#ifdef VMS -extern char const_flag; -#endif -static -struct hash_control * - sy_hash; /* symbol-name => struct symbol pointer */ +/* symbol-name => struct symbol pointer */ +static struct hash_control *sy_hash; /* Below are commented in "symbols.h". */ -unsigned int local_bss_counter; symbolS *symbol_rootP; symbolS *symbol_lastP; symbolS abs_symbol; -symbolS *dot_text_symbol; -symbolS *dot_data_symbol; -symbolS *dot_bss_symbol; - struct obstack notes; -#if __STDC__ == 1 -static void fb_label_init (void); -#else /* not __STDC__ */ -static void fb_label_init (); -#endif /* not __STDC__ */ - -void -symbol_begin () -{ - symbol_lastP = NULL; - symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ - sy_hash = hash_new (); - memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol)); - S_SET_SEGMENT (&abs_symbol, SEG_ABSOLUTE); /* Can't initialise a union. Sigh. */ - local_bss_counter = 0; -#ifdef LOCAL_LABELS_FB - fb_label_init (); -#endif /* LOCAL_LABELS_FB */ -} +static void fb_label_init PARAMS ((void)); /* * symbol_new() @@ -86,10 +60,10 @@ symbol_begin () */ symbolS * -symbol_new (name, segment, value, frag) - char *name; /* It is copied, the caller can destroy/modify */ +symbol_new (name, segment, valu, frag) + CONST char *name; /* It is copied, the caller can destroy/modify */ segT segment; /* Segment identifier (SEG_) */ - long value; /* Symbol value */ + valueT valu; /* Symbol value */ fragS *frag; /* Associated fragment */ { unsigned int name_length; @@ -99,42 +73,46 @@ symbol_new (name, segment, value, frag) name_length = strlen (name) + 1; /* +1 for \0 */ obstack_grow (¬es, name, name_length); preserved_copy_of_name = obstack_finish (¬es); +#ifdef STRIP_UNDERSCORE + if (preserved_copy_of_name[0] == '_') + preserved_copy_of_name++; +#endif symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS)); /* symbol must be born in some fixed state. This seems as good as any. */ memset (symbolP, 0, sizeof (symbolS)); -#ifdef STRIP_UNDERSCORE - S_SET_NAME (symbolP, (*preserved_copy_of_name == '_' - ? preserved_copy_of_name + 1 - : preserved_copy_of_name)); -#else /* STRIP_UNDERSCORE */ + +#ifdef BFD_ASSEMBLER + symbolP->bsym = bfd_make_empty_symbol (stdoutput); + assert (symbolP->bsym != 0); + symbolP->bsym->udata = (PTR) symbolP; +#endif S_SET_NAME (symbolP, preserved_copy_of_name); -#endif /* STRIP_UNDERSCORE */ S_SET_SEGMENT (symbolP, segment); - S_SET_VALUE (symbolP, value); - /* symbol_clear_list_pointers(symbolP); uneeded if symbol is born zeroed. */ + S_SET_VALUE (symbolP, valu); + symbol_clear_list_pointers(symbolP); symbolP->sy_frag = frag; - /* krm: uneeded if symbol is born zeroed. - symbolP->sy_forward = NULL; *//* JF */ +#ifndef BFD_ASSEMBLER symbolP->sy_number = ~0; - symbolP->sy_name_offset = ~0; + symbolP->sy_name_offset = (unsigned int) ~0; +#endif /* - * Link to end of symbol chain. - */ + * Link to end of symbol chain. + */ symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP); obj_symbol_new_hook (symbolP); -#ifdef DEBUG - /* verify_symbol_chain(symbol_rootP, symbol_lastP); */ -#endif /* DEBUG */ +#ifdef DEBUG_SYMS + verify_symbol_chain(symbol_rootP, symbol_lastP); +#endif /* DEBUG_SYMS */ - return (symbolP); -} /* symbol_new() */ + return symbolP; +} /* @@ -154,7 +132,8 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ register symbolS *symbolP; /* symbol we are working with */ #ifdef LOCAL_LABELS_DOLLAR - /* Sun local labels go out of scope whenever a non-local symbol is defined. */ + /* Sun local labels go out of scope whenever a non-local symbol is + defined. */ if (*sym_name != 'L') dollar_label_clear (); @@ -168,9 +147,10 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ fragS *frag_tmp; char *frag_opcode; - extern md_short_jump_size; - extern md_long_jump_size; - possible_bytes = md_short_jump_size + new_broken_words * md_long_jump_size; + extern const int md_short_jump_size; + extern const int md_long_jump_size; + possible_bytes = (md_short_jump_size + + new_broken_words * md_long_jump_size); frag_tmp = frag_now; frag_opcode = frag_var (rs_broken_word, @@ -182,8 +162,11 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ NULL); /* We want to store the pointer to where to insert the jump table in the - fr_opcode of the rs_broken_word frag. This requires a little hackery */ - while (frag_tmp && (frag_tmp->fr_type != rs_broken_word || frag_tmp->fr_opcode)) + fr_opcode of the rs_broken_word frag. This requires a little + hackery. */ + while (frag_tmp + && (frag_tmp->fr_type != rs_broken_word + || frag_tmp->fr_opcode)) frag_tmp = frag_tmp->fr_next; know (frag_tmp); frag_tmp->fr_opcode = frag_opcode; @@ -196,40 +179,22 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ if ((symbolP = symbol_find (sym_name)) != 0) { -#ifdef VMS - /* - * If the new symbol is .comm AND it has a size of zero, - * we ignore it (i.e. the old symbol overrides it) - */ - if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)) && - ((obstack_next_free (&frags) - frag_now->fr_literal) == 0)) +#ifdef RESOLVE_SYMBOL_REDEFINITION + if (RESOLVE_SYMBOL_REDEFINITION (symbolP)) return; +#endif /* - * If the old symbol is .comm and it has a size of zero, - * we override it with the new symbol value. - */ - if ((symbolP->sy_type == (N_UNDF | N_EXT)) - && (S_GET_VALUE (symbolP) == 0)) - { - symbolP->sy_frag = frag_now; - symbolP->sy_other = const_flag; - S_SET_VALUE (symbolP, obstack_next_free (&frags) - frag_now->fr_literal); - symbolP->sy_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg); /* keep N_EXT bit */ - return; - } -#endif /* VMS */ - /* - * Now check for undefined symbols - */ + * Now check for undefined symbols + */ if (!S_IS_DEFINED (symbolP)) { if (S_GET_VALUE (symbolP) == 0) { symbolP->sy_frag = frag_now; -#ifdef VMS - symbolP->sy_other = const_flag; +#ifdef OBJ_VMS + S_GET_OTHER(symbolP) = const_flag; #endif - S_SET_VALUE (symbolP, obstack_next_free (&frags) - frag_now->fr_literal); + S_SET_VALUE (symbolP, (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal)); S_SET_SEGMENT (symbolP, now_seg); #ifdef N_UNDF know (N_UNDF == 0); @@ -239,73 +204,66 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ else { /* - * There are still several cases to check: - * A .comm/.lcomm symbol being redefined as - * initialized data is OK - * A .comm/.lcomm symbol being redefined with - * a larger size is also OK - * - * This only used to be allowed on VMS gas, but Sun cc - * on the sparc also depends on it. - */ - /* char New_Type = SEGMENT_TO_SYMBOL_TYPE((int) now_seg); */ -#ifdef MANY_SEGMENTS -#define SEG_BSS SEG_E2 -#define SEG_DATA SEG_E1 -#endif - - if (((!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP) && S_IS_EXTERNAL (symbolP)) - || (S_GET_SEGMENT (symbolP) == SEG_BSS)) - && ((now_seg == SEG_DATA) - || (now_seg == S_GET_SEGMENT (symbolP)))) + * There are still several cases to check: + * A .comm/.lcomm symbol being redefined as + * initialized data is OK + * A .comm/.lcomm symbol being redefined with + * a larger size is also OK + * + * This only used to be allowed on VMS gas, but Sun cc + * on the sparc also depends on it. + */ + + if (((!S_IS_DEBUG (symbolP) + && !S_IS_DEFINED (symbolP) + && S_IS_EXTERNAL (symbolP)) + || S_GET_SEGMENT (symbolP) == bss_section) + && (now_seg == data_section + || now_seg == S_GET_SEGMENT (symbolP))) { /* - * Select which of the 2 cases this is - */ - if (now_seg != SEG_DATA) + * Select which of the 2 cases this is + */ + if (now_seg != data_section) { /* - * New .comm for prev .comm symbol. - * If the new size is larger we just - * change its value. If the new size - * is smaller, we ignore this symbol - */ + * New .comm for prev .comm symbol. + * If the new size is larger we just + * change its value. If the new size + * is smaller, we ignore this symbol + */ if (S_GET_VALUE (symbolP) - < ((unsigned) (obstack_next_free (&frags) - frag_now->fr_literal))) + < ((unsigned) frag_now_fix ())) { - S_SET_VALUE (symbolP, - obstack_next_free (&frags) - - frag_now->fr_literal); + S_SET_VALUE (symbolP, (valueT) frag_now_fix ()); } } else { - /* - * It is a .comm/.lcomm being converted - * to initialized data. - */ + /* It is a .comm/.lcomm being converted to initialized + data. */ symbolP->sy_frag = frag_now; -#ifdef VMS - symbolP->sy_other = const_flag; -#endif /* VMS */ - S_SET_VALUE (symbolP, obstack_next_free (&frags) - frag_now->fr_literal); +#ifdef OBJ_VMS + S_GET_OTHER(symbolP) = const_flag; +#endif /* OBJ_VMS */ + S_SET_VALUE (symbolP, (valueT) frag_now_fix ()); S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */ } } else { -#ifdef OBJ_COFF - as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.", +#if defined (S_GET_OTHER) && defined (S_GET_DESC) + as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.", sym_name, segment_name (S_GET_SEGMENT (symbolP)), - S_GET_VALUE (symbolP)); -#else /* OBJ_COFF */ - as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%d.", + S_GET_OTHER (symbolP), S_GET_DESC (symbolP), + (long) S_GET_VALUE (symbolP)); +#else + as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.", sym_name, segment_name (S_GET_SEGMENT (symbolP)), - S_GET_OTHER (symbolP), S_GET_DESC (symbolP), - S_GET_VALUE (symbolP)); -#endif /* OBJ_COFF */ + (long) S_GET_VALUE (symbolP)); +#endif } } /* if the undefined symbol has no value */ } @@ -313,7 +271,7 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ { /* Don't blow up if the definition is the same */ if (!(frag_now == symbolP->sy_frag - && S_GET_VALUE (symbolP) == obstack_next_free (&frags) - frag_now->fr_literal + && S_GET_VALUE (symbolP) == (char*)obstack_next_free (&frags) - frag_now->fr_literal && S_GET_SEGMENT (symbolP) == now_seg)) as_fatal ("Symbol %s already defined.", sym_name); } /* if this symbol is not yet defined */ @@ -323,17 +281,19 @@ colon (sym_name) /* just seen "x:" - rattle symbols & frags */ { symbolP = symbol_new (sym_name, now_seg, - (valueT) (obstack_next_free (&frags) - frag_now->fr_literal), + (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal), frag_now); -#ifdef VMS +#ifdef OBJ_VMS S_SET_OTHER (symbolP, const_flag); -#endif /* VMS */ +#endif /* OBJ_VMS */ symbol_table_insert (symbolP); } /* if we have seen this symbol before */ - return; -} /* colon() */ +#ifdef tc_frob_label + tc_frob_label (symbolP); +#endif +} /* @@ -347,12 +307,12 @@ void symbol_table_insert (symbolP) symbolS *symbolP; { - register char *error_string; + register const char *error_string; know (symbolP); know (S_GET_NAME (symbolP)); - if (*(error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (char *) symbolP))) + if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP))) { as_fatal ("Inserting \"%s\" into symbol table failed: %s", S_GET_NAME (symbolP), error_string); @@ -385,20 +345,15 @@ symbol_find_or_make (name) symbolS * symbol_make (name) - char *name; + CONST char *name; { symbolS *symbolP; /* Let the machine description default it, e.g. for register names. */ - symbolP = md_undefined_symbol (name); + symbolP = md_undefined_symbol ((char *) name); if (!symbolP) - { - symbolP = symbol_new (name, - SEG_UNKNOWN, - 0, - &zero_address_frag); - } /* if md didn't build us a symbol */ + symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag); return (symbolP); } /* symbol_make() */ @@ -414,7 +369,7 @@ symbol_make (name) symbolS * symbol_find (name) - char *name; + CONST char *name; { #ifdef STRIP_UNDERSCORE return (symbol_find_base (name, 1)); @@ -425,7 +380,7 @@ symbol_find (name) symbolS * symbol_find_base (name, strip_underscore) - char *name; + CONST char *name; int strip_underscore; { if (strip_underscore && *name == '_') @@ -476,13 +431,7 @@ symbol_append (addme, target, rootPP, lastPP) #ifdef SYMBOLS_NEED_BACKPOINTERS addme->sy_previous = target; #endif /* SYMBOLS_NEED_BACKPOINTERS */ - -#ifdef DEBUG - /* verify_symbol_chain(*rootPP, *lastPP); */ -#endif /* DEBUG */ - - return; -} /* symbol_append() */ +} #ifdef SYMBOLS_NEED_BACKPOINTERS /* Remove SYMBOLP from the list. */ @@ -512,12 +461,10 @@ symbol_remove (symbolP, rootPP, lastPP) symbolP->sy_previous->sy_next = symbolP->sy_next; } /* if not first */ -#ifdef DEBUG +#ifdef DEBUG_SYMS verify_symbol_chain (*rootPP, *lastPP); -#endif /* DEBUG */ - - return; -} /* symbol_remove() */ +#endif /* DEBUG_SYMS */ +} /* Set the chain pointers of SYMBOL to null. */ void @@ -526,7 +473,7 @@ symbol_clear_list_pointers (symbolP) { symbolP->sy_next = NULL; symbolP->sy_previous = NULL; -} /* symbol_clear_list_pointers() */ +} /* Link symbol ADDME before symbol TARGET in the chain. */ void @@ -550,12 +497,10 @@ symbol_insert (addme, target, rootPP, lastPP) target->sy_previous = addme; addme->sy_next = target; -#ifdef DEBUG +#ifdef DEBUG_SYMS verify_symbol_chain (*rootPP, *lastPP); -#endif /* DEBUG */ - - return; -} /* symbol_insert() */ +#endif /* DEBUG_SYMS */ +} #endif /* SYMBOLS_NEED_BACKPOINTERS */ @@ -567,29 +512,187 @@ verify_symbol_chain (rootP, lastP) symbolS *symbolP = rootP; if (symbolP == NULL) - { - return; - } /* empty chain */ + return; for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP)) { #ifdef SYMBOLS_NEED_BACKPOINTERS - /*$if (symbolP->sy_previous) { - know(symbolP->sy_previous->sy_next == symbolP); - } else { - know(symbolP == rootP); - }$*//* both directions */ know (symbolP->sy_next->sy_previous == symbolP); -#else /* SYMBOLS_NEED_BACKPOINTERS */ +#else + /* Walk the list anyways, to make sure pointers are still good. */ ; #endif /* SYMBOLS_NEED_BACKPOINTERS */ - } /* verify pointers */ + } + + assert (lastP == symbolP); +} + +void +verify_symbol_chain_2 (sym) + symbolS *sym; +{ + symbolS *p = sym, *n = sym; +#ifdef SYMBOLS_NEED_BACKPOINTERS + while (symbol_previous (p)) + p = symbol_previous (p); +#endif + while (symbol_next (n)) + n = symbol_next (n); + verify_symbol_chain (p, n); +} + +/* Resolve the value of a symbol. This is called during the final + pass over the symbol table to resolve any symbols with complex + values. */ + +void +resolve_symbol_value (symp) + symbolS *symp; +{ + int resolved; + + if (symp->sy_resolved) + return; - know (lastP == symbolP); + resolved = 0; - return; -} /* verify_symbol_chain() */ + if (symp->sy_resolving) + { + as_bad ("Symbol definition loop encountered at %s", + S_GET_NAME (symp)); + S_SET_VALUE (symp, (valueT) 0); + resolved = 1; + } + else + { + offsetT left, right, val; + segT seg_left, seg_right; + + symp->sy_resolving = 1; + + switch (symp->sy_value.X_op) + { + case O_absent: + S_SET_VALUE (symp, 0); + /* Fall through. */ + case O_constant: + S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address); + if (S_GET_SEGMENT (symp) == expr_section) + S_SET_SEGMENT (symp, absolute_section); + resolved = 1; + break; + + case O_symbol: + resolve_symbol_value (symp->sy_value.X_add_symbol); + +#ifdef obj_frob_forward_symbol + /* Some object formats need to forward the segment. */ + obj_frob_forward_symbol (symp); +#endif + + S_SET_VALUE (symp, + (symp->sy_value.X_add_number + + symp->sy_frag->fr_address + + S_GET_VALUE (symp->sy_value.X_add_symbol))); + if (S_GET_SEGMENT (symp) == expr_section + || S_GET_SEGMENT (symp) == undefined_section) + S_SET_SEGMENT (symp, + S_GET_SEGMENT (symp->sy_value.X_add_symbol)); + + resolved = symp->sy_value.X_add_symbol->sy_resolved; + break; + + case O_uminus: + case O_bit_not: + resolve_symbol_value (symp->sy_value.X_add_symbol); + if (symp->sy_value.X_op == O_uminus) + val = - S_GET_VALUE (symp->sy_value.X_add_symbol); + else + val = ~ S_GET_VALUE (symp->sy_value.X_add_symbol); + S_SET_VALUE (symp, + (val + + symp->sy_value.X_add_number + + symp->sy_frag->fr_address)); + if (S_GET_SEGMENT (symp) == expr_section + || S_GET_SEGMENT (symp) == undefined_section) + S_SET_SEGMENT (symp, absolute_section); + resolved = symp->sy_value.X_add_symbol->sy_resolved; + break; + + case O_multiply: + case O_divide: + case O_modulus: + case O_left_shift: + case O_right_shift: + case O_bit_inclusive_or: + case O_bit_or_not: + case O_bit_exclusive_or: + case O_bit_and: + case O_add: + case O_subtract: + resolve_symbol_value (symp->sy_value.X_add_symbol); + resolve_symbol_value (symp->sy_value.X_op_symbol); + seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol); + seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol); + if (seg_left != seg_right + && seg_left != undefined_section + && seg_right != undefined_section) + as_bad ("%s is operation on symbols in different sections", + S_GET_NAME (symp)); + if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol) + != absolute_section) + && symp->sy_value.X_op != O_subtract) + as_bad ("%s is illegal operation on non-absolute symbols", + S_GET_NAME (symp)); + left = S_GET_VALUE (symp->sy_value.X_add_symbol); + right = S_GET_VALUE (symp->sy_value.X_op_symbol); + switch (symp->sy_value.X_op) + { + case O_multiply: val = left * right; break; + case O_divide: val = left / right; break; + case O_modulus: val = left % right; break; + case O_left_shift: val = left << right; break; + case O_right_shift: val = left >> right; break; + case O_bit_inclusive_or: val = left | right; break; + case O_bit_or_not: val = left |~ right; break; + case O_bit_exclusive_or: val = left ^ right; break; + case O_bit_and: val = left & right; break; + case O_add: val = left + right; break; + case O_subtract: val = left - right; break; + default: abort (); + } + S_SET_VALUE (symp, + (symp->sy_value.X_add_number + + symp->sy_frag->fr_address + + val)); + if (S_GET_SEGMENT (symp) == expr_section + || S_GET_SEGMENT (symp) == undefined_section) + S_SET_SEGMENT (symp, absolute_section); + resolved = (symp->sy_value.X_add_symbol->sy_resolved + && symp->sy_value.X_op_symbol->sy_resolved); + break; + + case O_register: + case O_big: + case O_illegal: + /* Give an error (below) if not in expr_section. We don't + want to worry about expr_section symbols, because they + are fictional (they are created as part of expression + resolution), and any problems may not actually mean + anything. */ + break; + } + } + /* Don't worry if we can't resolve an expr_section symbol. */ + if (resolved) + symp->sy_resolved = 1; + else if (S_GET_SEGMENT (symp) != expr_section) + { + as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp)); + symp->sy_resolved = 1; + } +} #ifdef LOCAL_LABELS_DOLLAR @@ -600,11 +703,11 @@ verify_symbol_chain (rootP, lastP) the instance number, keep a list of defined symbols separate from the real symbol table, and we treat these buggers as a sparse array. */ -static long *dollar_labels = NULL; -static long *dollar_label_instances = NULL; -static char *dollar_label_defines = NULL; -static long dollar_label_count = 0; -static long dollar_label_max = 0; +static long *dollar_labels; +static long *dollar_label_instances; +static char *dollar_label_defines; +static long dollar_label_count; +static unsigned long dollar_label_max; int dollar_label_defined (label) @@ -615,15 +718,11 @@ dollar_label_defined (label) know ((dollar_labels != NULL) || (dollar_label_count == 0)); for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) - { - if (*i == label) - { - return (dollar_label_defines[i - dollar_labels]); - } /* found it */ - } /* look for label */ + if (*i == label) + return dollar_label_defines[i - dollar_labels]; /* if we get here, label isn't defined */ - return (0); + return 0; } /* dollar_label_defined() */ static int @@ -635,24 +734,19 @@ dollar_label_instance (label) know ((dollar_labels != NULL) || (dollar_label_count == 0)); for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) - { - if (*i == label) - { - return (dollar_label_instances[i - dollar_labels]); - } /* found it */ - } /* look for (the union :-) label */ + if (*i == label) + return (dollar_label_instances[i - dollar_labels]); - /* if we get here, we haven't seen the label before, therefor it's instance - count is zero. */ - return (0); -} /* dollar_label_instance() */ + /* If we get here, we haven't seen the label before, therefore its instance + count is zero. */ + return 0; +} void dollar_label_clear () { - memset (dollar_label_defines, '\0', dollar_label_count); - return; -} /* clear_dollar_labels() */ + memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count); +} #define DOLLAR_LABEL_BUMP_BY 10 @@ -663,14 +757,12 @@ define_dollar_label (label) long *i; for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) - { - if (*i == label) - { - ++dollar_label_instances[i - dollar_labels]; - dollar_label_defines[i - dollar_labels] = 1; - return; - } /* if we find it */ - } /* for each existing label */ + if (*i == label) + { + ++dollar_label_instances[i - dollar_labels]; + dollar_label_defines[i - dollar_labels] = 1; + return; + } /* if we get to here, we don't have label listed yet. */ @@ -681,7 +773,6 @@ define_dollar_label (label) dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY); dollar_label_max = DOLLAR_LABEL_BUMP_BY; dollar_label_count = 0; - } else if (dollar_label_count == dollar_label_max) { @@ -697,19 +788,18 @@ define_dollar_label (label) dollar_label_instances[dollar_label_count] = 1; dollar_label_defines[dollar_label_count] = 1; ++dollar_label_count; - return; -} /* define_dollar_label() */ +} /* * dollar_label_name() * * Caller must copy returned name: we re-use the area for the next name. * - * The mth occurence of label n: is turned into the symbol "Ln^Am" where - * n is the label number and m is the instance number. "L" makes it a label discarded - * unless debugging and "^A"('\1') ensures no ordinary symbol SHOULD get the - * same name as a local label symbol. The first "4:" is "L4^A1" - the m - * numbers begin at 1. + * The mth occurence of label n: is turned into the symbol "Ln^Am" + * where n is the label number and m is the instance number. "L" makes + * it a label discarded unless debugging and "^A"('\1') ensures no + * ordinary symbol SHOULD get the same name as a local label + * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1. * * fb labels get the same treatment, except that ^B is used in place of ^A. */ @@ -754,8 +844,8 @@ dollar_label_name (n, augend) while ((*p++ = *--q) != '\0');; /* The label, as a '\0' ended string, starts at symbol_name_build. */ - return (symbol_name_build); -} /* dollar_label_name() */ + return symbol_name_build; +} #endif /* LOCAL_LABELS_DOLLAR */ @@ -784,8 +874,8 @@ dollar_label_name (n, augend) static long fb_low_counter[FB_LABEL_SPECIAL]; static long *fb_labels; static long *fb_label_instances; -static long fb_label_count = 0; -static long fb_label_max = 0; +static long fb_label_count; +static long fb_label_max; /* this must be more than FB_LABEL_SPECIAL */ #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6) @@ -794,7 +884,6 @@ static void fb_label_init () { memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter)); - return; } /* fb_label_init() */ /* add one to the instance number of this fb label */ @@ -810,14 +899,18 @@ fb_label_instance_inc (label) return; } - for (i = fb_labels + FB_LABEL_SPECIAL; i < fb_labels + fb_label_count; ++i) + if (fb_labels != NULL) { - if (*i == label) + for (i = fb_labels + FB_LABEL_SPECIAL; + i < fb_labels + fb_label_count; ++i) { - ++fb_label_instances[i - fb_labels]; - return; - } /* if we find it */ - } /* for each existing label */ + if (*i == label) + { + ++fb_label_instances[i - fb_labels]; + return; + } /* if we find it */ + } /* for each existing label */ + } /* if we get to here, we don't have label listed yet. */ @@ -841,8 +934,7 @@ fb_label_instance_inc (label) fb_labels[fb_label_count] = label; fb_label_instances[fb_label_count] = 1; ++fb_label_count; - return; -} /* fb_label_instance_inc() */ +} static long fb_label_instance (label) @@ -855,31 +947,35 @@ fb_label_instance (label) return (fb_low_counter[label]); } - for (i = fb_labels + FB_LABEL_SPECIAL; i < fb_labels + fb_label_count; ++i) + if (fb_labels != NULL) { - if (*i == label) + for (i = fb_labels + FB_LABEL_SPECIAL; + i < fb_labels + fb_label_count; ++i) { - return (fb_label_instances[i - fb_labels]); - } /* if we find it */ - } /* for each existing label */ + if (*i == label) + { + return (fb_label_instances[i - fb_labels]); + } /* if we find it */ + } /* for each existing label */ + } - /* NOTREACHED */ - know (0); -} /* fb_label_instance() */ + /* We didn't find the label, so this must be a reference to the + first instance. */ + return 0; +} /* * fb_label_name() * * Caller must copy returned name: we re-use the area for the next name. * - * The mth occurence of label n: is turned into the symbol "Ln^Bm" where - * n is the label number and m is the instance number. "L" makes it a label discarded - * unless debugging and "^B"('\2') ensures no ordinary symbol SHOULD get the - * same name as a local label symbol. The first "4:" is "L4^B1" - the m - * numbers begin at 1. + * The mth occurence of label n: is turned into the symbol "Ln^Bm" + * where n is the label number and m is the instance number. "L" makes + * it a label discarded unless debugging and "^B"('\2') ensures no + * ordinary symbol SHOULD get the same name as a local label + * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1. * - * dollar labels get the same treatment, except that ^A is used in place of ^B. - */ + * dollar labels get the same treatment, except that ^A is used in place of ^B. */ char * /* Return local label name. */ fb_label_name (n, augend) @@ -977,12 +1073,170 @@ decode_local_label_name (s) return (symbol_decode); } /* decode_local_label_name() */ +/* Get the value of a symbol. */ -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ +valueT +S_GET_VALUE (s) + symbolS *s; +{ + if (s->sy_value.X_op != O_constant) + as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s)); + return (valueT) s->sy_value.X_add_number; +} + +/* Set the value of a symbol. */ + +void +S_SET_VALUE (s, val) + symbolS *s; + valueT val; +{ + s->sy_value.X_op = O_constant; + s->sy_value.X_add_number = (offsetT) val; + s->sy_value.X_unsigned = 0; +} + +#ifdef BFD_ASSEMBLER + +int +S_IS_EXTERNAL (s) + symbolS *s; +{ + flagword flags = s->bsym->flags; + + /* sanity check */ + if (flags & BSF_LOCAL && flags & BSF_GLOBAL) + abort (); + + return (flags & BSF_GLOBAL) != 0; +} + +int +S_IS_COMMON (s) + symbolS *s; +{ + return bfd_is_com_section (s->bsym->section); +} + +int +S_IS_DEFINED (s) + symbolS *s; +{ + return s->bsym->section != undefined_section; +} + +int +S_IS_DEBUG (s) + symbolS *s; +{ + if (s->bsym->flags & BSF_DEBUGGING) + return 1; + return 0; +} + +int +S_IS_LOCAL (s) + symbolS *s; +{ + flagword flags = s->bsym->flags; + + /* sanity check */ + if (flags & BSF_LOCAL && flags & BSF_GLOBAL) + abort (); + + return (S_GET_NAME (s) + && ! S_IS_DEBUG (s) + && (strchr (S_GET_NAME (s), '\001') + || strchr (S_GET_NAME (s), '\002') + || (S_LOCAL_NAME (s) + && !flagseen['L']))); +} + +int +S_IS_EXTERN (s) + symbolS *s; +{ + return S_IS_EXTERNAL (s); +} + +int +S_IS_STABD (s) + symbolS *s; +{ + return S_GET_NAME (s) == 0; +} + +CONST char * +S_GET_NAME (s) + symbolS *s; +{ + return s->bsym->name; +} + +segT +S_GET_SEGMENT (s) + symbolS *s; +{ + return s->bsym->section; +} + +void +S_SET_SEGMENT (s, seg) + symbolS *s; + segT seg; +{ + s->bsym->section = seg; +} + +void +S_SET_EXTERNAL (s) + symbolS *s; +{ + s->bsym->flags |= BSF_GLOBAL; + s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK); +} + +void +S_CLEAR_EXTERNAL (s) + symbolS *s; +{ + s->bsym->flags |= BSF_LOCAL; + s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK); +} + +void +S_SET_WEAK (s) + symbolS *s; +{ + s->bsym->flags |= BSF_WEAK; + s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL); +} + +void +S_SET_NAME (s, name) + symbolS *s; + char *name; +{ + s->bsym->name = name; +} +#endif /* BFD_ASSEMBLER */ + +void +symbol_begin () +{ + symbol_lastP = NULL; + symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ + sy_hash = hash_new (); + memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol)); +#ifdef BFD_ASSEMBLER + abs_symbol.bsym = bfd_abs_section.symbol; +#else + /* Can't initialise a union. Sigh. */ + S_SET_SEGMENT (&abs_symbol, absolute_section); +#endif +#ifdef LOCAL_LABELS_FB + fb_label_init (); +#endif /* LOCAL_LABELS_FB */ +} /* end of symbols.c */