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/write.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/write.c')
-rw-r--r-- | gas/write.c | 124 |
1 files changed, 97 insertions, 27 deletions
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, |