diff options
author | Ian Lance Taylor <ian@airs.com> | 1993-07-21 00:41:42 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1993-07-21 00:41:42 +0000 |
commit | 5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a (patch) | |
tree | bf71fb272c4a13449f3dcc4d6ac486784e909cac /gas/symbols.c | |
parent | b9b9f55a52a01203776fcd35f2870634068d683a (diff) | |
download | gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.zip gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.tar.gz gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.tar.bz2 |
* Extensive changes to permit symbols to contain any expression
type and to delay the computation of the expression until the
value is actually needed. This permits setting symbols to values
calculated based on object code size. Expressions were changed to
no longer be in a section, to stop the overloading of segment and
expression type that previously occurred.
* as.c (big_section, pass1_section, diff_section, absent_section):
Removed.
(expr_section): Added (used for dummy symbols which hold
intermediate expression values).
(perform_an_assembly_pass): Create expr_section, do not create the
sections now removed.
* as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and
SEG_DIFFERENCE. Added SEG_EXPR.
(SEG_NORMAL): Corresponding changes.
* subsegs.c (seg_name, subsegs_begin): Changed accordingly.
* write.c (write_object_file): Ditto.
* config/obj-aout.c (seg_N_TYPE): Ditto.
* config/obj-bout.c (seg_N_TYPE): Ditto.
* config/obj-coff.c (seg_N_TYPE): Ditto.
* config/obj-coffbfd.c (seg_N_TYPE): Ditto.
* config/obj-vms.c (seg_N_TYPE): Ditto.
* expr.h (operatorT): Moved in from expr.c, added some values.
(expressionS): Added X_op field, removed X_seg field; renamed
X_subtract_symbol to X_op_symbol.
* expr.c: Extensive changes to assign expression types rather than
sections and to simplify the parsing.
* write.c (fix_new_internal): New static function.
(fix_new): Removed sub_symbol argument.
(fix_new_exp): New function, takes expression argument.
* write.h: Prototype changes for fix_new and fix_new_exp.
* cond.c (s_if): Changed accordingly.
* read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons,
parse_repeat_cons, get_segmented_expression,
get_known_segmented_expression, get_absolute_expression): Ditto.
* symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE):
Ditto.
* write.c (write_object_file): Ditto.
* config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto.
* config/obj-coffbfd.c (obj_coff_def, obj_coff_val,
obj_coff_endef, yank_symbols): Ditto.
* config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto.
* config/tc-a29k.c (md_assemble, parse_operand, machine_ip,
print_insn, md_operand): Ditto.
* config/tc-h8300.c (parse_exp, colonmod24, check_operand,
do_a_fix_imm, build_bytes): Ditto.
* config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist,
get_specific, check, insert, md_convert_frag): Ditto.
* config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa,
md_assemble, pa_ip, getExpression, getAbsoluteExpression,
evaluateAbsolute, pa_build_unwind_subspace, pa_entry,
process_exit): Ditto.
* config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative,
is_complex): Ditto.
* config/tc-i386.c (pe, md_assemble, i386_operand,
md_estimate_size_before_relax, md_create_long_jump): Ditto.
* config/tc-i860.c (md_assemble, getExpression, print_insn):
Ditto.
* config/tc-i960.c (parse_expr, subs, segs, md_convert_frag,
get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc,
i960_handle_align): Ditto.
* config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op,
subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1,
md_estimate_size_before_relax, md_create_long_jump, get_num):
Ditto.
* config/tc-m88k.c (md_assemble, get_imm16, get_pcr,
md_create_short_jump, md_create_long_jump): Ditto.
* config/tc-mips.c (md_assemble, append_insn, gp_reference,
macro_build, macro, my_getExpression): Ditto. Also removed
get_optional_absolute_expression; just use get_absolute_expression
instead.
* config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif,
fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto.
* config/tc-ns32k.h (fix_new_ns32k prototype): Ditto.
* config/tc-sh.c (parse_exp, check, insert, md_convert_frag):
Ditto.
* config/tc-sparc.c (md_assemble, sparc_ip, getExpression,
print_insn): Ditto.
* config/tc-tahoe.c (struct top, md_estimate_size_before_relax,
tip_op, md_assemble): Ditto.
* config/tc-vax.c (seg_of_operand, md_assemble,
md_estimate_size_before_relax, md_create_long_jump): Ditto.
* config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
Diffstat (limited to 'gas/symbols.c')
-rw-r--r-- | gas/symbols.c | 110 |
1 files changed, 89 insertions, 21 deletions
diff --git a/gas/symbols.c b/gas/symbols.c index d305024..a5acf1f 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1,5 +1,4 @@ /* symbols.c -symbol table- - Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -585,12 +584,23 @@ resolve_symbol_value (symp) } else { + offsetT left, right, val; + segT seg_left, seg_right; + symp->sy_resolving = 1; - if (symp->sy_value.X_seg == absolute_section) - S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address); - else if (symp->sy_value.X_seg == undefined_section) + 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); + break; + + case O_symbol: resolve_symbol_value (symp->sy_value.X_add_symbol); #ifdef obj_frob_forward_symbol @@ -602,26 +612,84 @@ resolve_symbol_value (symp) (symp->sy_value.X_add_number + symp->sy_frag->fr_address + S_GET_VALUE (symp->sy_value.X_add_symbol))); - } - else if (symp->sy_value.X_seg == diff_section) - { + 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)); + 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); + 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_subtract_symbol); - if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) - != S_GET_SEGMENT (symp->sy_value.X_subtract_symbol)) - as_bad ("%s is difference of symbols in different sections", + 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 - + S_GET_VALUE (symp->sy_value.X_add_symbol) - - S_GET_VALUE (symp->sy_value.X_subtract_symbol))); - S_SET_SEGMENT (symp, absolute_section); - } - else - { - /* More cases need to be added here. */ - abort (); + + val)); + if (S_GET_SEGMENT (symp) == expr_section + || S_GET_SEGMENT (symp) == undefined_section) + S_SET_SEGMENT (symp, absolute_section); + break; + + case O_register: + case O_big: + case O_illegal: + as_bad ("bad value for symbol \"%s\"", S_GET_NAME (symp)); + break; } } @@ -1014,7 +1082,7 @@ valueT S_GET_VALUE (s) symbolS *s; { - if (s->sy_value.X_seg != absolute_section) + 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; } @@ -1026,7 +1094,7 @@ S_SET_VALUE (s, val) symbolS *s; valueT val; { - s->sy_value.X_seg = absolute_section; + s->sy_value.X_op = O_constant; s->sy_value.X_add_number = (offsetT) val; } |