diff options
author | Ken Raeburn <raeburn@cygnus> | 1994-09-28 20:27:31 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1994-09-28 20:27:31 +0000 |
commit | e702f6e6e3b8d9f48d46eed04bf6da1983476a30 (patch) | |
tree | 729e01eeb79d8e07585c30d463d8853994bf215b | |
parent | 3bbea7af281dcd8ebd320a036fa56f5883815159 (diff) | |
download | gdb-e702f6e6e3b8d9f48d46eed04bf6da1983476a30.zip gdb-e702f6e6e3b8d9f48d46eed04bf6da1983476a30.tar.gz gdb-e702f6e6e3b8d9f48d46eed04bf6da1983476a30.tar.bz2 |
(resolve_symbol_value, case O_symbol): Don't do any processing if add_symbol is
undefined or in expr_section.
(resolve_symbol_value, case O_add): For symbol plus constant-valued symbol,
convert to O_symbol and re-reduce.
(S_GET_VALUE): If symbol needs resolving, resolve it.
(indent_level): No longer static.
(print_symbol_value_1): Don't print frag address if it matches
zero_address_frag. Don't print "resolving" if already resolved. Print segment
name. Don't call print_expr_1 on an undefined symbol.
(print_expr_1): Fix whitespace before printing X_add_number.
-rw-r--r-- | gas/symbols.c | 107 |
1 files changed, 84 insertions, 23 deletions
diff --git a/gas/symbols.c b/gas/symbols.c index 20ccf67..86ea31c 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -605,6 +605,7 @@ resolve_symbol_value (symp) symp->sy_resolving = 1; + reduce: switch (symp->sy_value.X_op) { case O_absent: @@ -620,20 +621,21 @@ resolve_symbol_value (symp) 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)); - + if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) != undefined_section + && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section) + { + if (symp->sy_value.X_add_number == 0) + copy_symbol_attributes (symp, symp->sy_value.X_add_symbol); + + 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; @@ -654,6 +656,41 @@ resolve_symbol_value (symp) resolved = symp->sy_value.X_add_symbol->sy_resolved; break; + case O_add: +#if 1 + 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); + /* This case comes up with PIC support. */ + { + symbolS *s_left = symp->sy_value.X_add_symbol; + symbolS *s_right = symp->sy_value.X_op_symbol; + + if (seg_left == absolute_section) + { + symbolS *t; + segT ts; + t = s_left; + s_left = s_right; + s_right = t; + ts = seg_left; + seg_left = seg_right; + seg_right = ts; + } + if (seg_right == absolute_section + && s_right->sy_resolved) + { + symp->sy_value.X_add_number += S_GET_VALUE (s_right); + symp->sy_value.X_op_symbol = 0; + symp->sy_value.X_add_symbol = s_left; + symp->sy_value.X_op = O_symbol; + goto reduce; + } + } +#endif + /* fall through */ + case O_multiply: case O_divide: case O_modulus: @@ -663,7 +700,6 @@ resolve_symbol_value (symp) 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); @@ -1114,6 +1150,8 @@ valueT S_GET_VALUE (s) symbolS *s; { + if (!s->sy_resolved && !s->sy_resolving && s->sy_value.X_op != O_constant) + resolve_symbol_value (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; @@ -1131,6 +1169,22 @@ S_SET_VALUE (s, val) s->sy_value.X_unsigned = 0; } +void +copy_symbol_attributes (dest, src) + symbolS *dest, *src; +{ +#ifdef BFD_ASSEMBLER + /* In an expression, transfer the settings of these flags. + The user can override later, of course. */ +#define COPIED_SYMFLAGS (BSF_FUNCTION) + dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS; +#endif + +#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES + OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src); +#endif +} + #ifdef BFD_ASSEMBLER int @@ -1279,7 +1333,8 @@ symbol_begin () #endif /* LOCAL_LABELS_FB */ } -static int indent_level; + +int indent_level; static void indent () @@ -1298,23 +1353,29 @@ print_symbol_value_1 (file, sym) const char *name = S_GET_NAME (sym); if (!name || !name[0]) name = "(unnamed)"; - fprintf (file, "sym %lx %s frag %lx", sym, name, (long) sym->sy_frag); + fprintf (file, "sym %lx %s", sym, name); + if (sym->sy_frag != &zero_address_frag) + fprintf (file, " frag %lx", (long) sym->sy_frag); if (sym->written) fprintf (file, " written"); if (sym->sy_resolved) fprintf (file, " resolved"); - if (sym->sy_resolving) + else if (sym->sy_resolving) fprintf (file, " resolving"); if (sym->sy_used_in_reloc) fprintf (file, " used-in-reloc"); if (sym->sy_used) fprintf (file, " used"); + fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym))); if (sym->sy_resolved) { - /* XXX print segment name too */ - fprintf (file, " value %lx", (long) S_GET_VALUE (sym)); + segT s = S_GET_SEGMENT (sym); + + if (s != undefined_section + && s != expr_section) + fprintf (file, " %lx", (long) S_GET_VALUE (sym)); } - else if (indent_level < 8) + else if (indent_level < 8 && S_GET_SEGMENT (sym) != undefined_section) { indent_level++; fprintf (file, "\n%*s<", indent_level * 4, ""); @@ -1357,10 +1418,10 @@ print_expr_1 (file, exp) print_symbol_value_1 (file, exp->X_add_symbol); fprintf (file, ">"); maybe_print_addnum: - indent_level--; if (exp->X_add_number) - fprintf (file, "\n%*s %lx", indent_level * 4, "", + fprintf (file, "\n%*s%lx", indent_level * 4, "", (long) exp->X_add_number); + indent_level--; break; case O_register: fprintf (file, "register #%d", (int) exp->X_add_number); |