From 5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 21 Jul 1993 00:41:42 +0000 Subject: * 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. --- gas/write.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 27 deletions(-) (limited to 'gas/write.c') diff --git a/gas/write.c b/gas/write.c index 8a480f1..b527708 100644 --- a/gas/write.c +++ b/gas/write.c @@ -58,6 +58,15 @@ int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE; #endif /* BFD_ASSEMBLER */ +static fixS *fix_new_internal PARAMS ((fragS *, int where, short int size, + symbolS *add, symbolS *sub, + offsetT offset, int pcrel, +#ifdef BFD_ASSEMBLER + bfd_reloc_code_real_type r_type +#else + int r_type +#endif + )); static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type)); static relax_addressT relax_align PARAMS ((relax_addressT addr, int align)); void relax_segment PARAMS ((struct frag * seg_frag_root, segT seg_type)); @@ -67,13 +76,14 @@ void relax_segment PARAMS ((struct frag * seg_frag_root, segT seg_type)); * * Create a fixS in obstack 'notes'. */ -fixS * -fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, r_type) +static fixS * +fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel, + r_type) fragS *frag; /* Which frag? */ int where; /* Where in that frag? */ short int size; /* 1, 2, or 4 usually. */ symbolS *add_symbol; /* X_add_symbol. */ - symbolS *sub_symbol; /* X_subtract_symbol. */ + symbolS *sub_symbol; /* X_op_symbol. */ offsetT offset; /* X_add_number. */ int pcrel; /* TRUE if PC-relative relocation. */ #ifdef BFD_ASSEMBLER @@ -142,6 +152,70 @@ fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, r_type) return fixP; } +/* Create a fixup relative to a symbol (plus a constant). */ + +fixS * +fix_new (frag, where, size, add_symbol, offset, pcrel, r_type) + fragS *frag; /* Which frag? */ + int where; /* Where in that frag? */ + short int size; /* 1, 2, or 4 usually. */ + symbolS *add_symbol; /* X_add_symbol. */ + offsetT offset; /* X_add_number. */ + int pcrel; /* TRUE if PC-relative relocation. */ +#ifdef BFD_ASSEMBLER + bfd_reloc_code_real_type r_type; /* Relocation type */ +#else + int r_type; /* Relocation type */ +#endif +{ + return fix_new_internal (frag, where, size, add_symbol, + (symbolS *) NULL, offset, pcrel, r_type); +} + +/* Create a fixup for an expression. Currently we only support fixups + for difference expressions. That is itself more than most object + file formats support anyhow. */ + +fixS * +fix_new_exp (frag, where, size, exp, pcrel, r_type) + fragS *frag; /* Which frag? */ + int where; /* Where in that frag? */ + short int size; /* 1, 2, or 4 usually. */ + expressionS *exp; /* Expression. */ + int pcrel; /* TRUE if PC-relative relocation. */ +#ifdef BFD_ASSEMBLER + bfd_reloc_code_real_type r_type; /* Relocation type */ +#else + int r_type; /* Relocation type */ +#endif +{ + symbolS *add = NULL; + symbolS *sub = NULL; + offsetT off = 0; + + switch (exp->X_op) + { + case O_absent: + break; + + case O_subtract: + sub = exp->X_op_symbol; + /* Fall through. */ + case O_symbol: + add = exp->X_add_symbol; + /* Fall through. */ + case O_constant: + off = exp->X_add_number; + break; + + default: + as_bad ("expression too complex for fixup"); + } + + return fix_new_internal (frag, where, size, add, sub, off, + pcrel, r_type); +} + /* Append a string onto another string, bumping the pointer along. */ void append (charPP, fromP, length) @@ -763,11 +837,7 @@ write_object_file () while (seclist && *seclist) { sec = *seclist; - while (sec == big_section - || sec == reg_section - || sec == pass1_section - || sec == diff_section - || sec == absent_section) + while (sec == reg_section || sec == expr_section) { sec = sec->next; *seclist = sec; @@ -975,30 +1045,30 @@ write_object_file () for (lie = broken_words; lie; lie = lie->next_broken_word) if (!lie->added) { + expressionS exp; + + exp.X_op = O_subtract; + exp.X_add_symbol = lie->add; + exp.X_op_symbol = lie->sub; + exp.X_add_number = lie->addnum; #ifdef BFD_ASSEMBLER - fix_new (lie->frag, lie->word_goes_here - lie->frag->fr_literal, - 2, lie->add, lie->sub, lie->addnum, 0, - BFD_RELOC_NONE); + fix_new_exp (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp, 0, BFD_RELOC_NONE); #else #if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE) - fix_new (lie->frag, lie->word_goes_here - lie->frag->fr_literal, - 2, lie->add, - lie->sub, lie->addnum, - 0, NO_RELOC); + fix_new_exp (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp, 0, NO_RELOC); #else #ifdef TC_NS32K - fix_new_ns32k (lie->frag, - lie->word_goes_here - lie->frag->fr_literal, - 2, - lie->add, - lie->sub, - lie->addnum, - 0, 0, 2, 0, 0); + fix_new_ns32k_exp (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp, 0, 0, 2, 0, 0); #else - fix_new (lie->frag, lie->word_goes_here - lie->frag->fr_literal, - 2, lie->add, - lie->sub, lie->addnum, - 0, 0); + fix_new_exp (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp, 0, 0); #endif /* TC_NS32K */ #endif /* TC_SPARC|TC_A29K|NEED_FX_R_TYPE */ #endif /* BFD_ASSEMBLER */ @@ -1191,7 +1261,7 @@ write_object_file () if (! symp->sy_resolved) { - if (symp->sy_value.X_seg == absolute_section) + if (symp->sy_value.X_op == O_constant) { /* This is the normal case; skip the call. */ S_SET_VALUE (symp, -- cgit v1.1