From a161fe53205dbc69d42f5a123b2b04346724b2de Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 5 Sep 2002 00:01:18 +0000 Subject: [PATCH] gas reloc rewrite. --- gas/ChangeLog | 407 ++++++++++++++++++++++++++ gas/as.h | 10 +- gas/cgen.c | 35 +-- gas/config/obj-aout.c | 9 +- gas/config/obj-aout.h | 14 +- gas/config/obj-bout.h | 10 +- gas/config/obj-coff.c | 1 + gas/config/obj-coff.h | 55 +++- gas/config/obj-ecoff.c | 80 +++--- gas/config/obj-ecoff.h | 6 +- gas/config/obj-elf.c | 1 + gas/config/obj-elf.h | 2 +- gas/config/obj-ieee.h | 9 +- gas/config/obj-multi.h | 7 +- gas/config/obj-vms.h | 6 + gas/config/tc-alpha.c | 26 +- gas/config/tc-alpha.h | 45 ++- gas/config/tc-arc.c | 51 +--- gas/config/tc-arc.h | 10 +- gas/config/tc-arm.c | 24 +- gas/config/tc-arm.h | 60 ++-- gas/config/tc-avr.c | 37 +-- gas/config/tc-avr.h | 138 ++++----- gas/config/tc-cris.c | 29 +- gas/config/tc-cris.h | 63 ++--- gas/config/tc-d10v.c | 43 +-- gas/config/tc-d10v.h | 23 +- gas/config/tc-d30v.c | 27 +- gas/config/tc-d30v.h | 16 +- gas/config/tc-dlx.c | 21 +- gas/config/tc-dlx.h | 23 +- gas/config/tc-fr30.c | 20 +- gas/config/tc-fr30.h | 14 +- gas/config/tc-frv.c | 12 +- gas/config/tc-frv.h | 18 +- gas/config/tc-h8300.c | 2 +- gas/config/tc-h8300.h | 7 +- gas/config/tc-hppa.c | 19 +- gas/config/tc-hppa.h | 11 +- gas/config/tc-i370.c | 35 +-- gas/config/tc-i370.h | 11 +- gas/config/tc-i386.c | 27 +- gas/config/tc-i386.h | 58 ++-- gas/config/tc-i860.c | 2 +- gas/config/tc-i860.h | 9 +- gas/config/tc-i960.c | 66 ++--- gas/config/tc-i960.h | 70 +++-- gas/config/tc-ia64.c | 5 +- gas/config/tc-ia64.h | 19 +- gas/config/tc-ip2k.c | 8 +- gas/config/tc-ip2k.h | 21 +- gas/config/tc-m32r.c | 15 +- gas/config/tc-m32r.h | 15 +- gas/config/tc-m68hc11.c | 46 +-- gas/config/tc-m68hc11.h | 15 +- gas/config/tc-m68k.c | 4 - gas/config/tc-m68k.h | 33 +-- gas/config/tc-mcore.c | 14 +- gas/config/tc-mcore.h | 16 +- gas/config/tc-mips.c | 31 +- gas/config/tc-mips.h | 29 +- gas/config/tc-mmix.c | 83 ++---- gas/config/tc-mmix.h | 54 ++-- gas/config/tc-mn10300.c | 15 +- gas/config/tc-mn10300.h | 17 +- gas/config/tc-ns32k.h | 8 +- gas/config/tc-openrisc.c | 5 +- gas/config/tc-openrisc.h | 13 +- gas/config/tc-or32.c | 10 +- gas/config/tc-or32.h | 10 +- gas/config/tc-pj.c | 10 +- gas/config/tc-pj.h | 20 +- gas/config/tc-ppc.c | 73 +++-- gas/config/tc-ppc.h | 42 +-- gas/config/tc-s390.c | 48 +--- gas/config/tc-s390.h | 23 +- gas/config/tc-sh.c | 58 +--- gas/config/tc-sh.h | 97 ++++--- gas/config/tc-sh64.h | 79 +++--- gas/config/tc-sparc.c | 36 +-- gas/config/tc-sparc.h | 77 ++--- gas/config/tc-tic30.c | 16 +- gas/config/tc-v850.c | 23 +- gas/config/tc-v850.h | 11 +- gas/config/tc-vax.h | 21 +- gas/config/tc-w65.h | 3 +- gas/config/tc-xstormy16.c | 60 +--- gas/config/tc-xstormy16.h | 12 +- gas/doc/internals.texi | 106 +++++-- gas/obj.h | 3 +- gas/subsegs.c | 10 +- gas/symbols.c | 22 ++ gas/symbols.h | 1 + gas/write.c | 580 +++++++++++++++----------------------- gas/write.h | 1 + 95 files changed, 1801 insertions(+), 1786 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 3cbe9aa7f6a..01974c194ac 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,410 @@ +2002-09-05 Alan Modra + + * doc/internals.texi (md_apply_fix3): Expand. + (TC_VALIDATE_FIX, TC_FORCE_RELOCATION, TC_FORCE_RELOCATION_ABS, + TC_FORCE_RELOCATION_LOCAL, TC_FORCE_RELOCATION_SUB_SAME, + TC_FORCE_RELOCATION_SUB_ABS, TC_FORCE_RELOCATION_SUB_LOCAL, + TC_VALIDATE_FIX_SUB, MD_APPLY_SYM_VALUE, S_FORCE_RELOC, + EXTERN_FORCE_RELOC): Document. + (TC_HANDLES_FX_DONE, obj_fix_adjustable): Remove. + * as.h: Don't include struc-symbol.h for arc. + (IS_ELF): Define. + * cgen.c (gas_cgen_md_apply_fix3): Remove *valP fudges and code to + subtract absolute symbol. + * obj.h (struct format_ops): Add frob_file_before_fix. + * subsegs.c (section_symbol): Set BSF_SECTION_SYM flag. + * symbols.c (S_FORCE_RELOC): New function. + * symbols.h (S_FORCE_RELOC): Declare. + * write.c (TC_FORCE_RELOCATION): Change default. + (TC_FORCE_RELOCATION_ABS): Define. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FORCE_RELOCATION_SECTION): Don't define. + (TC_FORCE_RELOCATION_SUB_SAME): Define this instead. + (TC_FORCE_RELOCATION_SUB_ABS): Define. + (TC_FORCE_RELOCATION_SUB_LOCAL): Define. + (TC_VALIDATE_FIX_SUB): Define. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define this instead. + (abs_section_sym): New variable. + (adjust_reloc_syms): Use S_FORCE_RELOC. Remove obj_fix_adjustable + call. Don't symbol_mark_used_in_reloc here. Simplify link_once tests. + Don't put the absolute section sym on fixups here. + (fix_segment): New function. + (write_relocs): Don't call fixup_segment from here. + (write_object_file): Instead call tc_frob_file_before_fix, + obj_frob_file_before_fix, and fix_segment prior to symbol table code. + Don't output the absolute section symbol. + (fixup_segment): Rewrite. + * write.h (abs_section_sym): Declare. + * config/obj-aout.c (obj_aout_frob_file_before_fix): Rename from + obj_aout_frob_file. + (aout_format_ops): Adjust to suit. + * config/obj-aout.h (obj_frob_file): Don't define. + (obj_frob_file_before_fix): Define. + (obj_aout_frob_file_before_fix): Rename from obj_aout_frob_file. + (S_FORCE_RELOC): Define. + * config/obj-bout.h (S_FORCE_RELOC): Define. + * config/obj-coff.c (coff_format_ops): Init new field. + * config/obj-coff.h: Formatting fixes. + (obj_sec_sym_ok_for_reloc): Define. + (S_FORCE_RELOC): Define. + * config/obj-ecoff.c (ecoff_frob_file_before_fix): Split out .. + (ecoff_frob_file): .. from here. + (ecoff_format_ops): Add new function. + * config/obj-ecoff.h (ecoff_frob_file_before_fix): Declare. + (obj_frob_file_before_fix): Define. + * config/obj-elf.c (elf_format_ops): Init new field. + * config/obj-elf.h (obj_sec_sym_ok_for_reloc): Expand comment. + * config/obj-ieee.h: Formatting fixes. + (S_FORCE_RELOC): Define. + * config/obj-multi.h (obj_frob_file_before_fix): Define. + * config/obj-vms.h (S_FORCE_RELOC): Define. + * config/tc-alpha.c (md_apply_fix3): Correct GPDISP comment. + (alpha_force_relocation): Use S_FORCE_RELOC, and don't return 0 + for BFD_RELOC_32 and BFD_RELOC_64. + (alpha_fix_adjustable): Remove extern and weak tests. + (alpha_before_fix): Rename from alpha_adjust_symtab. + (alpha_adjust_relocs): Rename from alpha_adjust_symtab_relocs. + * config/tc-alpha.h (struct fix, struct alpha_reloc_tag): Declare. + (TC_VALIDATE_FIX): Tweak param name. + (TC_FORCE_RELOCATION, tc_fix_adjustable): Likewise. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (MD_APPLY_SYM_VALUE): Define. + (tc_adjust_symtab): Don't define. + (alpha_adjust_symtab): Don't declare. + (tc_frob_file_before_fix): Define. + (alpha_before_fix): Declare. + (TC_INIT_FIX_DATA): Tweak param names. + * config/tc-arc.c: Include "struc-symbol.h". + (md_pcrel_from): Remove undefined sym fudge. + (md_apply_fix3): Remove *valP fudges and code to subtract abs sym. + Don't set fx_addnumber. + (tc_gen_reloc): Remove spurious fx_addnumber comment. + * config/tc-arc.h (MD_APPLY_SYM_VALUE): Define. + (EXTERN_FORCE_RELOC): Define. + * config/tc-arm.c (md_apply_fix3 ): Remove. + (tc_gen_reloc): Fudge ARM_GOTPC addend. + (arm_validate_fix): Return void. + (arm_fix_adjustable ): Remove extern and weak tests. + Add plt and got reloc tests. + (arm_force_relocation): Call S_FORCE_RELOC. + * config/tc-arm.h (struct fix): Forward declare. + (TC_VALIDATE_FIX): No longer set add_symbolP. + (arm_validate_fix): Adjust declaration. + (TC_FORCE_RELOCATION ): Call i386_force_relocation. + (i386_force_relocation): Declare. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FORCE_RELOCATION ): Call S_FORCE_RELOC. + * config/tc-i860.c (md_apply_fix3): Don't cast valP pointer type. + * config/tc-i860.h (MD_APPLY_SYM_VALUE): Define. + (EXTERN_FORCE_RELOC): Define. + * config/tc-i960.c (reloc_callj): Remove declaration. Return false. + (md_apply_fix3): Don't cast valP pointer type. Move code here from + old fixup_segment. No need to test fx_pcrel before setting fx_done. + (i960_validate_fix): Remove add_symbolPP arg and add_symbolP macro. + Use fx_addsy instead of add_symbolP, as_bad_where instead of as_bad. + Remove #if 0 code. Invert return boolean. + * config/tc-i960.h (TC_COUNT_RELOC): Tweak param name. + (TC_COFF_FIX2RTYPE, TC_ADJUST_RELOC_COUNT, TC_VALIDATE_FIX): Likewise. + (tc_headers_hook, tc_coff_fix2rtype): Remove declaration. + (tc_coff_sizemachdep): Prototype. + (i960_handle_align): Likewise. + (i960_validate_fix): Adjust declaration. + (reloc_callj): Likewise. + (EXTERN_FORCE_RELOC): Define. + (TC_FORCE_RELOCATION_SUB_SAME): Define. + (TC_FORCE_RELOCATION_ABS): Define. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define. + * config/tc-ia64.c (ia64_force_relocation): Call S_FORCE_RELOC. + * config/tc-ia64.h (MD_APPLY_SYM_VALUE): Define. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + * config/tc-ip2k.c (ip2k_force_relocation): Call S_FORCE_RELOC. + * config/tc-ip2k.h (MD_APPLY_FIX3): Don't define. + (MD_APPLY_SYM_VALUE): Define. + (EXTERN_FORCE_RELOC): Define. + (TC_FORCE_RELOCATION): Tweak param name. + * config/tc-m32r.c (m32r_force_relocation): Call S_FORCE_RELOC. + (m32r_fix_adjustable): Don't test extern, weak. + * config/tc-m32r.h (MD_PCREL_FROM_SECTION): Tweak param name. + (MD_APPLY_SYM_VALUE): Define. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define. + (tc_frob_file): Don't define. + (tc_frob_file_before_fix): Define. + (EXTERN_FORCE_RELOC): Define. + * config/tc-m68hc11.c (tc_gen_reloc): Set addend to zero. Adjust + BFD_RELOC_VTABLE_ENTRY address. + (tc_m68hc11_force_relocation): Call S_FORCE_RELOC. + (tc_m68hc11_fix_adjustable): Don't test relaxable_symbol. + (md_apply_fix3): Remove *valP fudges and code to subtract abs sym. + Remove duplicated fx_done code. + * config/tc-m68hc11.h (MD_APPLY_SYM_VALUE): Define. + (EXTERN_FORCE_RELOC): Define. + * config/tc-m68k.c (tc_m68k_fix_adjustable): Don't test + relaxable_symbol. + * config/tc-m68k.h (TC_COFF_FIX2RTYPE): Tweak param name. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FIX_ADJUSTABLE): Don't define. + (EXTERN_FORCE_RELOC): Define. + (MD_APPLY_SYM_VALUE): Define. + (TC_FORCE_RELOCATION): Call S_FORCE_RELOC. + * config/tc-mcore.c (md_apply_fix3): Don't cast valP pointer type. + Remove fx_addsy tests. + (mcore_force_relocation): Call S_FORCE_RELOC. + (mcore_fix_adjustable): Don't test fx_addsy. + * config/tc-mcore.h (MD_PCREL_FROM_SECTION): Tweak param name. + (EXTERN_FORCE_RELOC): Define. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define. + (MD_APPLY_SYM_VALUE): Define. + * config/tc-mips.c (enum mips_pic_level): Move to tc-mips.h. + (mips_pic): No longer static. + (mips_force_relocation): Call S_FORCE_RELOC. + (mips_fix_adjustable): Remove extern, weak tests. + * config/tc-mips.h (enum mips_pic_level): Declare. + (mips_pic): Declare. + (tc_frob_file): Don't define. + (tc_frob_file_before_fix): Define this instead. + (EXTERN_FORCE_RELOC): Define. + * config/tc-mmix.c (md_apply_fix3): Replace real_reg_section tests + with reg_section tests. Set fx_done instead of calling + symbol_clear_used_in_reloc on bad relocs. + (tc_gen_reloc): Zero fx_addsy on bad relocs. + (mmix_force_relocation): Remove weak sym test. Call S_FORCE_RELOC. + (mmix_adjust_symtab): Simplify list handling. Abort on any + nonsense. + * config/tc-mmix.h (tc_fix_adjustable): Remove weak tests. Check + BFD_RELOC_MMIX_LOCAL. + (tc_frob_symbol): Keep user defined syms in reg_section. Don't punt. + (EXTERN_FORCE_RELOC): Define. + (MD_PCREL_FROM_SECTION): Tweak param name. + (tc_frob_file): Don't define. + (tc_frob_file_before_fix): Define this instead. + * config/tc-mn10300.c (mn10300_force_relocation): Call S_FORCE_RELOC. + Remove SEC_CODE checks. + (mn10300_fix_adjustable): Remove extern and weak tests. + * config/tc-mn10300.h (EXTERN_FORCE_RELOC): Define. + (TC_FORCE_RELOCATION): Tweak param name. + (obj_fix_adjustable): Don't define. + (TC_FORCE_RELOCATION_SUB_SAME): Define to handle SEC_CODE. + * config/tc-ns32k.h (TC_FIX_DATA_PRINT): Tweak param name. + * config/tc-openrisc.c (openrisc_force_relocation): Call S_FORCE_RELOC. + (openrisc_fix_adjustable): Don't test fx_addsy. + * config/tc-openrisc.h (MD_APPLY_SYM_VALUE): Define. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define this instead. + (MD_PCREL_FROM_SECTION): Remove duplicate. Tweak param name. + * config/tc-or32.c (md_apply_fix3): Don't cast valP pointer type. + (tc_gen_reloc): Don't fiddle with BFD_RELOC_VTABLE_INHERIT relocs. + Adjust the address for BFD_RELOC_VTABLE_ENTRY, not the addend. + * config/tc-or32.h (EXTERN_FORCE_RELOC): Define. + (MD_APPLY_SYM_VALUE): Define. + * config/tc-pj.c (md_apply_fix3): Don't cast valP pointer type. + Don't subtract symbol value. + * config/tc-pj.h (md_pcrel_from): Tweak param name. + (EXTERN_FORCE_RELOC): Define. + (TC_FORCE_RELOCATION): Call S_FORCE_RELOC. + (MD_APPLY_SYM_VALUE): Define. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define this instead. + * config/tc-ppc.c (ppc_frob_symbol ): Ignore absolute + section sym. + (ppc_force_relocation ): Call S_FORCE_RELOC. + (ppc_force_relocation ): New. + (ppc_fix_adjustable ): Remove extern and weak tests. + (md_apply_fix3): Don't subtract symbol values for ELF. Update + comments. Don't subtract fx_subsy as that is already done. + * config/tc-ppc.h (tc_fix_adjustable): Tweak param name. + (MD_PCREL_FROM_SECTION): Likewise. + (TC_FORCE_RELOCATION): Define for both ELF and XCOFF as calling + ppc_force_relocation. + (TC_FORCE_RELOCATION_SECTION): Delete. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (MD_APPLY_SYM_VALUE): Define. + * config/tc-s390.c: #include "dwarf2dbg.h". + (s390_insn): Remove excess parens. + (tc_s390_fix_adjustable): Remove extern, weak, SEC_MERGE tests. + (tc_s390_force_relocation): Call S_FORCE_RELOC. + (md_apply_fix3): Add ATTRIBUTE_UNUSED on "seg". Abort when fx_subsy + non-NULL. Don't subtract off fx_addsy value. + * config/tc-s390.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION, MD_PCREL_FROM_SECTION): Tweak param name. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define. + * config/tc-sh.c (SWITCH_TABLE_CONS): Move to tc-sh.h. + (SWITCH_TABLE): Likewise. + (sh_force_relocation): Call S_FORCE_RELOC. + (sh_fix_adjustable): Remove "return 1" cases handled by the default. + Replace TC_RELOC_RTSYM_LOC_FIXUP with reloc type tests. + (md_apply_fix3 ): Simplify, + fx_addnumber is zero on entry. Save val in fx_addnumber. + (tc_gen_reloc): Don't subtract fx_subsy. + * config/tc-sh.h (struct fix): Move. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define this instead. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define. + (SWITCH_TABLE_CONS): Define. + (SWITCH_TABLE): Define. + (TC_FORCE_RELOCATION_SUB_SAME): Define. + (TC_VALIDATE_FIX_SUB): Define. + (MD_PCREL_FROM_SECTION): Tweak param name. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FORCE_RELOCATION_SUB_ABS): Define. + * config/tc-sh64.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (TC_FORCE_RELOCATION_SUB_SAME): Define. + (TC_VALIDATE_FIX_SUB): Define. + (MD_PCREL_FROM_SECTION): Tweak param name. + * config/tc-sparc.c (md_apply_fix3): Don't subtract off symbol value. + (tc_gen_reloc): Use S_FORCE_RELOC. + (elf32_sparc_force_relocation): Call S_FORCE_RELOC. + * config/tc-sparc.h (TC_FORCE_RELOCATION ): Remove. + (TC_FORCE_RELOCATION_ABS): Define this instead. + (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FORCE_RELOCATION_LOCAL): Define this instead. + (tc_fix_adjustable): Remove extern and weak tests. Use S_FORCE_RELOC. + (MD_APPLY_SYM_VALUE): Define. + (TC_FIX_DATA_PRINT): Tweak param name. + * config/tc-tic30.c (USE_STDOUT): Don't define. + (md_parse_option): Remove stupid debug code. + (tc_gen_reloc): Don't use fx_addnumber. + * config/tc-v850.c (v850_fix_adjustable): Remove extern and weak tests. + (v850_force_relocation): Remove weak test. Call S_FORCE_RELOC. + * config/tc-v850.h (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define this instead. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define this instead. + (TC_FORCE_RELOCATION, MD_PCREL_FROM_SECTION): Tweak param name. + * config/tc-vax.h (TC_RELOC_RTSYM_LOC_FIXUP): Don't define. + (TC_FIX_ADJUSTABLE): Don't define. + (MD_APPLY_SYM_VALUE): Define this instead. + (tc_fix_adjustable): Remove extern and weak tests. + * config/tc-w65.h (struct fix): Forward declare. + * config/tc-xstormy16.c (xstormy16_force_relocation): Call + S_FORCE_RELOC. + (xstormy16_fix_adjustable): Remove extern and weak tests. Don't + call xstormy16_force_relocation; Instead test for FPTR16 reloc. + (xstormy16_md_apply_fix3): Remove *valP fudges and code to subtract + absolute symbol. + * config/tc-xstormy16.h (MD_APPLY_FIX3): Don't define. + (MD_APPLY_SYM_VALUE): Define. + (obj_fix_adjustable): Don't define. + (tc_fix_adjustable): Define this instead. + (MD_PCREL_FROM_SECTION): Remove duplicate. Tweak param name. + 2002-09-04 Alan Modra * config/tc-ppc.c (ppc_frob_symbol): Formatting, warning fix. diff --git a/gas/as.h b/gas/as.h index ff434cbed0c..3d95d145715 100644 --- a/gas/as.h +++ b/gas/as.h @@ -613,8 +613,14 @@ void eh_frame_convert_frag PARAMS ((fragS *)); /* this one starts the chain of target dependant headers */ #include "targ-env.h" -#ifdef TC_ARC -#include "struc-symbol.h" +#ifdef OBJ_MAYBE_ELF +#define IS_ELF (OUTPUT_FLAVOR == bfd_target_elf_flavour) +#else +#ifdef OBJ_ELF +#define IS_ELF 1 +#else +#define IS_ELF 0 +#endif #endif #include "write.h" diff --git a/gas/cgen.c b/gas/cgen.c index 67b9b16186e..541508315b6 100644 --- a/gas/cgen.c +++ b/gas/cgen.c @@ -1,5 +1,5 @@ /* GAS interface for targets using CGEN: Cpu tools GENerator. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -580,39 +580,12 @@ gas_cgen_md_apply_fix3 (fixP, valP, seg) /* Canonical name, since used a lot. */ CGEN_CPU_DESC cd = gas_cgen_cpu_desc; - /* FIXME FIXME FIXME: The value we are passed in *valuep includes - the symbol values. Since we are using BFD_ASSEMBLER, if we are - doing this relocation the code in write.c is going to call - bfd_install_relocation, which is also going to use the symbol - value. That means that if the reloc is fully resolved we want to - use *valuep since bfd_install_relocation is not being used. - However, if the reloc is not fully resolved we do not want to use - *valuep, and must use fx_offset instead. However, if the reloc - is PC relative, we do want to use *valuep since it includes the - result of md_pcrel_from. This is confusing. */ - if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; - else if (fixP->fx_pcrel) - ; - - else - { - value = fixP->fx_offset; - - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } - } + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) { diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c index a3943068312..d9037157092 100644 --- a/gas/config/obj-aout.c +++ b/gas/config/obj-aout.c @@ -1,6 +1,6 @@ /* a.out object file format - Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001 - Free Software Foundation, Inc. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -200,7 +200,7 @@ obj_aout_frob_symbol (sym, punt) } void -obj_aout_frob_file () +obj_aout_frob_file_before_fix () { /* Relocation processing may require knowing the VMAs of the sections. Since writing to a section will cause the BFD back end to compute the @@ -731,8 +731,9 @@ const struct format_ops aout_format_ops = 0, /* begin */ 0, /* app_file */ obj_aout_frob_symbol, - obj_aout_frob_file, + 0, /* frob_file */ 0, /* frob_file_before_adjust */ + obj_aout_frob_file_before_fix, 0, /* frob_file_after_relocs */ 0, /* s_get_size */ 0, /* s_set_size */ diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h index 54168d1f700..505c1a5acb3 100644 --- a/gas/config/obj-aout.h +++ b/gas/config/obj-aout.h @@ -1,6 +1,6 @@ /* obj-aout.h, a.out object file format for gas, the assembler. - Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000 - Free Software Foundation, Inc. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, + 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -82,9 +82,9 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ asection *text_section, *data_section, *bss_section; #define obj_frob_symbol(S,PUNT) obj_aout_frob_symbol (S, &PUNT) -#define obj_frob_file() obj_aout_frob_file () +#define obj_frob_file_before_fix() obj_aout_frob_file_before_fix () extern void obj_aout_frob_symbol PARAMS ((symbolS *, int *)); -extern void obj_aout_frob_file PARAMS ((void)); +extern void obj_aout_frob_file_before_fix PARAMS ((void)); #define obj_sec_sym_ok_for_reloc(SEC) (1) @@ -109,6 +109,12 @@ extern void obj_aout_frob_file PARAMS ((void)); #define S_IS_COMMON(s) \ (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0) +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +#define S_FORCE_RELOC(s) \ + (!SEG_NORMAL (S_GET_SEGMENT (s))) + #define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER) /* True if a debug special symbol entry */ diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h index f01fdca0848..3293902b98a 100644 --- a/gas/config/obj-bout.h +++ b/gas/config/obj-bout.h @@ -1,6 +1,6 @@ /* b.out object file format - Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000 - Free Software Foundation, Inc. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, + 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -182,6 +182,12 @@ struct relocation_info /* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */ #define S_IS_DEFINED(s) ((S_GET_TYPE(s) != N_UNDF) || (S_GET_DESC(s) != 0)) +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +#define S_FORCE_RELOC(s) \ + (!SEG_NORMAL (S_GET_SEGMENT (s))) + #define S_IS_COMMON(s) \ (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0) diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 56b55d7cbc8..af197fe0583 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -4659,6 +4659,7 @@ const struct format_ops coff_format_ops = coff_frob_symbol, 0, /* frob_file */ 0, /* frob_file_before_adjust */ + 0, /* frob_file_before_fix */ coff_frob_file_after_relocs, 0, /* s_get_size */ 0, /* s_set_size */ diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index ed1fda96ee4..e90dd70f041 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -249,6 +249,12 @@ extern void coff_obj_read_begin_hook PARAMS ((void)); #define OBJ_SYMFIELD_TYPE unsigned long #define sy_obj sy_flags +/* We can't use the predefined section symbols in bfd/section.c, as + COFF symbols have extra fields. See bfd/libcoff.h:coff_symbol_type. */ +#ifndef obj_sec_sym_ok_for_reloc +#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0) +#endif + #define SYM_AUXENT(S) \ (&coffsymbol (symbol_get_bfdsym (S))->native[1].u.auxent) #define SYM_AUXINFO(S) \ @@ -479,7 +485,9 @@ typedef struct /* Predicates. */ /* True if the symbol is external. */ -#define S_IS_EXTERNAL(s) ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION) +#define S_IS_EXTERNAL(s) \ + ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION) + /* True if symbol has been defined, ie : section > 0 (DATA, TEXT or BSS) section == 0 and value > 0 (external bss symbol). */ @@ -488,8 +496,17 @@ typedef struct || ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION \ && S_GET_VALUE (s) > 0) \ || ((s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION)) + +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +#define S_FORCE_RELOC(s) \ + (!SEG_NORMAL (S_GET_SEGMENT (s)) || S_IS_WEAK (s)) + /* True if a debug special symbol entry. */ -#define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) +#define S_IS_DEBUG(s) \ + ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION) + /* True if a symbol is local symbol name. */ /* A symbol name whose name includes ^A is a gas internal pseudo symbol. */ #define S_IS_LOCAL(s) \ @@ -500,13 +517,16 @@ typedef struct || (flag_strip_local_absolute \ && !S_IS_EXTERNAL(s) \ && (s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION)) + /* True if a symbol is not defined in this file. */ #define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ && S_GET_VALUE (s) == 0) + /* True if a symbol can be multiply defined (bss symbols have this def though it is bad practice). */ #define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \ && S_GET_VALUE (s) != 0) + /* True if a symbol name is in the string table, i.e. its length is > 8. */ #define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0) @@ -523,34 +543,51 @@ typedef struct /* Accessors. */ /* The name of the symbol. */ #define S_GET_NAME(s) ((char*) (s)->sy_symbol.ost_entry.n_offset) + /* The pointer to the string table. */ #define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset) + /* The numeric value of the segment. */ #define S_GET_SEGMENT(s) s_get_segment(s) + /* The data type. */ #define S_GET_DATA_TYPE(s) ((s)->sy_symbol.ost_entry.n_type) + /* The storage class. */ #define S_GET_STORAGE_CLASS(s) ((s)->sy_symbol.ost_entry.n_sclass) + /* The number of auxiliary entries. */ #define S_GET_NUMBER_AUXILIARY(s) ((s)->sy_symbol.ost_entry.n_numaux) /* Modifiers. */ /* Set the name of the symbol. */ -#define S_SET_NAME(s,v) ((s)->sy_symbol.ost_entry.n_offset = (unsigned long) (v)) +#define S_SET_NAME(s,v) \ + ((s)->sy_symbol.ost_entry.n_offset = (unsigned long) (v)) + /* Set the offset of the symbol. */ -#define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v)) +#define S_SET_OFFSET(s,v) \ + ((s)->sy_symbol.ost_entry.n_offset = (v)) + /* The numeric value of the segment. */ -#define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) +#define S_SET_SEGMENT(s,v) \ + ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v)) + /* The data type. */ -#define S_SET_DATA_TYPE(s,v) ((s)->sy_symbol.ost_entry.n_type = (v)) +#define S_SET_DATA_TYPE(s,v) \ + ((s)->sy_symbol.ost_entry.n_type = (v)) + /* The storage class. */ -#define S_SET_STORAGE_CLASS(s,v) ((s)->sy_symbol.ost_entry.n_sclass = (v)) +#define S_SET_STORAGE_CLASS(s,v) \ + ((s)->sy_symbol.ost_entry.n_sclass = (v)) + /* The number of auxiliary entries. */ -#define S_SET_NUMBER_AUXILIARY(s,v) ((s)->sy_symbol.ost_entry.n_numaux = (v)) +#define S_SET_NUMBER_AUXILIARY(s,v) \ + ((s)->sy_symbol.ost_entry.n_numaux = (v)) /* Additional modifiers. */ /* The symbol is external (does not mean undefined). */ -#define S_SET_EXTERNAL(s) { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); } +#define S_SET_EXTERNAL(s) \ + { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); } /* Auxiliary entry macros. SA_ stands for symbol auxiliary. */ /* Omit the tv related fields. */ diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c index 4d055cb62eb..32e051844ca 100644 --- a/gas/config/obj-ecoff.c +++ b/gas/config/obj-ecoff.c @@ -1,5 +1,5 @@ /* ECOFF object file format. - Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 + Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Cygnus Support. This file was put together by Ian Lance Taylor . @@ -98,18 +98,13 @@ const pseudo_typeS obj_pseudo_table[] = { NULL, s_ignore, 0 } }; -/* Swap out the symbols and debugging information for BFD. */ +/* Set section VMAs and GP values before reloc processing. */ void -ecoff_frob_file () +ecoff_frob_file_before_fix () { - const struct ecoff_debug_swap * const debug_swap - = &ecoff_backend (stdoutput)->debug_swap; bfd_vma addr; asection **sec; - HDRR *hdr; - char *buf; - char *set; /* Set the section VMA values. We force the .sdata and .sbss sections to the end to ensure that their VMA addresses are close @@ -177,6 +172,46 @@ ecoff_frob_file () if (secs[i]) bfd_section_list_insert (stdoutput, &stdoutput->sections, secs[i]); + /* Fill in the register masks. */ + { + unsigned long gprmask = 0; + unsigned long fprmask = 0; + unsigned long *cprmask = NULL; + +#ifdef TC_MIPS + /* Fill in the MIPS register masks. It's probably not worth + setting up a generic interface for this. */ + gprmask = mips_gprmask; + cprmask = mips_cprmask; +#endif + +#ifdef TC_ALPHA + alpha_frob_ecoff_data (); + + if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value)) + as_fatal (_("Can't set GP value")); + + gprmask = alpha_gprmask; + fprmask = alpha_fprmask; +#endif + + if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask)) + as_fatal (_("Can't set register masks")); + } +} + +/* Swap out the symbols and debugging information for BFD. */ + +void +ecoff_frob_file () +{ + const struct ecoff_debug_swap * const debug_swap + = &ecoff_backend (stdoutput)->debug_swap; + bfd_vma addr; + HDRR *hdr; + char *buf; + char *set; + /* Build the ECOFF debugging information. */ assert (ecoff_data (stdoutput) != 0); hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header; @@ -204,35 +239,7 @@ ecoff_frob_file () SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size); SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size); SET (external_ext, iextMax, PTR, debug_swap->external_ext_size); - #undef SET - - /* Fill in the register masks. */ - { - unsigned long gprmask = 0; - unsigned long fprmask = 0; - unsigned long *cprmask = NULL; - -#ifdef TC_MIPS - /* Fill in the MIPS register masks. It's probably not worth - setting up a generic interface for this. */ - gprmask = mips_gprmask; - cprmask = mips_cprmask; -#endif - -#ifdef TC_ALPHA - alpha_frob_ecoff_data (); - - if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value)) - as_fatal (_("Can't set GP value")); - - gprmask = alpha_gprmask; - fprmask = alpha_fprmask; -#endif - - if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask)) - as_fatal (_("Can't set register masks")); - } } /* This is called by the ECOFF code to set the external information @@ -296,6 +303,7 @@ const struct format_ops ecoff_format_ops = obj_ecoff_frob_symbol, ecoff_frob_file, 0, /* frob_file_before_adjust */ + ecoff_frob_file_before_fix, 0, /* frob_file_after_relocs */ 0, /* s_get_size */ 0, /* s_set_size */ diff --git a/gas/config/obj-ecoff.h b/gas/config/obj-ecoff.h index 01a67d73e84..54ee0438db3 100644 --- a/gas/config/obj-ecoff.h +++ b/gas/config/obj-ecoff.h @@ -1,5 +1,5 @@ /* ECOFF object file format header file. - Copyright 1993, 1994, 1995, 1996, 1997, 1999 + Copyright 1993, 1994, 1995, 1996, 1997, 1999, 2002 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Ian Lance Taylor . @@ -49,6 +49,10 @@ struct ecoff_sy_obj /* Modify the ECOFF symbol. */ #define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp) +/* Set section VMAs and GP. */ +extern void ecoff_frob_file_before_fix PARAMS ((void)); +#define obj_frob_file_before_fix() ecoff_frob_file_before_fix () + /* This is used to write the symbolic data in the format that BFD expects it. */ extern void ecoff_frob_file PARAMS ((void)); diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 375dcffff13..736a5d48488 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -2328,6 +2328,7 @@ const struct format_ops elf_format_ops = elf_frob_symbol, elf_frob_file, elf_frob_file_before_adjust, + 0, /* obj_frob_file_before_fix */ elf_frob_file_after_relocs, elf_s_get_size, elf_s_set_size, elf_s_get_align, elf_s_set_align, diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 6197bf1e652..d59bbfe86b9 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -166,7 +166,7 @@ extern struct fix *obj_elf_vtable_inherit PARAMS ((int)); extern struct fix *obj_elf_vtable_entry PARAMS ((int)); /* BFD wants to write the udata field, which is a no-no for the - globally defined sections. */ + predefined section symbols in bfd/section.c. They are read-only. */ #ifndef obj_sec_sym_ok_for_reloc #define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0) #endif diff --git a/gas/config/obj-ieee.h b/gas/config/obj-ieee.h index 2652bc20cfd..685ac4e57e5 100644 --- a/gas/config/obj-ieee.h +++ b/gas/config/obj-ieee.h @@ -1,5 +1,5 @@ /* This file is obj-ieee.h - Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000 + Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -28,16 +28,19 @@ typedef struct asymbol sy; int seg; } - obj_symbol_type; #define S_GET_NAME(s) (((s)->sy_symbol.sy.name)) +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +#define S_FORCE_RELOC(s) (!SEG_NORMAL (x->sy_symbol.seg)) + typedef struct { int x; } - object_headers; #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 1 diff --git a/gas/config/obj-multi.h b/gas/config/obj-multi.h index 225de2c63ab..37d9fe828b4 100644 --- a/gas/config/obj-multi.h +++ b/gas/config/obj-multi.h @@ -1,5 +1,5 @@ /* Multiple object format emulation. - Copyright 1995, 1996, 1997, 1999, 2000 + Copyright 1995, 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -55,6 +55,11 @@ ? (*this_format->frob_file_before_adjust) () \ : (void) 0) +#define obj_frob_file_before_fix() \ + (this_format->frob_file_before_fix \ + ? (*this_format->frob_file_before_fix) () \ + : (void) 0) + #define obj_frob_file_after_relocs() \ (this_format->frob_file_after_relocs \ ? (*this_format->frob_file_after_relocs) () \ diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h index ac0794f9172..ac1fd3df4a8 100644 --- a/gas/config/obj-vms.h +++ b/gas/config/obj-vms.h @@ -139,6 +139,12 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define S_IS_COMMON(s) (S_GET_TYPE(s) == N_UNDF && S_GET_VALUE(s) != 0) +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +#define S_FORCE_RELOC(s) \ + (!SEG_NORMAL (S_GET_SEGMENT (s))) + #define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER) /* True if a debug special symbol entry */ diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c index b84fa582a42..7b65354aef6 100644 --- a/gas/config/tc-alpha.c +++ b/gas/config/tc-alpha.c @@ -208,7 +208,7 @@ struct alpha_macro /* Prototypes for all local functions. */ static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long)); -static void alpha_adjust_symtab_relocs PARAMS ((bfd *, asection *, PTR)); +static void alpha_adjust_relocs PARAMS ((bfd *, asection *, PTR)); static int tokenize_arguments PARAMS ((char *, expressionS *, int)); static const struct alpha_opcode *find_opcode_match @@ -1171,9 +1171,9 @@ md_apply_fix3 (fixP, valP, seg) switch (fixP->fx_r_type) { /* The GPDISP relocations are processed internally with a symbol - referring to the current function; we need to drop in a value - which, when added to the address of the start of the function, - gives the desired GP. */ + referring to the current function's section; we need to drop + in a value which, when added to the address of the start of + the function, gives the desired GP. */ case BFD_RELOC_ALPHA_GPDISP_HI16: { fixS *next = fixP->fx_next; @@ -1502,14 +1502,14 @@ alpha_force_relocation (f) return 1; case BFD_RELOC_23_PCREL_S2: - case BFD_RELOC_32: - case BFD_RELOC_64: case BFD_RELOC_ALPHA_HINT: return 0; default: - return 0; + break; } + + return S_FORCE_RELOC (f->fx_addsy); } /* Return true if we can partially resolve a relocation now. */ @@ -1518,12 +1518,6 @@ int alpha_fix_adjustable (f) fixS *f; { -#ifdef OBJ_ELF - /* Prevent all adjustments to global symbols */ - if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)) - return 0; -#endif - /* Are there any relocation types for which we must generate a reloc but we can adjust the values contained within it? */ switch (f->fx_r_type) @@ -1719,14 +1713,14 @@ get_alpha_reloc_tag (sequence) relocations, and similarly for !gpdisp relocations. */ void -alpha_adjust_symtab () +alpha_before_fix () { if (alpha_literal_hash) - bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL); + bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL); } static void -alpha_adjust_symtab_relocs (abfd, sec, ptr) +alpha_adjust_relocs (abfd, sec, ptr) bfd *abfd ATTRIBUTE_UNUSED; asection *sec; PTR ptr ATTRIBUTE_UNUSED; diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h index 65e06844972..d6a8842aea5 100644 --- a/gas/config/tc-alpha.h +++ b/gas/config/tc-alpha.h @@ -1,5 +1,5 @@ /* This file is tc-alpha.h - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ken Raeburn . @@ -39,6 +39,9 @@ #define NEED_LITERAL_POOL #define REPEAT_CONS_EXPRESSIONS +struct fix; +struct alpha_reloc_tag; + extern void alpha_validate_fix PARAMS ((struct fix *)); extern int alpha_force_relocation PARAMS ((struct fix *)); extern int alpha_fix_adjustable PARAMS ((struct fix *)); @@ -47,24 +50,14 @@ extern unsigned long alpha_gprmask, alpha_fprmask; extern valueT alpha_gp_value; #ifdef OBJ_ELF -#define TC_VALIDATE_FIX(FIXP,SEGTYPE,SKIP) alpha_validate_fix (FIXP) +#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) alpha_validate_fix (FIX) #endif - -#define TC_FORCE_RELOCATION(FIXP) alpha_force_relocation (FIXP) -#define tc_fix_adjustable(FIXP) alpha_fix_adjustable (FIXP) +#define TC_FORCE_RELOCATION(FIX) alpha_force_relocation (FIX) +#define tc_fix_adjustable(FIX) alpha_fix_adjustable (FIX) #define RELOC_REQUIRES_SYMBOL -/* This expression evaluates to false if the relocation is for a local - object for which we still want to do the relocation at runtime. - True if we are willing to perform this relocation while building - the .o file. This is only used for pcrel relocations. */ - -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n") #define md_estimate_size_before_relax(f,s) \ @@ -129,8 +122,8 @@ extern flagword alpha_elf_section_flags PARAMS ((flagword, int, int)); supplied !lituse relocations follow the appropriate !literal relocations. Also convert the gas-internal relocations to the appropriate linker relocations. */ -#define tc_adjust_symtab() alpha_adjust_symtab () -extern void alpha_adjust_symtab PARAMS ((void)); +#define tc_frob_file_before_fix() alpha_before_fix () +extern void alpha_before_fix PARAMS ((void)); /* New fields for supporting explicit relocations (such as !literal to mark where a pointer is loaded from the global table, and !lituse_base to track @@ -145,19 +138,19 @@ struct alpha_fix_tag }; /* Initialize the TC_FIX_TYPE field. */ -#define TC_INIT_FIX_DATA(fixP) \ +#define TC_INIT_FIX_DATA(FIX) \ do { \ - fixP->tc_fix_data.next_reloc = (struct fix *)0; \ - fixP->tc_fix_data.info = (struct alpha_literal_tag *)0; \ + FIX->tc_fix_data.next_reloc = (struct fix *) 0; \ + FIX->tc_fix_data.info = (struct alpha_reloc_tag *) 0; \ } while (0) /* Work with DEBUG5 to print fields in tc_fix_type. */ -#define TC_FIX_DATA_PRINT(stream,fixP) \ +#define TC_FIX_DATA_PRINT(STREAM, FIX) \ do { \ - if (fixP->tc_fix_data.info) \ - fprintf (stderr, "\tinfo = 0x%lx, next_reloc = 0x%lx\n", \ - (long)fixP->tc_fix_data.info, \ - (long)fixP->tc_fix_data.next_reloc); \ + if (FIX->tc_fix_data.info) \ + fprintf (STREAM, "\tinfo = 0x%lx, next_reloc = 0x%lx\n", \ + (long) FIX->tc_fix_data.info, \ + (long) FIX->tc_fix_data.next_reloc); \ } while (0) #define DWARF2_LINE_MIN_INSN_LENGTH 4 diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 7dedda149ab..01709e957d4 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -23,6 +23,7 @@ #include #include "libiberty.h" #include "as.h" +#include "struc-symbol.h" #include "safe-ctype.h" #include "subsegs.h" #include "opcode/arc.h" @@ -1801,13 +1802,6 @@ long md_pcrel_from (fixP) fixS *fixP; { - if (fixP->fx_addsy != (symbolS *) NULL - && ! S_IS_DEFINED (fixP->fx_addsy)) - { - /* The symbol is undefined. Let the linker figure it out. */ - return 0; - } - /* Return the address of the delay slot. */ return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size; } @@ -1891,45 +1885,19 @@ md_apply_fix3 (fixP, valP, seg) #endif valueT value = * valP; - /* FIXME FIXME FIXME: The value we are passed in *valueP includes - the symbol values. Since we are using BFD_ASSEMBLER, if we are - doing this relocation the code in write.c is going to call - bfd_perform_relocation, which is also going to use the symbol - value. That means that if the reloc is fully resolved we want to - use *valueP since bfd_perform_relocation is not being used. - However, if the reloc is not fully resolved we do not want to use - *valueP, and must use fx_offset instead. However, if the reloc - is PC relative, we do want to use *valueP since it includes the - result of md_pcrel_from. This is confusing. */ - if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; else if (fixP->fx_pcrel) { - /* ELF relocations are against symbols. - If this symbol is in a different section then we need to leave it for - the linker to deal with. Unfortunately, md_pcrel_from can't tell, - so we have to undo it's effects here. */ - if (S_IS_DEFINED (fixP->fx_addsy) - && S_GET_SEGMENT (fixP->fx_addsy) != seg) + /* Hack around bfd_install_relocation brain damage. */ + if (S_GET_SEGMENT (fixP->fx_addsy) != seg) value += md_pcrel_from (fixP); } - else - { - value = fixP->fx_offset; - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We can't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - "expression too complex"); - } - } - } + + /* We can't actually support subtracting a symbol. */ + if (fixP->fx_subsy != NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) { @@ -2032,8 +2000,6 @@ md_apply_fix3 (fixP, valP, seg) abort (); } } - - fixP->fx_addnumber = value; } /* Translate internal representation of relocation info to BFD target @@ -2063,8 +2029,7 @@ tc_gen_reloc (section, fixP) assert (!fixP->fx_pcrel == !reloc->howto->pc_relative); /* Set addend to account for PC being advanced one insn before the - target address is computed, drop fx_addnumber as it is handled - elsewhere mlm */ + target address is computed. */ reloc->addend = (fixP->fx_pcrel ? -4 : 0); diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h index f14427101ff..884d375546a 100644 --- a/gas/config/tc-arc.h +++ b/gas/config/tc-arc.h @@ -1,5 +1,6 @@ /* tc-arc.h - Macros and type defines for the ARC. - Copyright 1994, 1995, 1997, 2000, 2001 Free Software Foundation, Inc. + Copyright 1994, 1995, 1997, 2000, 2001, 2002 + Free Software Foundation, Inc. Contributed by Doug Evans (dje@cygnus.com). This file is part of GAS, the GNU Assembler. @@ -64,3 +65,10 @@ extern void arc_cons_fix_new PARAMS ((struct frag *, int, int, struct expression arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP) #define DWARF2_LINE_MIN_INSN_LENGTH 4 + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index d2d70341145..bf34dc9e3a9 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -10010,10 +10010,6 @@ md_apply_fix3 (fixP, valP, seg) break; #endif - case BFD_RELOC_ARM_GOTPC: - md_number_to_chars (buf, value, 4); - break; - case BFD_RELOC_ARM_CP_OFF_IMM: sign = value >= 0; if (value < -1023 || value > 1023 || (value & 3)) @@ -11390,7 +11386,7 @@ arm_canonicalize_symbol_name (name) return name; } -boolean +void arm_validate_fix (fixP) fixS * fixP; { @@ -11404,10 +11400,7 @@ arm_validate_fix (fixP) && ! THUMB_IS_FUNC (fixP->fx_addsy)) { fixP->fx_addsy = find_real_start (fixP->fx_addsy); - return true; } - - return false; } #ifdef OBJ_COFF @@ -11447,13 +11440,6 @@ arm_fix_adjustable (fixP) if (fixP->fx_addsy == NULL) return 1; - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - if (THUMB_IS_FUNC (fixP->fx_addsy) && fixP->fx_subsy == NULL) return 0; @@ -11463,6 +11449,12 @@ arm_fix_adjustable (fixP) || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; + /* Don't allow symbols to be discarded on GOT related relocs. */ + if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32 + || fixP->fx_r_type == BFD_RELOC_ARM_GOT32 + || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF) + return 0; + return 1; } @@ -11505,7 +11497,7 @@ arm_force_relocation (fixp) || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23) return 1; - return 0; + return S_FORCE_RELOC (fixp->fx_addsy); } static bfd_reloc_code_real_type diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index 2de9674327f..e01594539d6 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -1,5 +1,5 @@ /* This file is tc-arm.h - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modified by David Taylor (dtaylor@armltd.co.uk) @@ -66,17 +66,19 @@ #define TARGET_FORMAT "aif" #endif +struct fix; + #if defined OBJ_COFF || defined OBJ_ELF # define ARM_BI_ENDIAN -# define TC_VALIDATE_FIX(fixP, segType, Label) \ - if (arm_validate_fix (fixP)) add_symbolP = fixP->fx_addsy - extern boolean arm_validate_fix PARAMS ((struct fix *)); +# define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL) arm_validate_fix (FIX) + extern void arm_validate_fix PARAMS ((struct fix *)); #endif #ifdef OBJ_COFF # if defined TE_PE -# define TC_FORCE_RELOCATION(x) ((x)->fx_r_type == BFD_RELOC_RVA) +# define TC_FORCE_RELOCATION(x) \ + ((x)->fx_r_type == BFD_RELOC_RVA || S_FORCE_RELOC ((x)->fx_addsy)) # ifdef TE_EPOC # define TARGET_FORMAT (target_big_endian ? "epoc-pe-arm-big" : "epoc-pe-arm-little") # else @@ -91,7 +93,7 @@ # define TARGET_FORMAT elf32_arm_target_format() extern const char * elf32_arm_target_format PARAMS ((void)); -# define TC_FORCE_RELOCATION(fixp) arm_force_relocation (fixp) +# define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX) extern int arm_force_relocation PARAMS ((struct fix *)); #endif @@ -114,18 +116,16 @@ symbols as Thumb. */ #define TC_FIX_TYPE PTR -#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL) +#define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data = NULL) #if defined OBJ_ELF || defined OBJ_COFF -#include "write.h" /* For definition of fixS */ -#define obj_fix_adjustable(fixP) arm_fix_adjustable (fixP) -boolean arm_fix_adjustable PARAMS ((fixS *)); +#define EXTERN_FORCE_RELOC 1 -/* This arranges for gas/write.c to not apply a relocation if - obj_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP) -#else -#define obj_fix_adjustable(fixP) 0 +#define tc_fix_adjustable(FIX) arm_fix_adjustable (FIX) +boolean arm_fix_adjustable PARAMS ((struct fix *)); + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #endif /* We need to keep some local information on symbols. */ @@ -175,30 +175,24 @@ void armelf_frob_symbol PARAMS ((symbolS *, int *)); #define LOCAL_LABEL_PREFIX '.' #endif -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we - are willing to perform this relocation while building the .o file. - This is only used for pcrel relocations, so GOTOFF does not need to be - checked here. I am not sure if some of the others are ever used with +/* This expression evaluates to true if the relocation is for a local + object for which we still want to do the relocation at runtime. + False if we are willing to perform this relocation while building + the .o file. GOTOFF does not need to be checked here because it is + not pcrel. I am not sure if some of the others are ever used with pcrel, but it is easier to be safe than sorry. */ -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ( (FIX)->fx_r_type != BFD_RELOC_ARM_GOT12 \ - && (FIX)->fx_r_type != BFD_RELOC_ARM_GOT32 \ - && (FIX)->fx_r_type != BFD_RELOC_32) +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT12 \ + || (FIX)->fx_r_type == BFD_RELOC_ARM_GOT32 \ + || (FIX)->fx_r_type == BFD_RELOC_32 \ + || TC_FORCE_RELOCATION (FIX)) #define TC_CONS_FIX_NEW cons_fix_new_arm extern void cons_fix_new_arm PARAMS ((fragS *, int, int, expressionS *)); -/* Don't allow symbols to be discarded on GOT related relocs, - nor on globals. */ -#define tc_fix_adjustable(x) (\ - ((x)->fx_r_type == BFD_RELOC_ARM_PLT32 \ - || (x)->fx_r_type == BFD_RELOC_ARM_GOT32 \ - || (x)->fx_r_type == BFD_RELOC_ARM_GOTOFF \ - || S_IS_EXTERN ((x)->fx_addsy) \ - || S_IS_WEAK ((x)->fx_addsy)) ? 0 : 1) - #ifdef OBJ_ELF #define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" #else diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c index bab0d2d5791..573fa38a2ad 100644 --- a/gas/config/tc-avr.c +++ b/gas/config/tc-avr.c @@ -1,6 +1,6 @@ /* tc-avr.c -- Assembler code for the ATMEL AVR - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Denis Chertykov This file is part of GAS, the GNU Assembler. @@ -833,40 +833,14 @@ md_apply_fix3 (fixP, valP, seg) { unsigned char *where; unsigned long insn; - long value = * (long *) valP; + long value = *valP; if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; - else if (fixP->fx_pcrel) - { - segT s = S_GET_SEGMENT (fixP->fx_addsy); - - if (fixP->fx_addsy && (s == seg || s == absolute_section)) - { - value += S_GET_VALUE (fixP->fx_addsy); - fixP->fx_done = 1; - } - } - else - { - value = fixP->fx_offset; - - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - { - value -= S_GET_VALUE (fixP->fx_subsy); - fixP->fx_done = 1; - } - else - { - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } - } + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); switch (fixP->fx_r_type) { @@ -1039,7 +1013,6 @@ md_apply_fix3 (fixP, valP, seg) default: break; } - fixP->fx_addnumber = value; } } diff --git a/gas/config/tc-avr.h b/gas/config/tc-avr.h index 7aff4e2f80a..8a1a4eb9e30 100644 --- a/gas/config/tc-avr.h +++ b/gas/config/tc-avr.h @@ -1,5 +1,5 @@ /* This file is tc-avr.h - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Denis Chertykov @@ -24,101 +24,103 @@ #error AVR support requires BFD_ASSEMBLER #endif +/* By convention, you should define this macro in the `.h' file. For + example, `tc-m68k.h' defines `TC_M68K'. You might have to use this + if it is necessary to add CPU specific code to the object format + file. */ #define TC_AVR -/* By convention, you should define this macro in the `.h' file. For - example, `tc-m68k.h' defines `TC_M68K'. You might have to use this - if it is necessary to add CPU specific code to the object format - file. */ +/* This macro is the BFD target name to use when creating the output + file. This will normally depend upon the `OBJ_FMT' macro. */ #define TARGET_FORMAT "elf32-avr" -/* This macro is the BFD target name to use when creating the output - file. This will normally depend upon the `OBJ_FMT' macro. */ +/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'. */ #define TARGET_ARCH bfd_arch_avr -/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'. */ +/* This macro is the BFD machine number to pass to + `bfd_set_arch_mach'. If it is not defined, GAS will use 0. */ #define TARGET_MACH 0 -/* This macro is the BFD machine number to pass to - `bfd_set_arch_mach'. If it is not defined, GAS will use 0. */ +/* You should define this macro to be non-zero if the target is big + endian, and zero if the target is little endian. */ #define TARGET_BYTES_BIG_ENDIAN 0 -/* You should define this macro to be non-zero if the target is big - endian, and zero if the target is little endian. */ +/* If you define this macro, GAS will warn about the use of + nonstandard escape sequences in a string. */ #define ONLY_STANDARD_ESCAPES -/* If you define this macro, GAS will warn about the use of - nonstandard escape sequences in a string. */ +/* GAS will call this function for any expression that can not be + recognized. When the function is called, `input_line_pointer' + will point to the start of the expression. */ #define md_operand(x) -/* GAS will call this function for any expression that can not be - recognized. When the function is called, `input_line_pointer' - will point to the start of the expression. */ - -void avr_parse_cons_expression (expressionS *exp, int nbytes); +/* You may define this macro to parse an expression used in a data + allocation pseudo-op such as `.word'. You can use this to + recognize relocation directives that may appear in such directives. */ #define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR,N) -/* - You may define this macro to parse an expression used in a data - allocation pseudo-op such as `.word'. You can use this to - recognize relocation directives that may appear in such directives.*/ - -void avr_cons_fix_new(fragS *frag,int where, int nbytes, expressionS *exp); +void avr_parse_cons_expression (expressionS *exp, int nbytes); +/* You may define this macro to generate a fixup for a data + allocation pseudo-op. */ #define TC_CONS_FIX_NEW(FRAG,WHERE,N,EXP) avr_cons_fix_new(FRAG,WHERE,N,EXP) -/* You may define this macro to generate a fixup for a data - allocation pseudo-op. */ +void avr_cons_fix_new(fragS *frag,int where, int nbytes, expressionS *exp); +/* This should just call either `number_to_chars_bigendian' or + `number_to_chars_littleendian', whichever is appropriate. On + targets like the MIPS which support options to change the + endianness, which function to call is a runtime decision. On + other targets, `md_number_to_chars' can be a simple macro. */ #define md_number_to_chars number_to_chars_littleendian -/* This should just call either `number_to_chars_bigendian' or - `number_to_chars_littleendian', whichever is appropriate. On - targets like the MIPS which support options to change the - endianness, which function to call is a runtime decision. On - other targets, `md_number_to_chars' can be a simple macro. */ +/* `md_short_jump_size' + `md_long_jump_size' + `md_create_short_jump' + `md_create_long_jump' + If `WORKING_DOT_WORD' is defined, GAS will not do broken word + processing (*note Broken words::.). Otherwise, you should set + `md_short_jump_size' to the size of a short jump (a jump that is + just long enough to jump around a long jmp) and + `md_long_jump_size' to the size of a long jump (a jump that can go + anywhere in the function), You should define + `md_create_short_jump' to create a short jump around a long jump, + and define `md_create_long_jump' to create a long jump. */ #define WORKING_DOT_WORD -/* -`md_short_jump_size' -`md_long_jump_size' -`md_create_short_jump' -`md_create_long_jump' - If `WORKING_DOT_WORD' is defined, GAS will not do broken word - processing (*note Broken words::.). Otherwise, you should set - `md_short_jump_size' to the size of a short jump (a jump that is - just long enough to jump around a long jmp) and - `md_long_jump_size' to the size of a long jump (a jump that can go - anywhere in the function), You should define - `md_create_short_jump' to create a short jump around a long jump, - and define `md_create_long_jump' to create a long jump. */ +/* If you define this macro, it means that `tc_gen_reloc' may return + multiple relocation entries for a single fixup. In this case, the + return value of `tc_gen_reloc' is a pointer to a null terminated + array. */ #undef RELOC_EXPANSION_POSSIBLE -/* If you define this macro, it means that `tc_gen_reloc' may return - multiple relocation entries for a single fixup. In this case, the - return value of `tc_gen_reloc' is a pointer to a null terminated - array. */ - -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) -/* If you define this macro, it should return the offset between the - address of a PC relative fixup and the position from which the PC - relative adjustment should be made. On many processors, the base - of a PC relative instruction is the next instruction, so this - macro would return the length of an instruction. */ +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* If you define this macro, it should return the offset between the + address of a PC relative fixup and the position from which the PC + relative adjustment should be made. On many processors, the base + of a PC relative instruction is the next instruction, so this + macro would return the length of an instruction. */ +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); +/* The number of bytes to put into a word in a listing. This affects + the way the bytes are clumped together in the listing. For + example, a value of 2 might print `1234 5678' where a value of 1 + would print `12 34 56 78'. The default value is 4. */ #define LISTING_WORD_SIZE 2 -/* The number of bytes to put into a word in a listing. This affects - the way the bytes are clumped together in the listing. For - example, a value of 2 might print `1234 5678' where a value of 1 - would print `12 34 56 78'. The default value is 4. */ -#define LEX_DOLLAR 0 /* AVR port uses `$' as a logical line separator */ +#define LEX_DOLLAR 0 +/* An `.lcomm' directive with no explicit alignment parameter will + use this macro to set P2VAR to the alignment that a request for + SIZE bytes will have. The alignment is expressed as a power of + two. If no alignment should take place, the macro definition + should do nothing. Some targets define a `.bss' directive that is + also affected by this macro. The default definition will set + P2VAR to the truncated power of two of sizes up to eight bytes. */ #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0 -/* An `.lcomm' directive with no explicit alignment parameter will - use this macro to set P2VAR to the alignment that a request for - SIZE bytes will have. The alignment is expressed as a power of - two. If no alignment should take place, the macro definition - should do nothing. Some targets define a `.bss' directive that is - also affected by this macro. The default definition will set - P2VAR to the truncated power of two of sizes up to eight bytes. */ diff --git a/gas/config/tc-cris.c b/gas/config/tc-cris.c index b5e95270746..e41b467a48f 100644 --- a/gas/config/tc-cris.c +++ b/gas/config/tc-cris.c @@ -1,5 +1,5 @@ /* tc-cris.c -- Assembler code for the CRIS CPU core. - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Axis Communications AB, Lund, Sweden. Originally written for GAS 1.38.1 by Mikael Asker. @@ -2895,10 +2895,8 @@ tc_gen_reloc (section, fixP) relP->address = fixP->fx_frag->fr_address + fixP->fx_where; if (fixP->fx_pcrel) - /* FIXME: Is this correct? */ - relP->addend = fixP->fx_addnumber; + relP->addend = 0; else - /* At least *this one* is correct. */ relP->addend = fixP->fx_offset; /* This is the standard place for KLUDGEs to work around bugs in @@ -2994,17 +2992,10 @@ md_apply_fix3 (fixP, valP, seg) } else { - /* I took this from tc-arc.c, since we used to not support - fx_subsy != NULL. I'm not totally sure it's TRT. */ + /* We can't actually support subtracting a symbol. */ if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - val -= S_GET_VALUE (fixP->fx_subsy); - else - /* We can't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } + as_bad_where (fixP->fx_file, fixP->fx_line, + _("expression too complex")); cris_number_to_imm (buf, val, fixP->fx_size, fixP, seg); } @@ -3042,10 +3033,10 @@ md_undefined_symbol (name) return 0; } -/* Definition of TC_FORCE_RELOCATION. - FIXME: Unsure of this. Can we omit it? Just copied from tc-i386.c - when doing multi-object format with ELF, since it's the only other - multi-object-format target with a.out and ELF. */ +/* If this function returns non-zero, it prevents the relocation + against symbol(s) in the FIXP from being replaced with relocations + against section symbols, and guarantees that a relocation will be + emitted even when the value can be resolved locally. */ int md_cris_force_relocation (fixp) struct fix *fixp; @@ -3066,7 +3057,7 @@ md_cris_force_relocation (fixp) ; } - return 0; + return S_FORCE_RELOC (fixp->fx_addsy); } /* Check and emit error if broken-word handling has failed to fix up a diff --git a/gas/config/tc-cris.h b/gas/config/tc-cris.h index d1d4b29bdfd..d20e0a83a95 100644 --- a/gas/config/tc-cris.h +++ b/gas/config/tc-cris.h @@ -1,5 +1,5 @@ /* tc-cris.h -- Header file for tc-cris.c, the CRIS GAS port. - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Axis Communications AB, Lund, Sweden. Originally written for GAS 1.38.1 by Mikael Asker. @@ -75,44 +75,33 @@ extern const int md_long_jump_size; extern const struct relax_type md_cris_relax_table[]; #define TC_GENERIC_RELAX_TABLE md_cris_relax_table -#define TC_FORCE_RELOCATION(fixp) md_cris_force_relocation (fixp) +#define TC_FORCE_RELOCATION(FIX) md_cris_force_relocation (FIX) extern int md_cris_force_relocation PARAMS ((struct fix *)); -#define IS_CRIS_PIC_RELOC(X) \ - ((X) == BFD_RELOC_CRIS_16_GOT \ - || (X) == BFD_RELOC_CRIS_32_GOT \ - || (X) == BFD_RELOC_CRIS_16_GOTPLT \ - || (X) == BFD_RELOC_CRIS_32_GOTPLT \ - || (X) == BFD_RELOC_CRIS_32_GOTREL \ - || (X) == BFD_RELOC_CRIS_32_PLT_GOTREL \ - || (X) == BFD_RELOC_CRIS_32_PLT_PCREL) - - -/* FIXME: Undocumented macro. Make sure we don't resolve fixups for which - we want to emit dynamic relocations. */ - -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy) \ - /* FIXME: Set fx_plt instead of this check. */ \ - && ! IS_CRIS_PIC_RELOC ((FIX)->fx_r_type))) - -/* This is really a workaround for a bug in write.c that resolves relocs - for weak symbols - it should be postponed to the link stage or later. - Also don't adjust fixups for global symbols for ELF, and no relocs - where the original symbol name must be kept. */ -#define tc_fix_adjustable(X) \ - (((X)->fx_addsy == NULL \ - || (! S_IS_WEAK ((X)->fx_addsy) \ - && ! (OUTPUT_FLAVOR == bfd_target_elf_flavour \ - && S_IS_EXTERNAL ((X)->fx_addsy)))) \ - && (X)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ - && (X)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \ - && (! IS_CRIS_PIC_RELOC ((X)->fx_r_type) \ - || (X)->fx_r_type == BFD_RELOC_CRIS_32_GOTREL)) +#define IS_CRIS_PIC_RELOC(RTYPE) \ + ((RTYPE) == BFD_RELOC_CRIS_16_GOT \ + || (RTYPE) == BFD_RELOC_CRIS_32_GOT \ + || (RTYPE) == BFD_RELOC_CRIS_16_GOTPLT \ + || (RTYPE) == BFD_RELOC_CRIS_32_GOTPLT \ + || (RTYPE) == BFD_RELOC_CRIS_32_GOTREL \ + || (RTYPE) == BFD_RELOC_CRIS_32_PLT_GOTREL \ + || (RTYPE) == BFD_RELOC_CRIS_32_PLT_PCREL) + +/* Make sure we don't resolve fixups for which we want to emit dynamic + relocations. FIXME: Set fx_plt instead of using IS_CRIS_PIC_RELOC. */ +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || IS_CRIS_PIC_RELOC ((FIX)->fx_r_type) \ + || TC_FORCE_RELOCATION (FIX)) + +/* For some reloc types, don't adjust fixups by reducing to a section + symbol. */ +#define tc_fix_adjustable(FIX) \ + ((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ + && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \ + && (! IS_CRIS_PIC_RELOC ((FIX)->fx_r_type) \ + || (FIX)->fx_r_type == BFD_RELOC_CRIS_32_GOTREL)) /* When we have fixups against constant expressions, we get a GAS-specific section symbol at no extra charge for obscure reasons in diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c index 679315f549a..8dab9a1e538 100644 --- a/gas/config/tc-d10v.c +++ b/gas/config/tc-d10v.c @@ -1661,11 +1661,10 @@ tc_gen_reloc (seg, fixp) return NULL; } - if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) reloc->address = fixp->fx_offset; - reloc->addend = fixp->fx_addnumber; + reloc->addend = 0; return reloc; } @@ -1694,37 +1693,21 @@ md_pcrel_from_section (fixp, sec) void md_apply_fix3 (fixP, valP, seg) fixS *fixP; - valueT * valP; + valueT *valP; segT seg ATTRIBUTE_UNUSED; { char *where; unsigned long insn; - long value = * (long *) valP; + long value = *valP; int op_type; int left = 0; if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; - else if (fixP->fx_pcrel) - ; - - else - { - value = fixP->fx_offset; - - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } - } + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); op_type = fixP->fx_r_type; if (op_type & 2048) @@ -1913,16 +1896,6 @@ boolean d10v_fix_adjustable (fixP) fixS *fixP; { - if (fixP->fx_addsy == NULL) - return 1; - - /* Prevent all adjustments to global and weak symbols or symbols in - merge sections. */ - if ((S_IS_EXTERN (fixP->fx_addsy) - || (S_IS_WEAK (fixP->fx_addsy)) - || (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)) - return 0; - /* We need the symbol name for the VTABLE entries. */ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) @@ -1939,5 +1912,5 @@ d10v_force_relocation (fixp) || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - return 0; + return S_FORCE_RELOC (fixp->fx_addsy); } diff --git a/gas/config/tc-d10v.h b/gas/config/tc-d10v.h index 68159505027..53fe66e7555 100644 --- a/gas/config/tc-d10v.h +++ b/gas/config/tc-d10v.h @@ -19,8 +19,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "write.h" /* For the definition of fixS. */ - #define TC_D10V #define TARGET_BYTES_BIG_ENDIAN 0 @@ -35,8 +33,9 @@ #define TARGET_FORMAT "elf32-d10v" /* Call md_pcrel_from_section, not md_pcrel_from. */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) -long md_pcrel_from_section PARAMS ((fixS *, segT)); +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) +struct fix; +long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -58,9 +57,17 @@ int d10v_cleanup PARAMS ((void)); S_SET_VALUE (sym, (valueT) frag_now_fix ()); \ } while (0) -#define obj_fix_adjustable(fixP) d10v_fix_adjustable(fixP) -boolean d10v_fix_adjustable PARAMS ((fixS *)); -#define TC_FORCE_RELOCATION(fixp) d10v_force_relocation(fixp) -extern int d10v_force_relocation PARAMS ((fixS *)); +#define tc_fix_adjustable(FIX) d10v_fix_adjustable(FIX) +boolean d10v_fix_adjustable PARAMS ((struct fix *)); + +#define TC_FORCE_RELOCATION(FIX) d10v_force_relocation(FIX) +extern int d10v_force_relocation PARAMS ((struct fix *)); + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 #define md_flush_pending_output d10v_cleanup diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c index b0b058f3330..4b547b370b7 100644 --- a/gas/config/tc-d30v.c +++ b/gas/config/tc-d30v.c @@ -1808,7 +1808,8 @@ tc_gen_reloc (seg, fixp) (int) fixp->fx_r_type); return NULL; } - reloc->addend = fixp->fx_addnumber; + + reloc->addend = 0; return reloc; } @@ -1836,33 +1837,19 @@ md_pcrel_from_section (fixp, sec) void md_apply_fix3 (fixP, valP, seg) fixS *fixP; - valueT * valP; + valueT *valP; segT seg; { char *where; unsigned long insn, insn2; - long value = * (long *) valP; + long value = *valP; if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; - else if (fixP->fx_pcrel) - ; - - else - { - value = fixP->fx_offset; - - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } + /* We don't support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); /* Fetch the instruction, insert the fully resolved operand value, and stuff the instruction back again. */ diff --git a/gas/config/tc-d30v.h b/gas/config/tc-d30v.h index 0b2b25cf998..e0f7475bf41 100644 --- a/gas/config/tc-d30v.h +++ b/gas/config/tc-d30v.h @@ -1,5 +1,5 @@ /* tc-310v.h -- Header file for tc-d30v.c. - Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc. + Copyright 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Martin Hunt, Cygnus Support. This file is part of GAS, the GNU Assembler. @@ -19,8 +19,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "write.h" /* For the definition of fixS. */ - #define TC_D30V #ifndef BFD_ASSEMBLER @@ -35,8 +33,9 @@ #define md_operand(x) /* Call md_pcrel_from_section, not md_pcrel_from. */ -extern long md_pcrel_from_section PARAMS ((fixS *fixp, segT sec)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +struct fix; +extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -60,3 +59,10 @@ void d30v_frob_label PARAMS ((symbolS *)); void d30v_cons_align PARAMS ((int)); #define md_cons_align(nbytes) d30v_cons_align(nbytes) + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 diff --git a/gas/config/tc-dlx.c b/gas/config/tc-dlx.c index 9722d0db96f..1fc0ab5e7dc 100644 --- a/gas/config/tc-dlx.c +++ b/gas/config/tc-dlx.c @@ -1150,7 +1150,8 @@ md_dlx_force_relocation (fixp) struct fix *fixp; { return (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY); + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY + || S_FORCE_RELOC (fixp->fx_addsy)); } boolean @@ -1158,15 +1159,14 @@ md_dlx_fix_adjustable (fixP) fixS *fixP; { /* We need the symbol name for the VTABLE entries. */ - return !(fixP->fx_addsy != NULL && - (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)) ; + return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT + && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY); } void md_apply_fix3 (fixP, valP, seg) fixS *fixP; - valueT * valP; + valueT *valP; segT seg ATTRIBUTE_UNUSED; { long val = *valP; @@ -1234,7 +1234,7 @@ md_apply_fix3 (fixP, valP, seg) } number_to_chars_bigendian (place, val, fixP->fx_size); - if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) + if (fixP->fx_addsy == NULL) fixP->fx_done = 1; return; } @@ -1442,11 +1442,10 @@ tc_gen_reloc (section, fixP) *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); reloc->address = fixP->fx_frag->fr_address + fixP->fx_where; - if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || - fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - reloc->addend = fixP->fx_offset; - else - reloc->addend = fixP->fx_addnumber; + if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->address = fixP->fx_offset; + reloc->addend = 0; + return reloc; } diff --git a/gas/config/tc-dlx.h b/gas/config/tc-dlx.h index cbdf7f79592..691981fa507 100644 --- a/gas/config/tc-dlx.h +++ b/gas/config/tc-dlx.h @@ -20,8 +20,6 @@ /* Initially created by Kuang Hwa Lin, 3/20/2002. */ -#include "write.h" /* For the definition of fixS. */ - #define TC_DLX #ifndef BFD_ASSEMBLER @@ -47,8 +45,7 @@ extern int set_dlx_skip_hi16_flag PARAMS ((int)); #define md_pop_insert() dlx_pop_insert () -#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n") -#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n") +#define md_convert_frag(b,s,f) as_fatal ("convert_frag called\n") #define md_estimate_size_before_relax(f,s) \ (as_fatal ("estimate_size_before_relax called"),1) @@ -73,18 +70,20 @@ extern int dlx_unrecognized_line PARAMS ((int)); #define TC_COUNT_RELOC(x) (x->fx_addsy) #define TC_CONS_RELOC BFD_RELOC_32_PCREL +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* We need to force out some relocations when relaxing. */ -#define TC_FORCE_RELOCATION(fix) md_dlx_force_relocation (fix) +#define TC_FORCE_RELOCATION(FIX) md_dlx_force_relocation (FIX) struct fix; extern int md_dlx_force_relocation PARAMS ((struct fix *)); -#define obj_fix_adjustable(fixP) md_dlx_fix_adjustable(fixP) -struct fix; +#define tc_fix_adjustable(FIX) md_dlx_fix_adjustable (FIX) extern boolean md_dlx_fix_adjustable PARAMS ((struct fix *)); -/* This arranges for gas/write.c to not apply a relocation if - obj_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #define NEED_FX_R_TYPE @@ -93,10 +92,8 @@ extern boolean md_dlx_fix_adjustable PARAMS ((struct fix *)); /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 -#ifdef LOCAL_LABELS_DOLLAR + #undef LOCAL_LABELS_DOLLAR -#endif #define LOCAL_LABELS_DOLLAR 0 #define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ - diff --git a/gas/config/tc-fr30.c b/gas/config/tc-fr30.c index 26768fe5cc8..54a12bfb346 100644 --- a/gas/config/tc-fr30.c +++ b/gas/config/tc-fr30.c @@ -1,5 +1,5 @@ /* tc-fr30.c -- Assembler for the Fujitsu FR30. - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -479,11 +479,11 @@ int fr30_force_relocation (fix) fixS * fix; { - if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT + if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - return 0; + return S_FORCE_RELOC (fix->fx_addsy); } /* Write a value out to the object file, using the appropriate endianness. */ @@ -645,20 +645,8 @@ boolean fr30_fix_adjustable (fixP) fixS * fixP; { - if (fixP->fx_addsy == NULL) - return 1; - -#if 0 - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; -#endif - /* We need the symbol name for the VTABLE entries */ - if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; diff --git a/gas/config/tc-fr30.h b/gas/config/tc-fr30.h index a9edc601778..be817cffbad 100644 --- a/gas/config/tc-fr30.h +++ b/gas/config/tc-fr30.h @@ -1,5 +1,5 @@ /* tc-fr30.h -- Header file for tc-fr30.c. - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -34,10 +34,6 @@ #define TARGET_BYTES_BIG_ENDIAN 1 -/* call md_pcrel_from_section, not md_pcrel_from */ -long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) - /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -46,9 +42,13 @@ long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* We don't need to handle .word strangely. */ #define WORKING_DOT_WORD +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define md_apply_fix3 gas_cgen_md_apply_fix3 -#define obj_fix_adjustable(fixP) fr30_fix_adjustable (fixP) +#define tc_fix_adjustable(FIX) fr30_fix_adjustable (FIX) +struct fix; extern boolean fr30_fix_adjustable PARAMS ((struct fix *)); /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ @@ -58,7 +58,7 @@ extern int fr30_force_relocation PARAMS ((struct fix *)); #define tc_gen_reloc gas_cgen_tc_gen_reloc /* Call md_pcrel_from_section(), not md_pcrel_from(). */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* For 8 vs 16 vs 32 bit branch selection. */ diff --git a/gas/config/tc-frv.c b/gas/config/tc-frv.c index 2a7db7075f2..6dbe78aa937 100644 --- a/gas/config/tc-frv.c +++ b/gas/config/tc-frv.c @@ -1226,7 +1226,7 @@ frv_force_relocation (fix) || fix->fx_r_type == BFD_RELOC_FRV_GPRELU12) return 1; - return 0; + return S_FORCE_RELOC (fix->fx_addsy); } /* Write a value out to the object file, using the appropriate endianness. */ @@ -1314,16 +1314,6 @@ frv_fix_adjustable (fixP) else reloc_type = fixP->fx_r_type; - if (fixP->fx_addsy == NULL) - return 1; - - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - /* We need the symbol name for the VTABLE entries */ if ( reloc_type == BFD_RELOC_VTABLE_INHERIT || reloc_type == BFD_RELOC_VTABLE_ENTRY diff --git a/gas/config/tc-frv.h b/gas/config/tc-frv.h index b399cd93310..843a9346bdf 100644 --- a/gas/config/tc-frv.h +++ b/gas/config/tc-frv.h @@ -34,10 +34,6 @@ #define TARGET_BYTES_BIG_ENDIAN 1 -/* call md_pcrel_from_section, not md_pcrel_from */ -long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) - /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -46,6 +42,9 @@ long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* We don't need to handle .word strangely. */ #define WORKING_DOT_WORD +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define md_apply_fix3 gas_cgen_md_apply_fix3 extern void frv_tomcat_workaround PARAMS ((void)); @@ -56,15 +55,10 @@ extern void frv_tomcat_workaround PARAMS ((void)); extern long frv_relax_frag PARAMS ((fragS *, long)); #define md_relax_frag(segment, fragP, stretch) frv_relax_frag(fragP, stretch) -#define obj_fix_adjustable(fixP) frv_fix_adjustable (fixP) +#define tc_fix_adjustable(FIX) frv_fix_adjustable (FIX) +struct fix; extern boolean frv_fix_adjustable PARAMS ((struct fix *)); -#ifdef OBJ_ELF -/* This arranges for gas/write.c to not apply a relocation if - obj_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP) -#endif - /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ #define TC_FORCE_RELOCATION(fix) frv_force_relocation (fix) extern int frv_force_relocation PARAMS ((struct fix *)); @@ -80,7 +74,7 @@ void frv_frob_label PARAMS ((symbolS *)); #define md_cgen_record_fixup_exp frv_cgen_record_fixup_exp /* Call md_pcrel_from_section(), not md_pcrel_from(). */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* After all of the symbols have been adjusted, go over the file looking diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index 641a7e54263..07103209b55 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -1510,7 +1510,7 @@ md_apply_fix3 (fixP, valP, seg) segT seg ATTRIBUTE_UNUSED; { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - long val = * (long *) valP; + long val = *valP; switch (fixP->fx_size) { diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h index 79647a637f2..4b2808e6ebe 100644 --- a/gas/config/tc-h8300.h +++ b/gas/config/tc-h8300.h @@ -1,6 +1,6 @@ /* This file is tc-h8300.h Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 2000 + 1997, 1998, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -35,6 +35,7 @@ #endif #if ANSI_PROTOTYPES +struct fix; struct internal_reloc; #endif @@ -53,6 +54,10 @@ struct internal_reloc; extern void tc_reloc_mangle PARAMS ((struct fix *, struct internal_reloc *, bfd_vma)); +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + #ifdef OBJ_ELF /* Provide mappings from the original H8 COFF relocation names to their corresponding BFD relocation names. This allows us to use diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 61e2a321cf8..166b50c0ce9 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -4483,13 +4483,6 @@ md_apply_fix3 (fixP, valP, seg) || hppa_fixP->fx_r_field == e_rtsel || hppa_fixP->fx_r_field == e_ltsel) new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0); - /* This is truly disgusting. The machine independent code blindly - adds in the value of the symbol being relocated against. Damn! */ - else if (fmt == 32 - && fixP->fx_addsy != NULL - && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr) - new_val = hppa_field_adjust (* valP - S_GET_VALUE (fixP->fx_addsy), - 0, hppa_fixP->fx_r_field); #endif else new_val = hppa_field_adjust (* valP, 0, hppa_fixP->fx_r_field); @@ -8426,10 +8419,6 @@ hppa_fix_adjustable (fixp) } #endif - if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy) - || S_IS_WEAK (fixp->fx_addsy))) - return 0; - /* Reject reductions of symbols in sym1-sym2 expressions when the fixup will occur in a CODE subspace. @@ -8439,11 +8428,7 @@ hppa_fix_adjustable (fixp) if (fixp->fx_addsy && fixp->fx_subsy && (hppa_fix->segment->flags & SEC_CODE)) - { - /* Apparently sy_used_in_reloc never gets set for sub symbols. */ - symbol_mark_used_in_reloc (fixp->fx_subsy); - return 0; - } + return 0; /* We can't adjust any relocs that use LR% and RR% field selectors. @@ -8533,7 +8518,7 @@ hppa_force_relocation (fixp) /* Ensure we emit a relocation for global symbols so that dynamic linking works. */ - if (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)) + if (S_FORCE_RELOC (fixp->fx_addsy)) return 1; /* It is necessary to force PC-relative calls/jumps to have a relocation diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index 3d9d00a3bb0..aa023465512 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -133,10 +133,12 @@ extern void pa_check_eof PARAMS ((void)); int hppa_fix_adjustable PARAMS((struct fix *)); #define tc_fix_adjustable hppa_fix_adjustable +#define EXTERN_FORCE_RELOC 1 + /* Because of the strange PA calling conventions, it is sometimes necessary to emit a relocation for a call even though it would normally appear safe to handle it completely within GAS. */ -#define TC_FORCE_RELOCATION(FIXP) hppa_force_relocation (FIXP) +#define TC_FORCE_RELOCATION(FIX) hppa_force_relocation (FIX) #ifdef OBJ_SOM /* If a symbol is imported, but never used, then the symbol should @@ -160,9 +162,8 @@ int hppa_fix_adjustable PARAMS((struct fix *)); #endif #ifdef OBJ_ELF -/* It's OK to subtract two symbols in the same section without - emitting a relocation. */ -#define TC_FORCE_RELOCATION_SECTION(FIXP, SEC) 0 +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 /* Handle .type psuedo. Given a type string of `millicode', set the internal elf symbol type to STT_PARISC_MILLI, and return @@ -201,6 +202,6 @@ int hppa_force_reg_syms_absolute PARAMS ((expressionS *, operatorT, expressionS *)); #define TC_FIX_TYPE PTR -#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL) +#define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data = NULL) #endif /* _TC_HPPA_H */ diff --git a/gas/config/tc-i370.c b/gas/config/tc-i370.c index 784411d9d86..5c4687176b0 100644 --- a/gas/config/tc-i370.c +++ b/gas/config/tc-i370.c @@ -2723,36 +2723,6 @@ md_apply_fix3 (fixP, valP, seg) if (fixP->fx_addsy != NULL) { - /* Notes: - Branches to labels will come in here with fixP->fx_pcrel set to 1 - and fixP->fx_subsy not null, and holding the value of the base - (i.e. the value of the .using). These we want to ignore. - - 'Strong' and 'weak' symbols will come in here with - fixP->fx_pcrel==0, fixP->fx_addsy defined, and - *valuep holding the value of the symbol. - - 'Strong' symbols will have S_GET_VALUE(fx_addsy) equal to zero, - whereas 'weak' symbols will have S_GET_VALUE(fx_addsy) set to the - symbol value (usually). - - We want to subtract S_GET_VALUE(fx_addsy) if it set, and - for all practical purposes, do a fixup with value zero. This - is because the linker/loader, at a later time, will do this - fixup with the correct value. If we fixup now with a value, - it will get double-fixed, leading to garbage. - - Note that subsy will also be set for strong/weak symbols - when the user program was compiled with -g. In that case, - subsy will hold the base address (i.e. the .using address). - */ - - if (fixP->fx_addsy->sy_used_in_reloc - && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section - && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section - && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy))) - value -= S_GET_VALUE (fixP->fx_addsy); - #ifdef DEBUG printf ("\nmd_apply_fix3: symbol %s at 0x%x (%s:%d) val=0x%x addend=0x%x\n", S_GET_NAME (fixP->fx_addsy), @@ -2762,10 +2732,7 @@ md_apply_fix3 (fixP, valP, seg) #endif } else - { - fixP->fx_done = 1; - return; - } + fixP->fx_done = 1; /* Apply fixups to operands. Note that there should be no relocations for any operands, since no instruction ever takes an operand diff --git a/gas/config/tc-i370.h b/gas/config/tc-i370.h index 7ddc12ce623..81007ac97da 100644 --- a/gas/config/tc-i370.h +++ b/gas/config/tc-i370.h @@ -1,5 +1,5 @@ /* tc-i370.h -- Header file for tc-i370.c. - Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001 + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. @@ -43,9 +43,7 @@ extern enum bfd_architecture i370_arch PARAMS ((void)); extern int target_big_endian; /* The target BFD format. */ -#ifdef OBJ_ELF #define TARGET_FORMAT ("elf32-i370") -#endif /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -53,15 +51,16 @@ extern int target_big_endian; /* $ is used to refer to the current location. */ /* #define DOLLAR_DOT */ -#ifdef OBJ_ELF #define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */ -#endif + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 /* We don't need to handle .word strangely. */ #define WORKING_DOT_WORD /* Call md_pcrel_from_section, not md_pcrel_from. */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define md_operand(x) diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 59e19dd1a2c..e79ae77dfb3 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1213,15 +1213,11 @@ tc_i386_fix_adjustable (fixP) if (OUTPUT_FLAVOR != bfd_target_elf_flavour) return 1; - /* Prevent all adjustments to global symbols, or else dynamic - linking will not work correctly. */ - if (S_IS_EXTERNAL (fixP->fx_addsy) - || S_IS_WEAK (fixP->fx_addsy) - /* Don't adjust pc-relative references to merge sections in 64-bit - mode. */ - || (use_rela_relocations - && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0 - && fixP->fx_pcrel)) + /* Don't adjust pc-relative references to merge sections in 64-bit + mode. */ + if (use_rela_relocations + && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0 + && fixP->fx_pcrel) return 0; /* adjust_reloc_syms doesn't know about the GOT. */ @@ -4597,7 +4593,7 @@ md_apply_fix3 (fixP, valP, seg) } } - if (fixP->fx_pcrel + if (fixP->fx_addsy != NULL && (fixP->fx_r_type == BFD_RELOC_32_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL || fixP->fx_r_type == BFD_RELOC_8_PCREL) @@ -5113,6 +5109,17 @@ i386_validate_fix (fixp) } } +boolean +i386_force_relocation (fixp) + fixS *fixp; +{ + if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 1; + + return S_FORCE_RELOC (fixp->fx_addsy); +} + arelent * tc_gen_reloc (section, fixp) asection *section ATTRIBUTE_UNUSED; diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index 580b96eeb82..2c4cd16b1eb 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -88,7 +88,7 @@ extern void i386_elf_emit_arch_note PARAMS ((void)); #define BFD_ARCH bfd_arch_i386 #define COFF_FLAGS F_AR32WR #define TC_COUNT_RELOC(x) ((x)->fx_addsy || (x)->fx_r_type==7) -#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP) +#define TC_COFF_FIX2RTYPE(FIX) tc_coff_fix2rtype(FIX) extern short tc_coff_fix2rtype PARAMS ((struct fix *)); #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep (frag) extern int tc_coff_sizemachdep PARAMS ((fragS *frag)); @@ -455,49 +455,33 @@ extern void x86_cons_fix_new #define NO_RELOC BFD_RELOC_NONE void i386_validate_fix PARAMS ((struct fix *)); -#define TC_VALIDATE_FIX(FIXP,SEGTYPE,SKIP) i386_validate_fix(FIXP) - -/* This is used to determine relocation types in tc-i386.c. The first - parameter is the current relocation type, the second one is the desired - type. The idea is that if the original type is already some kind of PIC - relocation, we leave it alone, otherwise we give it the desired type */ +#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX) #define tc_fix_adjustable(X) tc_i386_fix_adjustable(X) extern int tc_i386_fix_adjustable PARAMS ((struct fix *)); -#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) || defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF)) && !defined (TE_PE) -/* This arranges for gas/write.c to not apply a relocation if - tc_fix_adjustable() says it is not adjustable. - The "! symbol_used_in_reloc_p" test is there specifically to cover - the case of non-global symbols in linkonce sections. It's the - generally correct thing to do though; If a reloc is going to be - emitted against a symbol then we don't want to adjust the fixup by - applying the reloc during assembly. The reloc will be applied by - the linker during final link. */ -#define TC_FIX_ADJUSTABLE(fixP) \ - (! symbol_used_in_reloc_p ((fixP)->fx_addsy) && tc_fix_adjustable (fixP)) +#ifndef TE_PE +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #endif -#define TC_FORCE_RELOCATION(FIXP) \ - ((FIXP)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ - || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_ENTRY) +#define TC_FORCE_RELOCATION(FIX) i386_force_relocation (FIX) +extern boolean i386_force_relocation PARAMS ((struct fix *)); -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we - are willing to perform this relocation while building the .o file. - This is only used for pcrel relocations, so GOTOFF does not need to be - checked here. I am not sure if some of the others are ever used with +/* This expression evaluates to true if the relocation is for a local + object for which we still want to do the relocation at runtime. + False if we are willing to perform this relocation while building + the .o file. GOTOFF does not need to be checked here because it is + not pcrel. I am not sure if some of the others are ever used with pcrel, but it is easier to be safe than sorry. */ -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_r_type != BFD_RELOC_386_PLT32 \ - && (FIX)->fx_r_type != BFD_RELOC_386_GOT32 \ - && (FIX)->fx_r_type != BFD_RELOC_386_GOTPC \ - && ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy)))) +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || (FIX)->fx_r_type == BFD_RELOC_386_PLT32 \ + || (FIX)->fx_r_type == BFD_RELOC_386_GOT32 \ + || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC \ + || TC_FORCE_RELOCATION (FIX)) #else /* ! BFD_ASSEMBLER */ @@ -511,8 +495,8 @@ extern int tc_i386_fix_adjustable PARAMS ((struct fix *)); #undef REVERSE_SORT_RELOCS /* For COFF. */ -#define TC_FORCE_RELOCATION(FIXP) \ - ((FIXP)->fx_r_type == 7) +#define TC_FORCE_RELOCATION(FIX) \ + ((FIX)->fx_r_type == 7 || S_FORCE_RELOC ((FIX)->fx_addsy)) #endif /* ! BFD_ASSEMBLER */ #define md_operand(x) diff --git a/gas/config/tc-i860.c b/gas/config/tc-i860.c index 61724f5864a..5535cbf1006 100644 --- a/gas/config/tc-i860.c +++ b/gas/config/tc-i860.c @@ -1236,7 +1236,7 @@ md_apply_fix3 (fix, valP, seg) segT seg ATTRIBUTE_UNUSED; { char *buf; - long val = * (long *) valP + long val = *valP; unsigned long insn; valueT fup; diff --git a/gas/config/tc-i860.h b/gas/config/tc-i860.h index c5247297e27..72a5b6a52b5 100644 --- a/gas/config/tc-i860.h +++ b/gas/config/tc-i860.h @@ -1,5 +1,5 @@ /* tc-i860.h -- Header file for the i860. - Copyright 1991, 1992, 1995, 1998, 2000, 2001 + Copyright 1991, 1992, 1995, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. Brought back from the dead and completely reworked @@ -79,4 +79,11 @@ extern int target_big_endian; #define md_convert_frag(b,s,f) as_fatal (_("i860_convert_frag\n")); +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + #endif /* TC_I860 */ diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c index d238b9cef2d..41f953a914e 100644 --- a/gas/config/tc-i960.c +++ b/gas/config/tc-i960.c @@ -152,7 +152,6 @@ static void parse_memop (); /* Parse a memory operand */ static void parse_po (); /* Parse machine-dependent pseudo-op */ static void parse_regop (); /* Parse a register operand */ static void reg_fmt (); /* Generate a REG format instruction */ -void reloc_callj (); /* Relocate a 'callj' instruction */ static void relax_cobr (); /* "De-optimize" cobr into compare/branch */ static void s_leafproc (); /* Process '.leafproc' pseudo-op */ static void s_sysproc (); /* Process '.sysproc' pseudo-op */ @@ -2501,7 +2500,7 @@ relax_cobr (fragP) passed fixup structure. *************************************************************************** */ -void +int reloc_callj (fixP) /* Relocation that can be done at assembly time */ fixS *fixP; @@ -2512,7 +2511,7 @@ reloc_callj (fixP) if (!fixP->fx_tcbit) { /* This wasn't a callj instruction in the first place */ - return; + return 0; } where = fixP->fx_frag->fr_literal + fixP->fx_where; @@ -2526,7 +2525,6 @@ reloc_callj (fixP) /* Nothing else needs to be done for this instruction. Make sure 'md_number_to_field()' will perform a no-op. */ fixP->fx_bit_fixP = (bit_fixS *) 1; - } else if (TC_S_IS_CALLNAME (fixP->fx_addsy)) { @@ -2546,6 +2544,7 @@ reloc_callj (fixP) } /* switch on proc type */ /* else Symbol is neither a sysproc nor a leafproc */ + return 0; } /***************************************************************************** @@ -2810,10 +2809,10 @@ md_pcrel_from (fixP) void md_apply_fix3 (fixP, valP, seg) fixS *fixP; - valueT * valP; + valueT *valP; segT seg ATTRIBUTE_UNUSED; { - long val = * (long *) valP; + long val = *valP; char *place = fixP->fx_where + fixP->fx_frag->fr_literal; if (!fixP->fx_bit_fixP) @@ -2829,10 +2828,22 @@ md_apply_fix3 (fixP, valP, seg) md_number_to_imm (place, val, fixP->fx_size, fixP); } + else if ((int) fixP->fx_bit_fixP == 13 + && fixP->fx_addsy != NULL + && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section) + { + /* This is a COBR instruction. They have only a + 13-bit displacement and are only to be used + for local branches: flag as error, don't generate + relocation. */ + as_bad_where (fixP->fx_file, fixP->fx_line, + _("can't use COBR format with external label")); + fixP->fx_addsy = NULL; + } else md_number_to_field (place, val, fixP->fx_bit_fixP); - if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) + if (fixP->fx_addsy == NULL) fixP->fx_done = 1; } @@ -3191,47 +3202,26 @@ i960_handle_align (fragp) } int -i960_validate_fix (fixP, this_segment_type, add_symbolPP) +i960_validate_fix (fixP, this_segment_type) fixS *fixP; segT this_segment_type; - symbolS **add_symbolPP; { -#define add_symbolP (*add_symbolPP) - if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP)) + if (fixP->fx_tcbit && TC_S_IS_CALLNAME (fixP->fx_addsy)) { /* Relocation should be done via the associated 'bal' entry point symbol. */ - if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP))) + if (!TC_S_IS_BALNAME (tc_get_bal_of_call (fixP->fx_addsy))) { - as_bad (_("No 'bal' entry point for leafproc %s"), - S_GET_NAME (add_symbolP)); - return 1; + as_bad_where (fixP->fx_file, fixP->fx_line, + _("No 'bal' entry point for leafproc %s"), + S_GET_NAME (fixP->fx_addsy)); + return 0; } - fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP); + fixP->fx_addsy = tc_get_bal_of_call (fixP->fx_addsy); } -#if 0 - /* Still have to work out other conditions for these tests. */ - { - if (fixP->fx_tcbit) - { - as_bad (_("callj to difference of two symbols")); - return 1; - } - reloc_callj (fixP); - if ((int) fixP->fx_bit_fixP == 13) - { - /* This is a COBR instruction. They have only a 13-bit - displacement and are only to be used for local branches: - flag as error, don't generate relocation. */ - as_bad (_("can't use COBR format with external label")); - fixP->fx_addsy = NULL; /* No relocations please. */ - return 1; - } - } -#endif -#undef add_symbolP - return 0; + + return 1; } #ifdef BFD_ASSEMBLER diff --git a/gas/config/tc-i960.h b/gas/config/tc-i960.h index dfc0a4d727b..f75fc3ba567 100644 --- a/gas/config/tc-i960.h +++ b/gas/config/tc-i960.h @@ -1,6 +1,6 @@ /* tc-i960.h - Basic 80960 instruction formats. Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, - 2000 + 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -62,13 +62,11 @@ #define COFF_MAGIC I960ROMAGIC #define OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT #define OBJ_COFF_MAX_AUXENTRIES (2) -#define TC_COUNT_RELOC(FIXP) (!(FIXP)->fx_done) -#define TC_COFF_FIX2RTYPE(FIXP) tc_coff_fix2rtype (FIXP) +#define TC_COUNT_RELOC(FIX) (!(FIX)->fx_done) +#define TC_COFF_FIX2RTYPE(FIX) tc_coff_fix2rtype (FIX) #define TC_COFF_SIZEMACHDEP(FRAGP) tc_coff_sizemachdep (FRAGP) #define TC_COFF_SET_MACHINE(HDRS) tc_headers_hook (HDRS) -extern void tc_headers_hook (); -extern short tc_coff_fix2rtype (); -extern int tc_coff_sizemachdep (); +extern int tc_coff_sizemachdep PARAMS ((struct frag *)); /* MEANING OF 'n_other' in the symbol record. * @@ -128,54 +126,66 @@ struct relocation_info nuthin:1; /* Unused */ }; +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +/* Makes no sense to use the difference of 2 arbitrary symbols + as the target of a call instruction. */ +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + ((FIX)->fx_tcbit \ + || ! SEG_NORMAL (SEG)) + +/* reloc_callj() may replace a 'call' with a 'calls' or a + 'bal', in which cases it modifies *fixP as appropriate. + In the case of a 'calls', no further work is required. */ +extern int reloc_callj PARAMS ((struct fix *)); + +#define TC_FORCE_RELOCATION_ABS(FIX) \ + (TC_FORCE_RELOCATION (FIX) \ + || reloc_callj (FIX)) + +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || TC_FORCE_RELOCATION (FIX) \ + || reloc_callj (FIX)) + #ifdef OBJ_COFF /* We store the bal information in the sy_tc field. */ #define TC_SYMFIELD_TYPE symbolS * -#define TC_ADJUST_RELOC_COUNT(FIXP,COUNT) \ - { fixS *tcfixp = (FIXP); \ +#define TC_ADJUST_RELOC_COUNT(FIX,COUNT) \ + { fixS *tcfixp = (FIX); \ for (;tcfixp;tcfixp=tcfixp->fx_next) \ if (tcfixp->fx_tcbit && tcfixp->fx_addsy != 0) \ ++(COUNT); \ } #endif -extern int i960_validate_fix PARAMS ((struct fix *, segT, symbolS **)); -#define TC_VALIDATE_FIX(FIXP,SEGTYPE,LABEL) \ - if (i960_validate_fix (FIXP, SEGTYPE, &add_symbolP) != 0) goto LABEL +extern int i960_validate_fix PARAMS ((struct fix *, segT)); +#define TC_VALIDATE_FIX(FIX,SEGTYPE,LABEL) \ + if (!i960_validate_fix (FIX, SEGTYPE)) goto LABEL -#ifdef OBJ_ELF -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) -#endif +#define tc_fix_adjustable(FIX) ((FIX)->fx_bsr == 0) #ifndef OBJ_ELF -#define tc_fix_adjustable(FIXP) ((FIXP)->fx_bsr == 0) -/* This arranges for gas/write.c to not apply a relocation if - tc_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) tc_fix_adjustable (fixP) +/* Values passed to md_apply_fix3 sometimes include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) tc_fix_adjustable (FIX) #else -#define tc_fix_adjustable(FIXP) \ - ((FIXP)->fx_bsr == 0 \ - && ! S_IS_EXTERNAL ((FIXP)->fx_addsy) \ - && ! S_IS_WEAK ((FIXP)->fx_addsy)) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #endif extern void brtab_emit PARAMS ((void)); #define md_end() brtab_emit () -extern void reloc_callj (); - extern void tc_set_bal_of_call PARAMS ((symbolS *, symbolS *)); extern struct symbol *tc_get_bal_of_call PARAMS ((symbolS *)); -extern void i960_handle_align (); +extern void i960_handle_align PARAMS ((struct frag *)); #define HANDLE_ALIGN(FRAG) i960_handle_align (FRAG) #define NEED_FX_R_TYPE #define NO_RELOC -1 diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index a634d809552..cac7d0a493f 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -9985,9 +9985,10 @@ ia64_force_relocation (fix) return 1; default: - return 0; + break; } - return 0; + + return S_FORCE_RELOC (fix->fx_addsy); } /* Decide from what point a pc-relative relocation is relative to, diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h index 2da3285243c..b066807bc3f 100644 --- a/gas/config/tc-ia64.h +++ b/gas/config/tc-ia64.h @@ -101,6 +101,7 @@ extern void ia64_after_parse_args PARAMS ((void)); #define md_cons_align(n) ia64_cons_align (n) #define TC_FORCE_RELOCATION(f) ia64_force_relocation (f) #define tc_fix_adjustable(f) ia64_fix_adjustable (f) +#define MD_APPLY_SYM_VALUE(FIX) 0 #define md_convert_frag(b,s,f) as_fatal ("ia64_convert_frag") #define md_create_long_jump(p,f,t,fr,s) as_fatal ("ia64_create_long_jump") #define md_create_short_jump(p,f,t,fr,s) \ @@ -249,18 +250,16 @@ typedef struct unwind_record } record; } unwind_record; -/* This expression evaluates to false if the relocation is for a local +/* This expression evaluates to true if the relocation is for a local object for which we still want to do the relocation at runtime. - True if we are willing to perform this relocation while building - the .o file. This is only used for pcrel relocations. */ + False if we are willing to perform this relocation while building + the .o file. */ /* If the reloc type is BFD_RELOC_UNUSED, then this is for a TAG13/TAG13b field which has no external reloc, so we must resolve the value now. */ -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (FIX)->fx_r_type == BFD_RELOC_UNUSED \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + ((FIX)->fx_r_type != BFD_RELOC_UNUSED \ + && (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || TC_FORCE_RELOCATION (FIX))) diff --git a/gas/config/tc-ip2k.c b/gas/config/tc-ip2k.c index b9d63e4ffcd..615fce608d5 100644 --- a/gas/config/tc-ip2k.c +++ b/gas/config/tc-ip2k.c @@ -403,18 +403,20 @@ ip2k_force_relocation (fix) return 1; case BFD_RELOC_16: - if (fix->fx_subsy && S_IS_DEFINED (fix->fx_subsy) + if (fix->fx_subsy && S_IS_DEFINED (fix->fx_subsy) && fix->fx_addsy && S_IS_DEFINED (fix->fx_addsy) && (S_GET_SEGMENT (fix->fx_addsy)->flags & SEC_CODE)) { fix->fx_r_type = BFD_RELOC_IP2K_TEXT; return 0; } - return 0; + break; default: - return 0; + break; } + + return S_FORCE_RELOC (fix->fx_addsy); } void diff --git a/gas/config/tc-ip2k.h b/gas/config/tc-ip2k.h index 1c54f58c61f..3ce0f5b031d 100644 --- a/gas/config/tc-ip2k.h +++ b/gas/config/tc-ip2k.h @@ -47,19 +47,24 @@ #define LITERAL_PREFIXPERCENT_BIN #define DOUBLESLASH_LINE_COMMENTS -#define MD_APPLY_FIX3 -#define md_apply_fix3 ip2k_apply_fix3 +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 -#define md_elf_section_flags ip2k_elf_section_flags -extern int ip2k_elf_section_flags PARAMS ((int, int, int)); +#define md_apply_fix3 ip2k_apply_fix3 #define TC_HANDLES_FX_DONE +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +#define TC_FORCE_RELOCATION(FIX) ip2k_force_relocation (FIX) +extern int ip2k_force_relocation PARAMS ((struct fix *)); + #define tc_gen_reloc gas_cgen_tc_gen_reloc +#define md_elf_section_flags ip2k_elf_section_flags +extern int ip2k_elf_section_flags PARAMS ((int, int, int)); + #define md_operand(x) gas_cgen_md_operand (x) extern void gas_cgen_md_operand PARAMS ((expressionS *)); - -#define TC_FORCE_RELOCATION(fixp) ip2k_force_relocation (fixp) -extern int ip2k_force_relocation PARAMS ((struct fix *)); - diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c index 7a810d44384..6772b6e283d 100644 --- a/gas/config/tc-m32r.c +++ b/gas/config/tc-m32r.c @@ -1,5 +1,5 @@ /* tc-m32r.c -- Assembler for the Mitsubishi M32R. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1800,7 +1800,8 @@ m32r_force_relocation (fix) fixS *fix; { if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY + || S_FORCE_RELOC (fix->fx_addsy)) return 1; if (! m32r_relax) @@ -1912,7 +1913,6 @@ boolean m32r_fix_adjustable (fixP) fixS *fixP; { - bfd_reloc_code_real_type reloc_type; if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) @@ -1926,15 +1926,6 @@ m32r_fix_adjustable (fixP) else reloc_type = fixP->fx_r_type; - if (fixP->fx_addsy == NULL) - return 1; - - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - /* We need the symbol name for the VTABLE entries. */ if (reloc_type == BFD_RELOC_VTABLE_INHERIT || reloc_type == BFD_RELOC_VTABLE_ENTRY) diff --git a/gas/config/tc-m32r.h b/gas/config/tc-m32r.h index 34fda5776e2..d046b3e0e6c 100644 --- a/gas/config/tc-m32r.h +++ b/gas/config/tc-m32r.h @@ -1,5 +1,5 @@ /* tc-m32r.h -- Header file for tc-m32r.c. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -37,7 +37,7 @@ /* call md_pcrel_from_section, not md_pcrel_from */ long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -68,9 +68,12 @@ extern void m32r_handle_align PARAMS ((fragS *)); #define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2 + 4) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define md_apply_fix3 gas_cgen_md_apply_fix3 -#define obj_fix_adjustable(fixP) m32r_fix_adjustable(fixP) +#define tc_fix_adjustable(FIX) m32r_fix_adjustable (FIX) /* After creating a fixup for an instruction operand, we need to check for HI16 relocs and queue them up for later sorting. */ @@ -78,9 +81,13 @@ extern void m32r_handle_align PARAMS ((fragS *)); #define tc_gen_reloc gas_cgen_tc_gen_reloc -#define tc_frob_file() m32r_frob_file () +#define tc_frob_file_before_fix() m32r_frob_file () extern void m32r_frob_file PARAMS ((void)); +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ #define TC_FORCE_RELOCATION(fix) m32r_force_relocation (fix) extern int m32r_force_relocation (); diff --git a/gas/config/tc-m68hc11.c b/gas/config/tc-m68hc11.c index b7b2116c742..254bf1eac0f 100644 --- a/gas/config/tc-m68hc11.c +++ b/gas/config/tc-m68hc11.c @@ -2691,14 +2691,12 @@ tc_gen_reloc (section, fixp) return NULL; } - if (!fixp->fx_pcrel) - reloc->addend = fixp->fx_addnumber; - else - reloc->addend = (section->vma - /*+ (fixp->fx_pcrel_adjust == 64 - ? -1 : fixp->fx_pcrel_adjust)*/ - + fixp->fx_addnumber - + md_pcrel_from (fixp)); + /* Since we use Rel instead of Rela, encode the vtable entry to be + used in the relocation's section offset. */ + if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->address = fixp->fx_offset; + + reloc->addend = 0; return reloc; } @@ -3004,8 +3002,10 @@ tc_m68hc11_force_relocation (fixP) return 1; default: - return 0; + break; } + + return S_FORCE_RELOC (fixP->fx_addsy); } /* Here we decide which fixups can be adjusted to make them relative @@ -3017,10 +3017,6 @@ int tc_m68hc11_fix_adjustable (fixP) fixS *fixP; { - /* Prevent all adjustments to global symbols. */ - if (! relaxable_symbol (fixP->fx_addsy)) - return 0; - switch (fixP->fx_r_type) { /* For the linker relaxation to work correctly, these relocs @@ -3052,23 +3048,9 @@ md_apply_fix3 (fixP, valP, seg) if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; - else if (fixP->fx_pcrel) - ; - - else - { - value = fixP->fx_offset; - - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("Expression too complex.")); - } - } + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex.")); op_type = fixP->fx_r_type; @@ -3153,10 +3135,6 @@ md_apply_fix3 (fixP, valP, seg) as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line, fixP->fx_r_type); } - - /* Are we finished with this relocation now? */ - if (fixP->fx_addsy == 0 && !fixP->fx_pcrel) - fixP->fx_done = 1; } /* Set the ELF specific flags. */ diff --git a/gas/config/tc-m68hc11.h b/gas/config/tc-m68hc11.h index e17df1ebaf8..c57637f96e5 100644 --- a/gas/config/tc-m68hc11.h +++ b/gas/config/tc-m68hc11.h @@ -75,10 +75,6 @@ extern const char *m68hc11_listing_header PARAMS ((void)); /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 -#define TC_HANDLES_FX_DONE - -#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ - #define tc_init_after_args m68hc11_init_after_args extern void m68hc11_init_after_args PARAMS ((void)); @@ -97,6 +93,17 @@ extern int m68hc11_parse_long_option PARAMS ((char *)); #define TC_GENERIC_RELAX_TABLE md_relax_table extern struct relax_type md_relax_table[]; +#define TC_HANDLES_FX_DONE + +#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */ + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + #define TC_FORCE_RELOCATION(fix) tc_m68hc11_force_relocation (fix) extern int tc_m68hc11_force_relocation PARAMS ((struct fix *)); diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 6945809c699..d381ee38bc2 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -844,10 +844,6 @@ int tc_m68k_fix_adjustable (fixP) fixS *fixP; { - /* Prevent all adjustments to global symbols. */ - if (! relaxable_symbol (fixP->fx_addsy)) - return 0; - /* adjust_reloc_syms doesn't know about the GOT */ switch (fixP->fx_r_type) { diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h index fb33db4ed52..428d1f7631c 100644 --- a/gas/config/tc-m68k.h +++ b/gas/config/tc-m68k.h @@ -1,6 +1,6 @@ /* This file is tc-m68k.h Copyright 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 + 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -71,7 +71,7 @@ struct fix; #define COFF_FLAGS F_AR32W #define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy) -#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP) +#define TC_COFF_FIX2RTYPE(FIX) tc_coff_fix2rtype(FIX) #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag) extern int tc_coff_sizemachdep PARAMS ((struct frag *)); #ifdef TE_SUN3 @@ -166,36 +166,23 @@ while (0) #define RELAX_RELOC_PC32 BFD_RELOC_32_PCREL #ifdef OBJ_ELF - -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we - are willing to perform this relocation while building the .o file. If - the reloc is against an externally visible symbol, then the assembler - should never do the relocation. */ - -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) - #define tc_fix_adjustable(X) tc_m68k_fix_adjustable(X) extern int tc_m68k_fix_adjustable PARAMS ((struct fix *)); -#ifdef OBJ_ELF -/* This arranges for gas/write.c to not apply a relocation if - tc_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) tc_fix_adjustable (fixP) -#endif +/* Target *-*-elf implies an embedded target. No shared libs. */ +#define EXTERN_FORCE_RELOC (strcmp (TARGET_OS, "elf") != 0) + +/* Values passed to md_apply_fix3 don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #define elf_tc_final_processing m68k_elf_final_processing extern void m68k_elf_final_processing PARAMS ((void)); #endif #define TC_FORCE_RELOCATION(FIX) \ - ((FIX)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ - || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + ((FIX)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ + || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY \ + || S_FORCE_RELOC ((FIX)->fx_addsy)) #else /* ! BFD_ASSEMBLER */ diff --git a/gas/config/tc-mcore.c b/gas/config/tc-mcore.c index a1e10575aad..538d75b0d50 100644 --- a/gas/config/tc-mcore.c +++ b/gas/config/tc-mcore.c @@ -2099,19 +2099,14 @@ md_apply_fix3 (fixP, valP, segment) char * file = fixP->fx_file ? fixP->fx_file : _("unknown"); const char * symname; /* Note: use offsetT because it is signed, valueT is unsigned. */ - offsetT val = * (offsetT *) valP; + offsetT val = *valP; symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _(""); /* Save this for the addend in the relocation record. */ fixP->fx_addnumber = val; - /* If the fix is relative to a symbol which is not defined, or not - in the same segment as the fix, we cannot resolve it here. */ - if (fixP->fx_addsy != NULL - && ( ! S_IS_DEFINED (fixP->fx_addsy) - || (S_GET_SEGMENT (fixP->fx_addsy) != segment))) + if (fixP->fx_addsy != NULL) { - fixP->fx_done = 0; #ifdef OBJ_ELF /* For ELF we can just return and let the reloc that will be generated take care of everything. For COFF we still have to insert 'val' @@ -2434,7 +2429,7 @@ mcore_force_relocation (fix) || fix->fx_r_type == BFD_RELOC_RVA) return 1; - return 0; + return S_FORCE_RELOC (fix->fx_addsy); } /* Return true if the fix can be handled by GAS, false if it must @@ -2443,9 +2438,6 @@ boolean mcore_fix_adjustable (fixP) fixS * fixP; { - if (fixP->fx_addsy == NULL) - return 1; - /* We need the symbol name for the VTABLE entries. */ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) diff --git a/gas/config/tc-mcore.h b/gas/config/tc-mcore.h index c8787ddb794..b41c2a66ee4 100644 --- a/gas/config/tc-mcore.h +++ b/gas/config/tc-mcore.h @@ -1,6 +1,6 @@ /* This file is tc-mcore.h - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -57,7 +57,7 @@ extern const struct relax_type md_relax_table[]; #define md_end md_mcore_end /* Want the section information too... */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) #ifdef OBJ_COFF @@ -71,7 +71,8 @@ struct mcore_tc_sy #define TC_SYMFIELD_TYPE struct mcore_tc_sy # if defined TE_PE -# define TC_FORCE_RELOCATION(x) ((x)->fx_r_type == BFD_RELOC_RVA) +# define TC_FORCE_RELOCATION(x) \ + ((x)->fx_r_type == BFD_RELOC_RVA || S_FORCE_RELOC ((x)->fx_addsy)) # endif #endif /* OBJ_COFF */ @@ -86,13 +87,20 @@ struct mcore_tc_sy /* Other special sections not generated by the assembler: .reginfo, .liblist, .conflict, .gptab, .got, .dynamic, .rel.dyn. */ +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ #define TC_FORCE_RELOCATION(fix) mcore_force_relocation (fix) extern int mcore_force_relocation PARAMS ((struct fix *)); -#define obj_fix_adjustable(fixP) mcore_fix_adjustable (fixP) +#define tc_fix_adjustable(FIX) mcore_fix_adjustable (FIX) extern boolean mcore_fix_adjustable PARAMS ((struct fix *)); +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #endif /* OBJ_ELF */ #ifndef TARGET_FORMAT diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 4b785628588..638d1df9a8e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -322,22 +322,7 @@ static int mips_32bitmode = 0; /* MIPS PIC level. */ -enum mips_pic_level -{ - /* Do not generate PIC code. */ - NO_PIC, - - /* Generate PIC code as in the SVR4 MIPS ABI. */ - SVR4_PIC, - - /* Generate PIC code without using a global offset table: the data - segment has a maximum size of 64K, all data references are off - the $gp register, and all text references are PC relative. This - is used on some embedded systems. */ - EMBEDDED_PIC -}; - -static enum mips_pic_level mips_pic; +enum mips_pic_level mips_pic; /* Warn about all NOPS that the assembler generates. */ static int warn_nops = 0; @@ -10601,7 +10586,8 @@ mips_force_relocation (fixp) fixS *fixp; { if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY + || S_FORCE_RELOC (fixp->fx_addsy)) return 1; if (HAVE_NEWABI @@ -12549,26 +12535,23 @@ int mips_fix_adjustable (fixp) fixS *fixp; { -#ifdef OBJ_ELF - /* Prevent all adjustments to global symbols. */ - if (OUTPUT_FLAVOR == bfd_target_elf_flavour - && mips_pic != EMBEDDED_PIC - && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))) - return 0; -#endif if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP) return 0; + if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; + if (fixp->fx_addsy == NULL) return 1; + #ifdef OBJ_ELF if (OUTPUT_FLAVOR == bfd_target_elf_flavour && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16 && fixp->fx_subsy == NULL) return 0; #endif + return 1; } diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h index d0acd8c9b4d..6b2c3dc06f4 100644 --- a/gas/config/tc-mips.h +++ b/gas/config/tc-mips.h @@ -1,5 +1,5 @@ /* tc-mips.h -- header file for tc-mips.c. - Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001 + Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by the OSF and Ralph Campbell. Written by Keith Knowles and Ralph Campbell, working independently. @@ -72,6 +72,25 @@ extern void mips_handle_align PARAMS ((struct frag *)); #define TARGET_FORMAT mips_target_format() extern const char *mips_target_format PARAMS ((void)); +/* MIPS PIC level. */ + +enum mips_pic_level +{ + /* Do not generate PIC code. */ + NO_PIC, + + /* Generate PIC code as in the SVR4 MIPS ABI. */ + SVR4_PIC, + + /* Generate PIC code without using a global offset table: the data + segment has a maximum size of 64K, all data references are off + the $gp register, and all text references are PC relative. This + is used on some embedded systems. */ + EMBEDDED_PIC +}; + +extern enum mips_pic_level mips_pic; + struct mips_cl_insn { unsigned long insn_opcode; @@ -98,7 +117,7 @@ extern void mips_define_label PARAMS ((symbolS *)); #define tc_frob_file_before_adjust() mips_frob_file_before_adjust () extern void mips_frob_file_before_adjust PARAMS ((void)); -#define tc_frob_file() mips_frob_file () +#define tc_frob_file_before_fix() mips_frob_file () extern void mips_frob_file PARAMS ((void)); #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) @@ -109,6 +128,12 @@ extern void mips_frob_file_after_relocs PARAMS ((void)); #define tc_fix_adjustable(fixp) mips_fix_adjustable (fixp) extern int mips_fix_adjustable PARAMS ((struct fix *)); +/* Global syms must not be resolved, to support ELF shared libraries. + When generating embedded code, we don't have shared libs. */ +#define EXTERN_FORCE_RELOC \ + (OUTPUT_FLAVOR == bfd_target_elf_flavour \ + && mips_pic != EMBEDDED_PIC) + /* When generating embedded PIC code we must keep PC relative relocations. */ #define TC_FORCE_RELOCATION(fixp) mips_force_relocation (fixp) diff --git a/gas/config/tc-mmix.c b/gas/config/tc-mmix.c index 74668b44a9a..15dd5f292d6 100644 --- a/gas/config/tc-mmix.c +++ b/gas/config/tc-mmix.c @@ -2410,8 +2410,7 @@ md_apply_fix3 (fixP, valP, segment) && symsec != absolute_section && ((fixP->fx_r_type != BFD_RELOC_MMIX_REG && fixP->fx_r_type != BFD_RELOC_MMIX_REG_OR_BYTE) - || (symsec != reg_section - && symsec != real_reg_section))))) + || symsec != reg_section)))) { fixP->fx_done = 0; return; @@ -2495,11 +2494,17 @@ md_apply_fix3 (fixP, valP, segment) case BFD_RELOC_MMIX_REG_OR_BYTE: if (fixP->fx_addsy != NULL - && (S_GET_SEGMENT (fixP->fx_addsy) != real_reg_section + && (S_GET_SEGMENT (fixP->fx_addsy) != reg_section || S_GET_VALUE (fixP->fx_addsy) > 255) && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("invalid operands")); + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("invalid operands")); + /* We don't want this "symbol" appearing in output, because + that will fail. */ + fixP->fx_done = 1; + } + buf[0] = val; /* If this reloc is for a Z field, we need to adjust @@ -2510,25 +2515,19 @@ md_apply_fix3 (fixP, valP, segment) && (fixP->fx_addsy == NULL || S_GET_SEGMENT (fixP->fx_addsy) == absolute_section)) buf[-3] |= IMM_OFFSET_BIT; - - /* We don't want this "symbol" appearing in output, because that - will fail. */ - if (fixP->fx_addsy - && S_GET_SEGMENT (fixP->fx_addsy) == real_reg_section) - symbol_clear_used_in_reloc (fixP->fx_addsy); break; case BFD_RELOC_MMIX_REG: if (fixP->fx_addsy == NULL - || S_GET_SEGMENT (fixP->fx_addsy) != real_reg_section + || S_GET_SEGMENT (fixP->fx_addsy) != reg_section || S_GET_VALUE (fixP->fx_addsy) > 255) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("invalid operands")); - *buf = val; + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("invalid operands")); + fixP->fx_done = 1; + } - if (fixP->fx_addsy - && S_GET_SEGMENT (fixP->fx_addsy) == real_reg_section) - symbol_clear_used_in_reloc (fixP->fx_addsy); + *buf = val; break; case BFD_RELOC_MMIX_BASE_PLUS_OFFSET: @@ -2843,8 +2842,7 @@ tc_gen_reloc (section, fixP) /* Unmark this symbol as used in a reloc, so we don't bump into a BFD assert when trying to output reg_section. FIXME: A gas bug. */ - if (addsy) - symbol_clear_used_in_reloc (addsy); + fixP->fx_addsy = NULL; return NULL; } @@ -3249,11 +3247,6 @@ mmix_force_relocation (fixP) || fixP->fx_r_type == BFD_RELOC_MMIX_BASE_PLUS_OFFSET) return 1; - /* FIXME: This is dubious. Handling of weak symbols should have been - caught before we get here. */ - if ((fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy))) - return 1; - if (linkrelax) return 1; @@ -3264,7 +3257,7 @@ mmix_force_relocation (fixP) if (fixP->fx_pcrel) return 1; - return 0; + return S_FORCE_RELOC (fixP->fx_addsy); } /* The location from which a PC relative jump should be calculated, @@ -3288,47 +3281,29 @@ md_pcrel_from_section (fixP, sec) } /* Adjust the symbol table. We make reg_section relative to the real - register section. - - FIXME: There's a gas bug; should be fixed when the reg_section symbol - is "accidentally" saved for relocs which are really fixups that will be - fixed up. */ + register section. */ void mmix_adjust_symtab () { symbolS *sym; - symbolS *prevsym; symbolS *regsec = section_symbol (reg_section); - segT realregsec = NULL; - for (prevsym = sym = symbol_rootP; - sym != NULL; - prevsym = sym, sym = symbol_next (sym)) + for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym)) if (S_GET_SEGMENT (sym) == reg_section) { - if (sym == regsec - || (!S_IS_EXTERN (sym) && !symbol_used_in_reloc_p (sym))) + if (sym == regsec) { + if (S_IS_EXTERN (sym) || symbol_used_in_reloc_p (sym)) + abort (); symbol_remove (sym, &symbol_rootP, &symbol_lastP); - - /* We make one extra turn, or we'll lose the next symbol. We - assume that the symbol we remove is not the symbol root - (.text normally is). */ - sym = prevsym; } else - { - /* Change section to the *real* register section, so it gets - proper treatment when writing it out. Only do this for - global symbols. This also means we don't have to check for - $0..$255. */ - if (realregsec == NULL) - realregsec - = bfd_make_section_old_way (stdoutput, MMIX_REG_SECTION_NAME); - - S_SET_SEGMENT (sym, realregsec); - } + /* Change section to the *real* register section, so it gets + proper treatment when writing it out. Only do this for + global symbols. This also means we don't have to check for + $0..$255. */ + S_SET_SEGMENT (sym, real_reg_section); } } diff --git a/gas/config/tc-mmix.h b/gas/config/tc-mmix.h index 0ce112e9cf0..cd54e0d7295 100644 --- a/gas/config/tc-mmix.h +++ b/gas/config/tc-mmix.h @@ -127,51 +127,53 @@ extern const struct relax_type mmix_relax_table[]; extern long mmix_md_relax_frag PARAMS ((segT, fragS *, long)); #define md_relax_frag mmix_md_relax_frag -#define tc_fix_adjustable(X) \ - ((! (X)->fx_addsy \ - || (! S_IS_WEAK ((X)->fx_addsy) \ - && S_GET_SEGMENT ((X)->fx_addsy) != reg_section)) \ - && (X)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ - && (X)->fx_r_type != BFD_RELOC_VTABLE_ENTRY) +#define tc_fix_adjustable(FIX) \ + (((FIX)->fx_addsy == NULL \ + || S_GET_SEGMENT ((FIX)->fx_addsy) != reg_section) \ + && (FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ + && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \ + && (FIX)->fx_r_type != BFD_RELOC_MMIX_LOCAL) /* Adjust symbols which are registers. */ #define tc_adjust_symtab() mmix_adjust_symtab () extern void mmix_adjust_symtab PARAMS ((void)); -/* Avoid outputting GAS register section symbols. This happens when the - assembly had errors, and will propagate to an assert in BFD. FIXME: - It seems the symbol output when-errors is a bug in GAS. Fix that - some time. See also tc_gen_reloc. - - Here's where we make all symbols global, when so requested. +/* Here's where we make all symbols global, when so requested. We must avoid doing that for expression symbols or section symbols, though. */ extern int mmix_globalize_symbols; #define tc_frob_symbol(sym, punt) \ do \ { \ - if (S_GET_SEGMENT (sym) == reg_section \ - || (symp) == section_symbol (absolute_section)) \ - (punt) = 1; \ - \ - if (mmix_globalize_symbols \ - && ! symbol_section_p (sym) \ - && symp != section_symbol (absolute_section) \ - && (! S_IS_LOCAL (sym) \ - || S_GET_SEGMENT (sym) == reg_section) \ - && (S_GET_SEGMENT (sym) != reg_section \ - || (S_GET_NAME (sym)[0] != '$' \ - && S_GET_VALUE (sym) < 256))) \ + if (S_GET_SEGMENT (sym) == reg_section) \ + { \ + if (S_GET_NAME (sym)[0] != '$' \ + && S_GET_VALUE (sym) < 256) \ + { \ + if (mmix_globalize_symbols) \ + S_SET_EXTERNAL (sym); \ + else \ + symbol_mark_used_in_reloc (sym); \ + } \ + } \ + else if (mmix_globalize_symbols \ + && ! symbol_section_p (sym) \ + && sym != section_symbol (absolute_section) \ + && ! S_IS_LOCAL (sym)) \ S_SET_EXTERNAL (sym); \ } \ while (0) +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ #define TC_FORCE_RELOCATION(fix) mmix_force_relocation (fix) extern int mmix_force_relocation PARAMS ((struct fix *)); /* Call md_pcrel_from_section(), not md_pcrel_from(). */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define md_section_align(seg, size) (size) @@ -191,7 +193,7 @@ extern fragS *mmix_opcode_frag; fixups are done and relocs are output. Similarly for each unknown symbol. */ extern void mmix_frob_file PARAMS ((void)); -#define tc_frob_file mmix_frob_file +#define tc_frob_file_before_fix mmix_frob_file /* Used by mmix_frob_file. Hangs on section symbols and unknown symbols. */ struct mmix_symbol_gregs; diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 4611b86854e..012932b41ff 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -2002,16 +2002,7 @@ mn10300_force_relocation (fixp) || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - /* Do not adjust relocations involving symbols in code sections, - because it breaks linker relaxations. This could be fixed in the - linker, but this fix is simpler, and it pretty much only affects - object size a little bit. */ - if ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) - && fixp->fx_subsy - && S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)) - return 1; - - return 0; + return S_FORCE_RELOC (fixp->fx_addsy); } /* Return zero if the fixup in fixp should be left alone and not @@ -2021,10 +2012,6 @@ boolean mn10300_fix_adjustable (fixp) struct fix *fixp; { - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)) - return 0; - if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; diff --git a/gas/config/tc-mn10300.h b/gas/config/tc-mn10300.h index c09ddad6723..21611961c53 100644 --- a/gas/config/tc-mn10300.h +++ b/gas/config/tc-mn10300.h @@ -1,5 +1,5 @@ /* tc-mn10300.h -- Header file for tc-mn10300.c. - Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + Copyright 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -31,12 +31,21 @@ #define TARGET_FORMAT "elf32-mn10300" +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* For fixup and relocation handling. */ #define TC_FORCE_RELOCATION(fixp) mn10300_force_relocation (fixp) extern int mn10300_force_relocation PARAMS ((struct fix *)); -#define obj_fix_adjustable(fixP) mn10300_fix_adjustable (fixP) -extern boolean mn10300_fix_adjustable PARAMS ((struct fix *)); +/* Do not adjust relocations involving symbols in code sections, + because it breaks linker relaxations. This could be fixed in the + linker, but this fix is simpler, and it pretty much only affects + object size a little bit. */ +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (! SEG_NORMAL (SEG) \ + || ((SEG)->flags & SEC_CODE) != 0) /* Fixup debug sections since we will never relax them. */ #define TC_LINKRELAX_FIXUP(seg) (seg->flags & SEC_ALLOC) @@ -53,6 +62,8 @@ extern boolean mn10300_fix_adjustable PARAMS ((struct fix *)); /* Don't bother to adjust relocs. */ #define tc_fix_adjustable(FIX) 0 +/* #define tc_fix_adjustable(FIX) mn10300_fix_adjustable (FIX) */ +extern boolean mn10300_fix_adjustable PARAMS ((struct fix *)); /* We do relaxing in the assembler as well as the linker. */ extern const struct relax_type md_relax_table[]; diff --git a/gas/config/tc-ns32k.h b/gas/config/tc-ns32k.h index 417395df9e8..e547bf59a9a 100644 --- a/gas/config/tc-ns32k.h +++ b/gas/config/tc-ns32k.h @@ -128,12 +128,12 @@ extern const struct relax_type md_relax_table[]; } \ while (0) -#define TC_FIX_DATA_PRINT(FILE, FIXP) \ +#define TC_FIX_DATA_PRINT(FILE, FIX) \ do \ { \ fprintf ((FILE), "opcode_frag=%ld, operand offset=%d, bsr=%d\n", \ - (unsigned long) fix_opcode_frag (FIXP), \ - fix_opcode_offset (FIXP), \ - fix_bsr (FIXP)); \ + (unsigned long) fix_opcode_frag (FIX), \ + fix_opcode_offset (FIX), \ + fix_bsr (FIX)); \ } \ while (0) diff --git a/gas/config/tc-openrisc.c b/gas/config/tc-openrisc.c index d992ff7cf98..2a7869ab33e 100644 --- a/gas/config/tc-openrisc.c +++ b/gas/config/tc-openrisc.c @@ -409,7 +409,7 @@ openrisc_force_relocation (fix) || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - return 0; + return S_FORCE_RELOC (fix->fx_addsy); } @@ -487,9 +487,6 @@ boolean openrisc_fix_adjustable (fixP) fixS * fixP; { - if (fixP->fx_addsy == NULL) - return 1; - /* We need the symbol name for the VTABLE entries */ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) diff --git a/gas/config/tc-openrisc.h b/gas/config/tc-openrisc.h index 365aa7ffff2..cf38d50b3c4 100644 --- a/gas/config/tc-openrisc.h +++ b/gas/config/tc-openrisc.h @@ -1,5 +1,5 @@ /* tc-openrisc.h -- Header file for tc-openrisc.c. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -39,10 +39,6 @@ extern unsigned long openrisc_machine; extern const char openrisc_comment_chars []; #define tc_comment_chars openrisc_comment_chars -/* Call md_pcrel_from_section, not md_pcrel_from. */ -extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) - /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -51,10 +47,13 @@ extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* We don't need to handle .word strangely. */ #define WORKING_DOT_WORD +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define md_apply_fix3 gas_cgen_md_apply_fix3 extern boolean openrisc_fix_adjustable PARAMS ((struct fix *)); -#define obj_fix_adjustable(fixP) openrisc_fix_adjustable (fixP) +#define tc_fix_adjustable(FIX) openrisc_fix_adjustable (FIX) /* When relaxing, we need to emit various relocs we otherwise wouldn't. */ extern int openrisc_force_relocation PARAMS ((struct fix *)); @@ -64,7 +63,7 @@ extern int openrisc_force_relocation PARAMS ((struct fix *)); /* Call md_pcrel_from_section(), not md_pcrel_from(). */ extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) /* For 8 vs 16 vs 32 bit branch selection. */ extern const struct relax_type md_relax_table[]; diff --git a/gas/config/tc-or32.c b/gas/config/tc-or32.c index 44cbfc8bc9f..2983b7a215d 100644 --- a/gas/config/tc-or32.c +++ b/gas/config/tc-or32.c @@ -1057,7 +1057,7 @@ md_apply_fix3 (fixP, valP, seg) valueT *valP; segT seg ATTRIBUTE_UNUSED; { - long val = *(long*)valP; + long val = *valP; char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; #if DEBUG @@ -1624,12 +1624,10 @@ tc_gen_reloc (seg, fixp) return NULL; } - if ( fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY - || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT) - reloc->addend = fixp->fx_offset; - else - reloc->addend = fixp->fx_addnumber; + if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + reloc->address = fixp->fx_offset; + reloc->addend = fixp->fx_addnumber; return reloc; } #endif diff --git a/gas/config/tc-or32.h b/gas/config/tc-or32.h index b78cf93848b..cfed1cb5fb5 100644 --- a/gas/config/tc-or32.h +++ b/gas/config/tc-or32.h @@ -50,6 +50,15 @@ extern int or32_unrecognized_line PARAMS ((int)); #define BFD_ARCH bfd_arch_or32 #define COFF_MAGIC SIPFBOMAGIC +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + +#ifdef OBJ_ELF +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 +#endif + /* Should the reloc be output ? on the 29k, this is true only if there is a symbol attatched. on the h8, this is allways true, since no fixup is done. */ @@ -60,4 +69,3 @@ extern int or32_unrecognized_line PARAMS ((int)); #define NEED_FX_R_TYPE #define ZERO_BASED_SEGMENTS - diff --git a/gas/config/tc-pj.c b/gas/config/tc-pj.c index e9521463fe7..a16971d1408 100644 --- a/gas/config/tc-pj.c +++ b/gas/config/tc-pj.c @@ -434,18 +434,10 @@ md_apply_fix3 (fixP, valP, seg) segT seg ATTRIBUTE_UNUSED; { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - long val = * (long *) valP; + long val = *valP; long max, min; int shift; - /* adjust_reloc_syms won't convert a reloc against a weak symbol - into a reloc against a section, but bfd_install_relocation will - screw up if the symbol is defined, so we have to adjust val here - to avoid the screw up later. */ - - if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy)) - val -= S_GET_VALUE (fixP->fx_addsy); - max = min = 0; shift = 0; switch (fixP->fx_r_type) diff --git a/gas/config/tc-pj.h b/gas/config/tc-pj.h index 52d33d2c627..4e6c92d889d 100644 --- a/gas/config/tc-pj.h +++ b/gas/config/tc-pj.h @@ -1,5 +1,5 @@ /* This file is tc-pj.h - Copyright 1999, 2000 Free Software Foundation, Inc. + Copyright 1999, 2000, 2002 Free Software Foundation, Inc. Contributed by Steve Chamberlain of Transmeta, sac@pobox.com @@ -32,7 +32,7 @@ : "Pico Java GAS Little Endian") void pj_cons_fix_new_pj PARAMS ((struct frag *, int, int, expressionS *)); -arelent *tc_gen_reloc PARAMS((asection *section, struct fix *fixp)); +arelent *tc_gen_reloc PARAMS((asection *, struct fix *)); #define md_section_align(SEGMENT, SIZE) (SIZE) #define md_convert_frag(B, S, F) (as_fatal (_("convert_frag\n")), 0) @@ -42,17 +42,25 @@ arelent *tc_gen_reloc PARAMS((asection *section, struct fix *fixp)); /* PC relative operands are relative to the start of the opcode, and the operand is always one byte into the opcode. */ -#define md_pcrel_from(FIXP) \ - ((FIXP)->fx_where + (FIXP)->fx_frag->fr_address - 1) +#define md_pcrel_from(FIX) \ + ((FIX)->fx_where + (FIX)->fx_frag->fr_address - 1) #define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP) +/* No shared lib support, so we don't need to ensure externally + visible symbols can be overridden. */ +#define EXTERN_FORCE_RELOC 0 + /* Always leave vtable relocs untouched in the output. */ #define TC_FORCE_RELOCATION(FIX) \ ((FIX)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ - || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY \ + || S_FORCE_RELOC ((FIX)->fx_addsy)) + +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 -#define obj_fix_adjustable(FIX) \ +#define tc_fix_adjustable(FIX) \ (! ((FIX)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY)) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index c15acb676a2..613a61a203c 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -4663,6 +4663,10 @@ ppc_frob_symbol (sym) && S_GET_STORAGE_CLASS (sym) != C_FILE))) return 1; + /* This one will disappear anyway. Don't make a csect sym for it. */ + if (sym == abs_section_sym) + return 1; + if (symbol_get_tc (sym)->real_name != (char *) NULL) S_SET_NAME (sym, symbol_get_tc (sym)->real_name); else @@ -5243,12 +5247,38 @@ ppc_force_relocation (fix) <= fix->fx_frag->fr_address)))) return 1; - return 0; + return S_FORCE_RELOC (fix->fx_addsy); } #endif /* OBJ_XCOFF */ #ifdef OBJ_ELF +/* If this function returns non-zero, it guarantees that a relocation + will be emitted for a fixup. */ + +int +ppc_force_relocation (fix) + fixS *fix; +{ + /* Branch prediction relocations must force a relocation, as must + the vtable description relocs. */ + switch (fix->fx_r_type) + { + case BFD_RELOC_PPC_B16_BRTAKEN: + case BFD_RELOC_PPC_B16_BRNTAKEN: + case BFD_RELOC_PPC_BA16_BRTAKEN: + case BFD_RELOC_PPC_BA16_BRNTAKEN: + case BFD_RELOC_PPC64_TOC: + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + return 1; + default: + break; + } + + return S_FORCE_RELOC (fix->fx_addsy); +} + int ppc_fix_adjustable (fix) fixS *fix; @@ -5260,8 +5290,6 @@ ppc_fix_adjustable (fix) && fix->fx_r_type != BFD_RELOC_GPREL16 && fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY - && ! S_IS_EXTERNAL (fix->fx_addsy) - && ! S_IS_WEAK (fix->fx_addsy) && (fix->fx_pcrel || (fix->fx_subsy != NULL && (S_GET_SEGMENT (fix->fx_subsy) @@ -5290,32 +5318,22 @@ md_apply_fix3 (fixP, valP, seg) #ifdef OBJ_ELF if (fixP->fx_addsy != NULL) { - /* `*valuep' may contain the value of the symbol on which the reloc - will be based; we have to remove it. */ - if (symbol_used_in_reloc_p (fixP->fx_addsy) - && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section - && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section - && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy))) - value -= S_GET_VALUE (fixP->fx_addsy); - - /* FIXME: Why '+'? Better yet, what exactly is '*valuep' - supposed to be? I think this is related to various similar - FIXMEs in tc-i386.c and tc-sparc.c. */ + /* Hack around bfd_install_relocation brain damage. */ if (fixP->fx_pcrel) value += fixP->fx_frag->fr_address + fixP->fx_where; } else fixP->fx_done = 1; #else - /* FIXME FIXME FIXME: The value we are passed in *valuep includes + /* FIXME FIXME FIXME: The value we are passed in *valP includes the symbol values. Since we are using BFD_ASSEMBLER, if we are doing this relocation the code in write.c is going to call bfd_install_relocation, which is also going to use the symbol value. That means that if the reloc is fully resolved we want to - use *valuep since bfd_install_relocation is not being used. + use *valP since bfd_install_relocation is not being used. However, if the reloc is not fully resolved we do not want to use - *valuep, and must use fx_offset instead. However, if the reloc - is PC relative, we do want to use *valuep since it includes the + *valP, and must use fx_offset instead. However, if the reloc + is PC relative, we do want to use *valP since it includes the result of md_pcrel_from. This is confusing. */ if (fixP->fx_addsy == (symbolS *) NULL) fixP->fx_done = 1; @@ -5324,21 +5342,14 @@ md_apply_fix3 (fixP, valP, seg) ; else + value = fixP->fx_offset; +#endif + + if (fixP->fx_subsy != (symbolS *) NULL) { - value = fixP->fx_offset; - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We can't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } + /* We can't actually support subtracting a symbol. */ + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); } -#endif if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) { diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 0e8ee5a6f8d..f4f8ab517d0 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -117,7 +117,7 @@ extern char *ppc_target_format PARAMS ((void)); #define LEX_QM 1 /* Don't adjust TOC relocs. */ -#define tc_fix_adjustable(fixp) ppc_pe_fix_adjustable (fixp) +#define tc_fix_adjustable(FIX) ppc_pe_fix_adjustable (FIX) extern int ppc_pe_fix_adjustable PARAMS ((struct fix *)); #endif @@ -177,13 +177,9 @@ extern void ppc_symbol_new_hook PARAMS ((symbolS *)); extern void ppc_frob_label PARAMS ((symbolS *)); /* TOC relocs requires special handling. */ -#define tc_fix_adjustable(fixp) ppc_fix_adjustable (fixp) +#define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX) extern int ppc_fix_adjustable PARAMS ((struct fix *)); -/* A relocation from one csect to another must be kept. */ -#define TC_FORCE_RELOCATION(FIXP) ppc_force_relocation (FIXP) -extern int ppc_force_relocation PARAMS ((struct fix *)); - /* We need to set the section VMA. */ #define tc_frob_section(sec) ppc_frob_section (sec) extern void ppc_frob_section PARAMS ((asection *)); @@ -212,22 +208,6 @@ do { \ #ifdef OBJ_ELF -/* Branch prediction relocations must force relocation, as must - the vtable description relocs. */ -#define TC_FORCE_RELOCATION(FIXP) \ -((FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRTAKEN \ - || (FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRNTAKEN \ - || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRTAKEN \ - || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN \ - || (FIXP)->fx_r_type == BFD_RELOC_PPC64_TOC \ - || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \ - || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - -#define TC_FORCE_RELOCATION_SECTION(FIXP,SEC) \ -(TC_FORCE_RELOCATION (FIXP) \ - || ((FIXP)->fx_addsy && !(FIXP)->fx_subsy \ - && S_GET_SEGMENT ((FIXP)->fx_addsy) != SEC)) - /* Support for SHF_EXCLUDE and SHT_ORDERED */ extern int ppc_section_letter PARAMS ((int, char **)); extern int ppc_section_type PARAMS ((char *, size_t)); @@ -259,18 +239,11 @@ extern int ppc_section_flags PARAMS ((int, int, int)); extern const char *ppc_comment_chars; /* Keep relocations relative to the GOT, or non-PC relative. */ -#define tc_fix_adjustable(fixp) ppc_fix_adjustable (fixp) +#define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX) extern int ppc_fix_adjustable PARAMS ((struct fix *)); -/* We must never ever try to resolve references to externally visible - symbols in the assembler, because the .o file might go into a shared - library, and some other shared library might override that symbol. */ -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) +/* Values passed to md_apply_fix3 don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #define tc_frob_file_before_adjust ppc_frob_file_before_adjust extern void ppc_frob_file_before_adjust PARAMS ((void)); @@ -278,8 +251,11 @@ extern void ppc_frob_file_before_adjust PARAMS ((void)); #define DWARF2_LINE_MIN_INSN_LENGTH 4 #endif /* OBJ_ELF */ +#define TC_FORCE_RELOCATION(FIX) ppc_force_relocation (FIX) +extern int ppc_force_relocation PARAMS ((struct fix *)); + /* call md_pcrel_from_section, not md_pcrel_from */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define md_parse_name(name, exp, c) ppc_parse_name (name, exp) diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c index bce0604f61a..a4b275f3e23 100644 --- a/gas/config/tc-s390.c +++ b/gas/config/tc-s390.c @@ -24,6 +24,7 @@ #include "safe-ctype.h" #include "subsegs.h" #include "struc-symbol.h" +#include "dwarf2dbg.h" #include "opcode/s390.h" #include "elf/s390.h" @@ -1374,9 +1375,9 @@ s390_insn (ignore) expression (&exp); if (exp.X_op == O_constant) { - if ( ((opformat->oplen == 6) && (exp.X_op > 0) && (exp.X_op < (1ULL << 48))) - || ((opformat->oplen == 4) && (exp.X_op > 0) && (exp.X_op < (1ULL << 32))) - || ((opformat->oplen == 2) && (exp.X_op > 0) && (exp.X_op < (1ULL << 16)))) + if ( (opformat->oplen == 6 && exp.X_op > 0 && exp.X_op < (1ULL << 48)) + || (opformat->oplen == 4 && exp.X_op > 0 && exp.X_op < (1ULL << 32)) + || (opformat->oplen == 2 && exp.X_op > 0 && exp.X_op < (1ULL << 16))) md_number_to_chars (insn, exp.X_add_number, opformat->oplen); else as_bad (_("Invalid .insn format\n")); @@ -1628,14 +1629,6 @@ int tc_s390_fix_adjustable (fixP) fixS *fixP; { - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - /* Don't adjust references to merge sections. */ - if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0) - return 0; /* adjust_reloc_syms doesn't know about the GOT. */ if ( fixP->fx_r_type == BFD_RELOC_32_GOTOFF || fixP->fx_r_type == BFD_RELOC_390_PLT16DBL @@ -1679,8 +1672,10 @@ tc_s390_force_relocation (fixp) case BFD_RELOC_VTABLE_ENTRY: return 1; default: - return 0; + break;; } + + return S_FORCE_RELOC (fixp->fx_addsy); } /* Apply a fixup to the object code. This is called for all the @@ -1696,7 +1691,7 @@ void md_apply_fix3 (fixP, valP, seg) fixS *fixP; valueT *valP; - segT seg; + segT seg ATTRIBUTE_UNUSED; { char *where; valueT value = *valP; @@ -1704,35 +1699,10 @@ md_apply_fix3 (fixP, valP, seg) where = fixP->fx_frag->fr_literal + fixP->fx_where; if (fixP->fx_subsy != NULL) - { - if ((fixP->fx_addsy != NULL - && S_GET_SEGMENT (fixP->fx_addsy) == S_GET_SEGMENT (fixP->fx_subsy) - && SEG_NORMAL (S_GET_SEGMENT (fixP->fx_addsy))) - || (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)) - value += S_GET_VALUE (fixP->fx_subsy); - if (!S_IS_DEFINED (fixP->fx_subsy)) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("unresolved fx_subsy symbol that must be resolved")); - value -= S_GET_VALUE (fixP->fx_subsy); - - if (S_GET_SEGMENT (fixP->fx_subsy) == seg && ! fixP->fx_pcrel) - value += MD_PCREL_FROM_SECTION (fixP, seg); - } + abort (); if (fixP->fx_addsy != NULL) { - if ((fixP->fx_subsy != NULL - && S_GET_SEGMENT (fixP->fx_addsy) == S_GET_SEGMENT (fixP->fx_subsy) - && SEG_NORMAL (S_GET_SEGMENT (fixP->fx_addsy))) - || (S_GET_SEGMENT (fixP->fx_addsy) == seg - && fixP->fx_pcrel && TC_RELOC_RTSYM_LOC_FIXUP (fixP)) - || (!fixP->fx_pcrel - && S_GET_SEGMENT (fixP->fx_addsy) == absolute_section) - || (S_GET_SEGMENT (fixP->fx_addsy) != undefined_section - && !bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)) - && TC_FIX_ADJUSTABLE (fixP))) - value -= S_GET_VALUE (fixP->fx_addsy); - if (fixP->fx_pcrel) value += fixP->fx_frag->fr_address + fixP->fx_where; } diff --git a/gas/config/tc-s390.h b/gas/config/tc-s390.h index 48dbeda96d3..e197029ae73 100644 --- a/gas/config/tc-s390.h +++ b/gas/config/tc-s390.h @@ -29,29 +29,14 @@ struct fix; #error S390 support requires BFD_ASSEMBLER #endif -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we - are willing to perform this relocation while building the .o file. - This is only used for pcrel relocations, so GOTOFF does not need to be - checked here. I am not sure if some of the others are ever used with - pcrel, but it is easier to be safe than sorry. */ - -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_r_type != BFD_RELOC_390_GOTENT \ - && ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy)))) - -#define TC_FORCE_RELOCATION(FIXP) tc_s390_force_relocation(FIXP) +#define TC_FORCE_RELOCATION(FIX) tc_s390_force_relocation(FIX) extern int tc_s390_force_relocation PARAMS ((struct fix *)); #define tc_fix_adjustable(X) tc_s390_fix_adjustable(X) extern int tc_s390_fix_adjustable PARAMS ((struct fix *)); -#define TC_FIX_ADJUSTABLE(fixP) \ - (! symbol_used_in_reloc_p ((fixP)->fx_addsy) && tc_fix_adjustable (fixP)) +/* Values passed to md_apply_fix3 don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 /* The target BFD architecture. */ #define TARGET_ARCH bfd_arch_s390 @@ -106,7 +91,7 @@ if (fragP->fr_type == rs_align_code) \ - fragP->fr_fix)); /* call md_pcrel_from_section, not md_pcrel_from */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define md_operand(x) diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 4ae4c036f97..b74dc56b22f 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -3211,31 +3211,6 @@ sh_handle_align (frag) BFD_RELOC_SH_ALIGN); } -/* This macro decides whether a particular reloc is an entry in a - switch table. It is used when relaxing, because the linker needs - to know about all such entries so that it can adjust them if - necessary. */ - -#ifdef BFD_ASSEMBLER -#define SWITCH_TABLE_CONS(fix) (0) -#else -#define SWITCH_TABLE_CONS(fix) \ - ((fix)->fx_r_type == 0 \ - && ((fix)->fx_size == 2 \ - || (fix)->fx_size == 1 \ - || (fix)->fx_size == 4)) -#endif - -#define SWITCH_TABLE(fix) \ - ((fix)->fx_addsy != NULL \ - && (fix)->fx_subsy != NULL \ - && S_GET_SEGMENT ((fix)->fx_addsy) == text_section \ - && S_GET_SEGMENT ((fix)->fx_subsy) == text_section \ - && ((fix)->fx_r_type == BFD_RELOC_32 \ - || (fix)->fx_r_type == BFD_RELOC_16 \ - || (fix)->fx_r_type == BFD_RELOC_8 \ - || SWITCH_TABLE_CONS (fix))) - /* See whether we need to force a relocation into the output file. This is used to force out switch and PC relative relocations when relaxing. */ @@ -3244,11 +3219,11 @@ int sh_force_relocation (fix) fixS *fix; { - if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY || fix->fx_r_type == BFD_RELOC_SH_LOOP_START - || fix->fx_r_type == BFD_RELOC_SH_LOOP_END) + || fix->fx_r_type == BFD_RELOC_SH_LOOP_END + || S_FORCE_RELOC (fix->fx_addsy)) return 1; if (! sh_relax) @@ -3271,20 +3246,9 @@ boolean sh_fix_adjustable (fixP) fixS *fixP; { - - if (fixP->fx_addsy == NULL) - return 1; - - if (fixP->fx_r_type == BFD_RELOC_SH_PCDISP8BY2 - || fixP->fx_r_type == BFD_RELOC_SH_PCDISP12BY2 - || fixP->fx_r_type == BFD_RELOC_SH_PCRELIMM8BY2 - || fixP->fx_r_type == BFD_RELOC_SH_PCRELIMM8BY4 - || fixP->fx_r_type == BFD_RELOC_8_PCREL - || fixP->fx_r_type == BFD_RELOC_SH_SWITCH16 - || fixP->fx_r_type == BFD_RELOC_SH_SWITCH32) - return 1; - - if (! TC_RELOC_RTSYM_LOC_FIXUP (fixP) + if (fixP->fx_r_type == BFD_RELOC_32_PLT_PCREL + || fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL + || fixP->fx_r_type == BFD_RELOC_SH_GOTPC || fixP->fx_r_type == BFD_RELOC_RVA) return 0; @@ -3530,9 +3494,10 @@ md_apply_fix3 (fixP, valP, seg) /* Make the jump instruction point to the address of the operand. At runtime we merely add the offset to the actual PLT entry. */ * valP = 0xfffffffc; - val = fixP->fx_addnumber; + val = 0; if (fixP->fx_subsy) val -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_addnumber = val; md_number_to_chars (buf, val, 4); break; @@ -3903,13 +3868,6 @@ tc_gen_reloc (section, fixp) *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; - if (fixp->fx_subsy - && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) - { - fixp->fx_addnumber -= S_GET_VALUE (fixp->fx_subsy); - fixp->fx_subsy = 0; - } - r_type = fixp->fx_r_type; if (SWITCH_TABLE (fixp)) @@ -3953,7 +3911,7 @@ tc_gen_reloc (section, fixp) rel->addend = 0; rel->howto = bfd_reloc_type_lookup (stdoutput, r_type); - if (rel->howto == NULL || fixp->fx_subsy) + if (rel->howto == NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, _("Cannot represent relocation type %s"), diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index ffe948a7dd6..6ff45c88761 100644 --- a/gas/config/tc-sh.h +++ b/gas/config/tc-sh.h @@ -24,6 +24,11 @@ #define TARGET_ARCH bfd_arch_sh #if ANSI_PROTOTYPES +/* The type fixS is defined (to struct fix) in write.h, but write.h uses + definitions from this file. To avoid problems with including write.h + after the "right" definitions, don't; just forward-declare struct fix + here. */ +struct fix; struct segment_info_struct; struct internal_reloc; #endif @@ -53,30 +58,42 @@ extern void sh_handle_align PARAMS ((fragS *)); /* We need to force out some relocations when relaxing. */ #define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix) - -/* The type fixS is defined (to struct fix) in write.h, but write.h uses - definitions from this file. To avoid problems with including write.h - after the "right" definitions, don't; just forward-declare struct fix - here. */ -struct fix; extern int sh_force_relocation PARAMS ((struct fix *)); -#ifdef OBJ_ELF -#define obj_fix_adjustable(fixP) sh_fix_adjustable(fixP) -struct fix; -extern boolean sh_fix_adjustable PARAMS ((struct fix *)); +/* This macro decides whether a particular reloc is an entry in a + switch table. It is used when relaxing, because the linker needs + to know about all such entries so that it can adjust them if + necessary. */ -/* This arranges for gas/write.c to not apply a relocation if - obj_fix_adjustable() says it is not adjustable. */ -/* ??? fixups with symbols in SEC_MERGE sections are marked with - obj_fix_adjustable and have a non-section symbol, as in - "vwxyz"+1 in execute/string-opt-6.c . Maybe the test of - (symbol_used_in_reloc_p should be done in the machine-independent code. */ -#define TC_FIX_ADJUSTABLE(fixP) \ - (! symbol_used_in_reloc_p (fixP->fx_addsy) && obj_fix_adjustable (fixP)) +#ifdef BFD_ASSEMBLER +#define SWITCH_TABLE_CONS(FIX) (0) +#else +#define SWITCH_TABLE_CONS(FIX) \ + ((FIX)->fx_r_type == 0 \ + && ((FIX)->fx_size == 2 \ + || (FIX)->fx_size == 1 \ + || (FIX)->fx_size == 4)) #endif -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define SWITCH_TABLE(FIX) \ + ((FIX)->fx_addsy != NULL \ + && (FIX)->fx_subsy != NULL \ + && S_GET_SEGMENT ((FIX)->fx_addsy) == text_section \ + && S_GET_SEGMENT ((FIX)->fx_subsy) == text_section \ + && ((FIX)->fx_r_type == BFD_RELOC_32 \ + || (FIX)->fx_r_type == BFD_RELOC_16 \ + || (FIX)->fx_r_type == BFD_RELOC_8 \ + || SWITCH_TABLE_CONS (FIX))) + +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (! SEG_NORMAL (SEG) \ + || (sh_relax && SWITCH_TABLE (FIX))) + +/* Don't complain when we leave fx_subsy around. */ +#define TC_VALIDATE_FIX_SUB(FIX) \ + (sh_relax && SWITCH_TABLE (FIX)) + +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define IGNORE_NONSTANDARD_ESCAPES @@ -115,6 +132,7 @@ extern void sh_flush_pending_output PARAMS ((void)); #endif extern void sh_frob_file PARAMS ((void)); + #ifdef OBJ_COFF /* COFF specific definitions. */ @@ -192,12 +210,15 @@ extern void sh_elf_final_processing PARAMS ((void)); the expression into something we can use. */ #define TC_RELOC_GLOBAL_OFFSET_TABLE BFD_RELOC_SH_GOTPC -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we +#define tc_fix_adjustable(FIX) sh_fix_adjustable(FIX) +extern boolean sh_fix_adjustable PARAMS ((struct fix *)); + +/* Values passed to md_apply_fix3 don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* This expression evaluates to true if the relocation is for a local object + for which we still want to do the relocation at runtime. False if we are willing to perform this relocation while building the .o file. - This is only used for pcrel relocations, so GOTOFF does not need to be - checked here. I am not sure if some of the others are ever used with - pcrel, but it is easier to be safe than sorry. We can't resolve references to the GOT or the PLT when creating the object file, since these tables are only created by the linker. @@ -205,15 +226,25 @@ extern void sh_elf_final_processing PARAMS ((void)); assembler can't compute the appropriate reloc, since its location can only be determined at link time. */ -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \ - && (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC \ - && ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy)))) +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || (FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (FIX)->fx_r_type == BFD_RELOC_32_GOT_PCREL \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC \ + || TC_FORCE_RELOCATION (FIX)) + +/* This keeps the subtracted symbol around, for use by PLT_PCREL + relocs. */ +#define TC_FORCE_RELOCATION_SUB_ABS(FIX) \ + ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || S_FORCE_RELOC ((FIX)->fx_subsy)) + +/* Don't complain when we leave fx_subsy around. */ +#undef TC_VALIDATE_FIX_SUB +#define TC_VALIDATE_FIX_SUB(FIX) \ + ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (sh_relax && SWITCH_TABLE (FIX))) #define md_parse_name(name, exprP, nextcharP) \ sh_parse_name ((name), (exprP), (nextcharP)) diff --git a/gas/config/tc-sh64.h b/gas/config/tc-sh64.h index d786162d750..ad631c53599 100644 --- a/gas/config/tc-sh64.h +++ b/gas/config/tc-sh64.h @@ -1,5 +1,5 @@ /* This file is tc-sh64.h - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -75,37 +75,48 @@ extern const char *sh64_target_format PARAMS ((void)); #define TARGET_MACH sh64_target_mach () extern int sh64_target_mach PARAMS ((void)); -#undef TC_RELOC_RTSYM_LOC_FIXUP -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \ - && (FIX)->fx_r_type != BFD_RELOC_SH_PLT_LOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_PLT_MEDLOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_PLT_MEDHI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_PLT_HI16 \ - && (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT_LOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT_MEDLOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT_MEDHI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT_HI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT10BY4 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOT10BY8 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT32 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT_LOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT_MEDLOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT_MEDHI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT_HI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT10BY4 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPLT10BY8 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC_LOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC_MEDLOW16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC_MEDHI16 \ - && (FIX)->fx_r_type != BFD_RELOC_SH_GOTPC_HI16 \ - && ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy)))) +#undef TC_FORCE_RELOCATION_LOCAL +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || (FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_LOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_MEDLOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_MEDHI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_HI16 \ + || (FIX)->fx_r_type == BFD_RELOC_32_GOT_PCREL \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_LOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_MEDLOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_MEDHI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_HI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT10BY4 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOT10BY8 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT32 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_LOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_MEDLOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_MEDHI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_HI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT10BY4 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT10BY8 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_LOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_MEDLOW16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_MEDHI16 \ + || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_HI16 \ + || TC_FORCE_RELOCATION (FIX)) + +#undef TC_FORCE_RELOCATION_SUB_SAME +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (! SEG_NORMAL (SEG) \ + || (sh_relax && SWITCH_TABLE (FIX)) \ + || *symbol_get_tc ((FIX)->fx_addsy) != NULL) + +/* Don't complain when we leave fx_subsy around. */ +#undef TC_VALIDATE_FIX_SUB +#define TC_VALIDATE_FIX_SUB(FIX) \ + ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (sh_relax && SWITCH_TABLE (FIX)) \ + || *symbol_get_tc ((FIX)->fx_addsy) != NULL) /* Note the kludge: we want to put back C, and we also want to consume the expression, since we have handled it ourselves. FIXME: What we really @@ -120,8 +131,8 @@ extern int sh64_consume_datalabel #define DOLLAR_DOT #undef MD_PCREL_FROM_SECTION -#define MD_PCREL_FROM_SECTION(FIXP, SEC) \ - shmedia_md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) \ + shmedia_md_pcrel_from_section (FIX, SEC) extern valueT shmedia_md_pcrel_from_section PARAMS ((struct fix *, segT)); diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 5fa4fe980f3..1a24c2b1272 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -2902,34 +2902,9 @@ md_apply_fix3 (fixP, valP, segment) fixP->fx_addnumber = val; /* Remember value for emit_reloc. */ #ifdef OBJ_ELF - /* FIXME: SPARC ELF relocations don't use an addend in the data - field itself. This whole approach should be somehow combined - with the calls to bfd_install_relocation. Also, the value passed - in by fixup_segment includes the value of a defined symbol. We - don't want to include the value of an externally visible symbol. */ + /* SPARC ELF relocations don't use an addend in the data field. */ if (fixP->fx_addsy != NULL) - { - symbolS * sym = fixP->fx_addsy; - segT seg = S_GET_SEGMENT (sym); - - if (symbol_used_in_reloc_p (sym) - && (S_IS_EXTERNAL (sym) - || S_IS_WEAK (sym) - || (seg->flags & SEC_MERGE) - || (seg->flags & SEC_THREAD_LOCAL) - || (sparc_pic_code && ! fixP->fx_pcrel) - || (seg != segment - && (((bfd_get_section_flags (stdoutput, seg) & SEC_LINK_ONCE) != 0) - || (strncmp (segment_name (seg), - ".gnu.linkonce", - sizeof ".gnu.linkonce" - 1) == 0)))) - && seg != absolute_section - && seg != undefined_section - && ! bfd_is_com_section (seg)) - fixP->fx_addnumber -= S_GET_VALUE (sym); - - return; - } + return; #endif /* This is a hack. There should be a better way to @@ -3352,10 +3327,7 @@ tc_gen_reloc (section, fixp) switch (code) { case BFD_RELOC_32_PCREL_S2: - if (! S_IS_DEFINED (fixp->fx_addsy) - || S_IS_COMMON (fixp->fx_addsy) - || S_IS_EXTERNAL (fixp->fx_addsy) - || S_IS_WEAK (fixp->fx_addsy)) + if (S_FORCE_RELOC (fixp->fx_addsy)) code = BFD_RELOC_SPARC_WPLT30; break; case BFD_RELOC_HI22: @@ -4385,6 +4357,6 @@ elf32_sparc_force_relocation (fixp) || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - return 0; + return S_FORCE_RELOC (fixp->fx_addsy); } #endif diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index 5d545de0e23..62be7495b35 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -1,6 +1,6 @@ /* tc-sparc.h - Macros and type defines for the sparc. Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -69,74 +69,59 @@ extern void sparc_handle_align PARAMS ((struct frag *)); #define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 4) -#if defined (OBJ_ELF) || defined (OBJ_AOUT) - -/* This expression evaluates to false if the relocation is for a local - object for which we still want to do the relocation at runtime. - True if we are willing to perform this relocation while building - the .o file. - - If the reloc is against an externally visible symbol, then the - a.out assembler should not do the relocation if generating PIC, and - the ELF assembler should never do the relocation. */ - #ifdef OBJ_ELF -#define obj_relocate_extern 0 -#else -#define obj_relocate_extern (! sparc_pic_code) -#endif - -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - (obj_relocate_extern \ - || (FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) +#define TC_FORCE_RELOCATION(FIX) elf32_sparc_force_relocation(FIX) +extern int elf32_sparc_force_relocation PARAMS ((struct fix *)); #endif /* I know that "call 0" fails in sparc-coff if this doesn't return 1. I don't know about other relocation types, or other formats, yet. */ #ifdef OBJ_COFF -#define TC_FORCE_RELOCATION(FIXP) \ - ((FIXP)->fx_r_type == BFD_RELOC_32_PCREL_S2 \ - && ((FIXP)->fx_addsy == 0 \ - || S_GET_SEGMENT ((FIXP)->fx_addsy) == absolute_section)) +#define TC_FORCE_RELOCATION_ABS(FIX) \ + ((FIX)->fx_r_type == BFD_RELOC_32_PCREL_S2 \ + || TC_FORCE_RELOCATION (FIX)) + #define RELOC_REQUIRES_SYMBOL #endif -#ifdef OBJ_ELF -#define TC_FORCE_RELOCATION(fixp) elf32_sparc_force_relocation(fixp) -extern int elf32_sparc_force_relocation PARAMS ((struct fix *)); +#ifdef OBJ_AOUT +/* This expression evaluates to true if the relocation is for a local + object for which we still want to do the relocation at runtime. + False if we are willing to perform this relocation while building + the .o file. */ + +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || (sparc_pic_code \ + && S_IS_EXTERNAL ((FIX)->fx_addsy)) \ + || TC_FORCE_RELOCATION (FIX)) #endif #ifdef OBJ_ELF -/* Keep relocations against global symbols. Don't turn them into - relocations against sections. This is required for the dynamic - linker to operate properly. When generating PIC, we need to keep - any non PC relative reloc. The PIC part of this test must be - parallel to the code in tc_gen_reloc which converts relocations to - GOT relocations. */ +/* Don't turn certain relocs into relocations against sections. This + is required for the dynamic linker to operate properly. When + generating PIC, we need to keep any non PC relative reloc. The PIC + part of this test must be parallel to the code in tc_gen_reloc which + converts relocations to GOT relocations. */ #define tc_fix_adjustable(FIX) \ - (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && (FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ + ((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \ && (! sparc_pic_code \ || ((FIX)->fx_r_type != BFD_RELOC_HI22 \ && (FIX)->fx_r_type != BFD_RELOC_LO10 \ && (FIX)->fx_r_type != BFD_RELOC_SPARC13 \ && ((FIX)->fx_r_type != BFD_RELOC_32_PCREL_S2 \ - || (S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy) \ - && ! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy))) \ + || !S_FORCE_RELOC ((FIX)->fx_addsy)) \ && ((FIX)->fx_pcrel \ || ((FIX)->fx_subsy != NULL \ && (S_GET_SEGMENT ((FIX)->fx_subsy) \ == S_GET_SEGMENT ((FIX)->fx_addsy))) \ || S_IS_LOCAL ((FIX)->fx_addsy))))) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + /* Finish up the entire symtab. */ #define tc_adjust_symtab() sparc_adjust_symtab () extern void sparc_adjust_symtab PARAMS ((void)); @@ -184,11 +169,11 @@ extern void cons_fix_new_sparc } \ while (0) -#define TC_FIX_DATA_PRINT(FILE, FIXP) \ +#define TC_FIX_DATA_PRINT(FILE, FIX) \ do \ { \ fprintf ((FILE), "addend2=%ld\n", \ - (unsigned long) (FIXP)->tc_fix_data); \ + (unsigned long) (FIX)->tc_fix_data); \ } \ while (0) diff --git a/gas/config/tc-tic30.c b/gas/config/tc-tic30.c index 1258b1317d5..a4e90c04c07 100644 --- a/gas/config/tc-tic30.c +++ b/gas/config/tc-tic30.c @@ -1,5 +1,5 @@ /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30 - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au) This file is part of GAS, the GNU Assembler. @@ -77,9 +77,6 @@ const pseudo_typeS md_pseudo_table[] = { {0, 0, 0} }; -#undef USE_STDOUT -#define USE_STDOUT 1 - #ifdef USE_STDARG #include @@ -1594,13 +1591,7 @@ md_parse_option (c, arg) int c; char *arg; { - int i; - debug ("In md_parse_option()\n"); - for (i = 0; i < c; i++) - { - printf ("%c\n", arg[c]); - } return 0; } @@ -1838,10 +1829,7 @@ tc_gen_reloc (section, fixP) rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy); rel->address = fixP->fx_frag->fr_address + fixP->fx_where; - if (fixP->fx_pcrel) - rel->addend = fixP->fx_addnumber; - else - rel->addend = 0; + rel->addend = 0; rel->howto = bfd_reloc_type_lookup (stdoutput, code); if (!rel->howto) { diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index aa789b3dc28..b3c45a033e4 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -2457,14 +2457,6 @@ v850_fix_adjustable (fixP) if (fixP->fx_addsy == NULL) return 1; - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - /* Similarly for weak symbols. */ - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - /* Don't adjust function names. */ if (S_IS_FUNCTION (fixP->fx_addsy)) return 0; @@ -2481,24 +2473,21 @@ int v850_force_relocation (fixP) struct fix *fixP; { - if (fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)) - return 1; - if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; - if ( fixP->fx_r_type == BFD_RELOC_V850_LONGCALL + if (fixP->fx_r_type == BFD_RELOC_V850_LONGCALL || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP) return 1; if (v850_relax && (fixP->fx_pcrel - || fixP->fx_r_type == BFD_RELOC_V850_ALIGN - || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL - || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL - || fixP->fx_r_type >= BFD_RELOC_UNUSED)) + || fixP->fx_r_type == BFD_RELOC_V850_ALIGN + || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL + || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL + || fixP->fx_r_type >= BFD_RELOC_UNUSED)) return 1; - return 0; + return S_FORCE_RELOC (fixP->fx_addsy); } diff --git a/gas/config/tc-v850.h b/gas/config/tc-v850.h index f3827e7c9c1..c69a06a13c5 100644 --- a/gas/config/tc-v850.h +++ b/gas/config/tc-v850.h @@ -37,16 +37,15 @@ #define md_operand(x) -#define obj_fix_adjustable(fixP) v850_fix_adjustable(fixP) +#define tc_fix_adjustable(FIX) v850_fix_adjustable (FIX) extern boolean v850_fix_adjustable PARAMS ((struct fix *)); -#define TC_FORCE_RELOCATION(fixp) v850_force_relocation(fixp) +#define TC_FORCE_RELOCATION(FIX) v850_force_relocation(FIX) extern int v850_force_relocation PARAMS ((struct fix *)); #ifdef OBJ_ELF -/* This arranges for gas/write.c to not apply a relocation if - obj_fix_adjustable() says it is not adjustable. */ -#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP) +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 #endif /* Permit temporary numeric labels. */ @@ -97,7 +96,7 @@ extern void v850_handle_align PARAMS ((fragS *)); { ".call_table_data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \ { ".call_table_text", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR }, -#define MD_PCREL_FROM_SECTION(fixP,section) v850_pcrel_from_section (fixP, section) +#define MD_PCREL_FROM_SECTION(FIX, SEC) v850_pcrel_from_section (FIX, SEC) extern long v850_pcrel_from_section PARAMS ((struct fix *, asection *)); #define DWARF2_LINE_MIN_INSN_LENGTH 2 diff --git a/gas/config/tc-vax.h b/gas/config/tc-vax.h index 4953ff4fc47..a1beb1c82e1 100644 --- a/gas/config/tc-vax.h +++ b/gas/config/tc-vax.h @@ -1,5 +1,5 @@ /* tc-vax.h -- Header file for tc-vax.c. - Copyright 1987, 1991, 1992, 1993, 1995, 1996, 1997, 2000 + Copyright 1987, 1991, 1992, 1993, 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -59,28 +59,15 @@ long md_chars_to_number PARAMS ((unsigned char *, int)); extern const struct relax_type md_relax_table[]; #define TC_GENERIC_RELAX_TABLE md_relax_table -/* This expression evaluates to false if the relocation is for a local object - for which we still want to do the relocation at runtime. True if we - are willing to perform this relocation while building the .o file. If - the reloc is against an externally visible symbol, then the assembler - should never do the relocation. */ - #ifdef BFD_ASSEMBLER -#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ - ((FIX)->fx_addsy == NULL \ - || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ - && S_IS_DEFINED ((FIX)->fx_addsy) \ - && ! S_IS_COMMON ((FIX)->fx_addsy))) -#define TC_FIX_ADJUSTABLE(FIX) \ - (!symbol_used_in_reloc_p ((FIX)) && tc_fix_adjustable ((FIX))) +/* Values passed to md_apply_fix3 don't include symbol values. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define tc_fix_adjustable(FIX) \ ((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \ && (FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \ && (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \ - && ! S_IS_EXTERNAL ((FIX)->fx_addsy) \ - && ! S_IS_WEAK ((FIX)->fx_addsy) \ && ((FIX)->fx_pcrel \ || ((FIX)->fx_subsy != NULL \ && (S_GET_SEGMENT ((FIX)->fx_subsy) \ diff --git a/gas/config/tc-w65.h b/gas/config/tc-w65.h index 0bdfcea4776..a0287286064 100644 --- a/gas/config/tc-w65.h +++ b/gas/config/tc-w65.h @@ -1,5 +1,5 @@ /* This file is tc-w65.h - Copyright 1995, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright 1995, 1997, 1998, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -24,6 +24,7 @@ #if ANSI_PROTOTYPES struct internal_reloc; +struct fix; #endif #define WORKING_DOT_WORD diff --git a/gas/config/tc-xstormy16.c b/gas/config/tc-xstormy16.c index 5e77bd17af9..30b8bcf4596 100644 --- a/gas/config/tc-xstormy16.c +++ b/gas/config/tc-xstormy16.c @@ -379,8 +379,10 @@ xstormy16_force_relocation (fix) return 1; default: - return 0; + break; } + + return S_FORCE_RELOC (fix->fx_addsy); } /* Return true if a relocation against a symbol may be replaced with @@ -390,22 +392,15 @@ boolean xstormy16_fix_adjustable (fixP) fixS * fixP; { - if (fixP->fx_addsy == NULL) - return 1; - - /* Prevent all adjustments to global symbols. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - - if (S_IS_WEAK (fixP->fx_addsy)) - return 0; - /* We need the symbol name for the VTABLE entries. */ - if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; - return ! xstormy16_force_relocation (fixP); + if (fixP->fx_r_type == BFD_RELOC_XSTORMY16_FPTR16) + return 0; + + return 1; } /* This is a copy of gas_cgen_md_apply_fix3, with some enhancements to @@ -418,7 +413,7 @@ xstormy16_md_apply_fix3 (fixP, valueP, seg) segT seg ATTRIBUTE_UNUSED; { char *where = fixP->fx_frag->fr_literal + fixP->fx_where; - valueT value; + valueT value = *valueP; /* Canonical name, since used a lot. */ CGEN_CPU_DESC cd = gas_cgen_cpu_desc; @@ -447,39 +442,12 @@ xstormy16_md_apply_fix3 (fixP, valueP, seg) break; } - /* FIXME FIXME FIXME: The value we are passed in *valuep includes - the symbol values. Since we are using BFD_ASSEMBLER, if we are - doing this relocation the code in write.c is going to call - bfd_install_relocation, which is also going to use the symbol - value. That means that if the reloc is fully resolved we want to - use *valuep since bfd_install_relocation is not being used. - However, if the reloc is not fully resolved we do not want to use - *valuep, and must use fx_offset instead. However, if the reloc - is PC relative, we do want to use *valuep since it includes the - result of md_pcrel_from. This is confusing. */ - if (fixP->fx_addsy == (symbolS *) NULL) - { - value = *valueP; - fixP->fx_done = 1; - } - else if (fixP->fx_pcrel) - value = *valueP; - else - { - value = fixP->fx_offset; - if (fixP->fx_subsy != (symbolS *) NULL) - { - if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section) - value -= S_GET_VALUE (fixP->fx_subsy); - else - { - /* We don't actually support subtracting a symbol. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("expression too complex")); - } - } - } + fixP->fx_done = 1; + + /* We don't actually support subtracting a symbol. */ + if (fixP->fx_subsy != (symbolS *) NULL) + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) { diff --git a/gas/config/tc-xstormy16.h b/gas/config/tc-xstormy16.h index a5072f62255..c3ff06bdbbc 100644 --- a/gas/config/tc-xstormy16.h +++ b/gas/config/tc-xstormy16.h @@ -34,10 +34,6 @@ #define TARGET_BYTES_BIG_ENDIAN 0 -/* call md_pcrel_from_section, not md_pcrel_from */ -long md_pcrel_from_section PARAMS ((struct fix *, segT)); -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) - /* Permit temporary numeric labels. */ #define LOCAL_LABELS_FB 1 @@ -46,10 +42,12 @@ long md_pcrel_from_section PARAMS ((struct fix *, segT)); /* We don't need to handle .word strangely. */ #define WORKING_DOT_WORD -#define MD_APPLY_FIX3 +/* Values passed to md_apply_fix3 don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + #define md_apply_fix3 xstormy16_md_apply_fix3 -#define obj_fix_adjustable(fixP) xstormy16_fix_adjustable (fixP) +#define tc_fix_adjustable(FIX) xstormy16_fix_adjustable (FIX) extern boolean xstormy16_fix_adjustable PARAMS ((struct fix *)); #define TC_FORCE_RELOCATION(fix) xstormy16_force_relocation (fix) @@ -60,7 +58,7 @@ extern int xstormy16_force_relocation PARAMS ((struct fix *)); #define tc_gen_reloc gas_cgen_tc_gen_reloc /* Call md_pcrel_from_section(), not md_pcrel_from(). */ -#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC) +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); #define TC_CONS_FIX_NEW xstormy16_cons_fix_new diff --git a/gas/doc/internals.texi b/gas/doc/internals.texi index 6bd327701a6..647d2736556 100644 --- a/gas/doc/internals.texi +++ b/gas/doc/internals.texi @@ -1,6 +1,6 @@ \input texinfo @c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -@c 2001 +@c 2001, 2002 @c Free Software Foundation, Inc. @setfilename internals.info @node Top @@ -1250,18 +1250,94 @@ information removed. Depending upon the processing performed by @code{md_convert_frag} the frag information may or may not be necessary, as may the resolved values of the symbols. The default value is 1. -@item md_apply_fix3 -@cindex md_apply_fix3 -GAS will call this for each fixup. It should store the correct value in the -object file. @code{fixup_segment} performs a generic overflow check on the -@code{valueT *val} argument after @code{md_apply_fix3} returns. If the overflow -check is relevant for the target machine, then @code{md_apply_fix3} should -modify @code{valueT *val}, typically to the value stored in the object file. +@item TC_VALIDATE_FIX (@var{fixP}, @var{seg}, @var{skip}) +@cindex TC_VALIDATE_FIX +This macro is evaluated for each fixup (when @var{linkrelax} is not set). +It may be used to change the fixup in @code{struct fix *@var{fixP}} before +the generic code sees it, or to fully process the fixup. In the latter case, +a @code{goto @var{skip}} will bypass the generic code. -@item TC_HANDLES_FX_DONE -@cindex TC_HANDLES_FX_DONE -If this macro is defined, it means that @code{md_apply_fix3} correctly sets the -@code{fx_done} field in the fixup. +@item md_apply_fix3 (@var{fixP}, @var{valP}, @var{seg}) +@cindex md_apply_fix3 +GAS will call this for each fixup that passes the @code{TC_VALIDATE_FIX} test +when @var{linkrelax} is not set. It should store the correct value in the +object file. @code{struct fix *@var{fixP}} is the fixup @code{md_apply_fix3} +is operating on. @code{valueT *@var{valP}} is the value to store into the +object files, or at least is the generic code's best guess. Specifically, +*@var{valP} is the value of the fixup symbol, perhaps modified by +@code{MD_APPLY_SYM_VALUE}, plus @code{@var{fixP}->fx_offset} (symbol addend), +less @code{MD_PCREL_FROM_SECTION} for pc-relative fixups. +@code{segT @var{seg}} is the section the fix is in. +@code{fixup_segment} performs a generic overflow check on *@var{valP} after +@code{md_apply_fix3} returns. If the overflow check is relevant for the target +machine, then @code{md_apply_fix3} should modify *@var{valP}, typically to the +value stored in the object file. + +@item TC_FORCE_RELOCATION (@var{fix}) +@cindex TC_FORCE_RELOCATION +If this macro returns non-zero, it guarantees that a relocation will be emitted +even when the value can be resolved locally, as @code{fixup_segment} tries to +reduce the number of relocations emitted. For example, a fixup expression +against an absolute symbol will normally not require a reloc. If undefined, +a default of @w{@code{(S_FORCE_RELOC ((@var{fix})->fx_addsy))}} is used. + +@item TC_FORCE_RELOCATION_ABS (@var{fix}) +@cindex TC_FORCE_RELOCATION_ABS +Like @code{TC_FORCE_RELOCATION}, but used only for fixup expressions against an +absolute symbol. If undefined, @code{TC_FORCE_RELOCATION} will be used. + +@item TC_FORCE_RELOCATION_LOCAL (@var{fix}) +@cindex TC_FORCE_RELOCATION_LOCAL +Like @code{TC_FORCE_RELOCATION}, but used only for fixup expressions against a +symbol in the current section. If undefined, fixups that are not +@code{fx_pcrel} or @code{fx_plt} or for which @code{TC_FORCE_RELOCATION} +returns non-zero, will emit relocs. + +@item TC_FORCE_RELOCATION_SUB_SAME (@var{fix}, @var{seg}) +@cindex TC_FORCE_RELOCATION_SUB +This macro controls resolution of fixup expressions involving the +difference of two symbols in the same section. If this macro returns zero, +the subtrahend will be resolved and @code{fx_subsy} set to @code{NULL} for +@code{md_apply_fix3}. If undefined, the default of +@w{@code{! SEG_NORMAL (@var{seg})}} will be used. + +@item TC_FORCE_RELOCATION_SUB_ABS (@var{fix}) +@cindex TC_FORCE_RELOCATION_SUB_ABS +Like @code{TC_FORCE_RELOCATION_SUB_SAME}, but used when the subtrahend is an +absolute symbol. If the macro is undefined a default of +@w{@code{(S_FORCE_RELOC ((@var{fix})->fx_subsy))}} is used. + +@item TC_FORCE_RELOCATION_SUB_LOCAL (@var{fix}) +@cindex TC_FORCE_RELOCATION_SUB_LOCAL +Like @code{TC_FORCE_RELOCATION_SUB_ABS}, but the subtrahend is a symbol in the +same section as the fixup. + +@item TC_VALIDATE_FIX_SUB (@var{fix}) +@cindex TC_VALIDATE_FIX_SUB +This macro is evaluated for any fixup with a @code{fx_subsy} that +@code{fixup_segment} cannot reduce to a number. If the macro returns +@code{false} an error will be reported. + +@item MD_APPLY_SYM_VALUE (@var{fix}) +@cindex MD_APPLY_SYM_VALUE +This macro controls whether the symbol value becomes part of the value passed +to @code{md_apply_fix3}. If the macro is undefined, or returns non-zero, the +symbol value will be included. For ELF, a suitable definition might simply be +@code{0}, because ELF relocations don't include the symbol value in the addend. + +@item S_FORCE_RELOC (@var{sym}) +@cindex S_FORCE_RELOC +This macro (or function, for @code{BFD_ASSEMBLER} gas) returns true for symbols +that should not be reduced to section symbols or eliminated from expressions, +because they may be overridden by the linker. ie. for symbols that are +undefined, common or weak, or for ELF assemblers that support ELF shared +library linking semantics, global. + +@item EXTERN_FORCE_RELOC +@cindex EXTERN_FORCE_RELOC +This macro controls whether @code{S_FORCE_RELOC} returns true for global +symbols. If undefined, the default is @code{true} for ELF assemblers, and +@code{false} for non-ELF. @item tc_gen_reloc @cindex tc_gen_reloc @@ -1449,12 +1525,6 @@ You should define this macro to copy object format specific information from one symbol to another. GAS will call it when one symbol is equated to another. -@item obj_fix_adjustable -@cindex obj_fix_adjustable -You may define this macro to indicate whether a fixup against a locally defined -symbol should be adjusted to be against the section symbol. It should return a -non-zero value if the adjustment is acceptable. - @item obj_sec_sym_ok_for_reloc @cindex obj_sec_sym_ok_for_reloc You may define this macro to indicate that it is OK to use a section symbol in diff --git a/gas/obj.h b/gas/obj.h index 846627a65e3..f7c1217f8ef 100644 --- a/gas/obj.h +++ b/gas/obj.h @@ -1,7 +1,7 @@ /* obj.h - defines the object dependent hooks for all object format backends. - Copyright 1987, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1999, 2000 + Copyright 1987, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -55,6 +55,7 @@ struct format_ops { void (*frob_symbol) PARAMS ((symbolS *, int *)); void (*frob_file) PARAMS ((void)); void (*frob_file_before_adjust) PARAMS ((void)); + void (*frob_file_before_fix) PARAMS ((void)); void (*frob_file_after_relocs) PARAMS ((void)); bfd_vma (*s_get_size) PARAMS ((symbolS *)); void (*s_set_size) PARAMS ((symbolS *, bfd_vma)); diff --git a/gas/subsegs.c b/gas/subsegs.c index 99d2a8b866c..a546b925259 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -1,6 +1,6 @@ /* subsegs.c - subsegments - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000 + 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -526,11 +526,7 @@ section_symbol (sec) #define EMIT_SECTION_SYMBOLS 1 #endif - if (! EMIT_SECTION_SYMBOLS -#ifdef BFD_ASSEMBLER - || symbol_table_frozen -#endif - ) + if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen) { /* Here we know it won't be going into the symbol table. */ s = symbol_create (sec->name, sec, 0, &zero_address_frag); @@ -555,6 +551,8 @@ section_symbol (sec) /* Use the BFD section symbol, if possible. */ if (obj_sec_sym_ok_for_reloc (sec)) symbol_set_bfdsym (s, sec->symbol); + else + symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM; seginfo->sym = s; return s; diff --git a/gas/symbols.c b/gas/symbols.c index 63b4d47a2a4..6d8147ce84a 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1762,6 +1762,28 @@ S_IS_DEFINED (s) return s->bsym->section != undefined_section; } + +#ifndef EXTERN_FORCE_RELOC +#define EXTERN_FORCE_RELOC IS_ELF +#endif + +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +int +S_FORCE_RELOC (s) + symbolS *s; +{ + if (LOCAL_SYMBOL_CHECK (s)) + return ((struct local_symbol *) s)->lsy_section == undefined_section; + + return ((s->bsym->flags & BSF_WEAK) != 0 + || (EXTERN_FORCE_RELOC + && (s->bsym->flags & BSF_GLOBAL) != 0) + || s->bsym->section == undefined_section + || bfd_is_com_section (s->bsym->section)); +} + int S_IS_DEBUG (s) symbolS *s; diff --git a/gas/symbols.h b/gas/symbols.h index 2fb0439679a..3c63d1b0fdf 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -90,6 +90,7 @@ extern int S_IS_EXTERNAL PARAMS ((symbolS *)); extern int S_IS_WEAK PARAMS ((symbolS *)); extern int S_IS_COMMON PARAMS ((symbolS *)); extern int S_IS_DEFINED PARAMS ((symbolS *)); +extern int S_FORCE_RELOC PARAMS ((symbolS *)); extern int S_IS_DEBUG PARAMS ((symbolS *)); extern int S_IS_LOCAL PARAMS ((symbolS *)); extern int S_IS_EXTERN PARAMS ((symbolS *)); diff --git a/gas/write.c b/gas/write.c index 3f609d3eadd..17c323209fe 100644 --- a/gas/write.c +++ b/gas/write.c @@ -33,19 +33,62 @@ #endif #ifndef TC_FORCE_RELOCATION -#define TC_FORCE_RELOCATION(FIX) 0 +#define TC_FORCE_RELOCATION(FIX) \ + (S_FORCE_RELOC ((FIX)->fx_addsy)) #endif -#ifndef TC_FORCE_RELOCATION_SECTION -#define TC_FORCE_RELOCATION_SECTION(FIX, SEG) TC_FORCE_RELOCATION (FIX) +#ifndef TC_FORCE_RELOCATION_ABS +#define TC_FORCE_RELOCATION_ABS(FIX) \ + (TC_FORCE_RELOCATION (FIX)) +#endif + +#ifndef TC_FORCE_RELOCATION_LOCAL +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_plt \ + || TC_FORCE_RELOCATION (FIX)) +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_SAME +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (! SEG_NORMAL (SEG)) +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_ABS +#define TC_FORCE_RELOCATION_SUB_ABS(FIX) \ + (S_FORCE_RELOC ((FIX)->fx_subsy)) +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_LOCAL +#ifdef DIFF_EXPR_OK +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) \ + (S_FORCE_RELOC ((FIX)->fx_subsy)) +#else +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1 +#endif +#endif + +#ifndef TC_VALIDATE_FIX_SUB +#ifdef UNDEFINED_DIFFERENCE_OK +/* The PA needs this for PIC code generation. */ +#define TC_VALIDATE_FIX_SUB(FIX) 1 +#else +#ifdef BFD_ASSEMBLER +#define TC_VALIDATE_FIX_SUB(FIX) \ + ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \ + || (FIX)->fx_r_type == BFD_RELOC_GPREL16) +#else +#define TC_VALIDATE_FIX_SUB(FIX) 0 +#endif +#endif #endif #ifndef TC_LINKRELAX_FIXUP #define TC_LINKRELAX_FIXUP(SEG) 1 #endif -#ifndef TC_FIX_ADJUSTABLE -#define TC_FIX_ADJUSTABLE(FIX) 1 +#ifndef MD_APPLY_SYM_VALUE +#define MD_APPLY_SYM_VALUE(FIX) 1 #endif #ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG @@ -65,6 +108,9 @@ extern const int md_long_jump_size; int finalize_syms = 0; int symbol_table_frozen; + +symbolS *abs_section_sym; + void print_fixup PARAMS ((fixS *)); #ifdef BFD_ASSEMBLER @@ -125,6 +171,7 @@ static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *)); static void chain_frchains_together PARAMS ((bfd *, segT, PTR)); static void cvt_frag_to_fill PARAMS ((segT, fragS *)); static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR)); +static void fix_segment PARAMS ((bfd *, asection *, PTR)); static void write_relocs PARAMS ((bfd *, asection *, PTR)); static void write_contents PARAMS ((bfd *, asection *, PTR)); static void set_symtab PARAMS ((void)); @@ -775,41 +822,32 @@ adjust_reloc_syms (abfd, sec, xxx) continue; } + /* If the symbol is undefined, common, weak, or global (ELF + shared libs), we can't replace it with the section symbol. */ + if (S_FORCE_RELOC (fixp->fx_addsy)) + continue; + + /* Is there some other (target cpu dependent) reason we can't adjust + this one? (E.g. relocations involving function addresses on + the PA. */ +#ifdef tc_fix_adjustable + if (! tc_fix_adjustable (fixp)) + continue; +#endif + + /* Since we're reducing to section symbols, don't attempt to reduce + anything that's already using one. */ + if (symbol_section_p (sym)) + continue; + symsec = S_GET_SEGMENT (sym); if (symsec == NULL) abort (); if (bfd_is_abs_section (symsec)) { - /* The fixup_segment routine will not use this symbol in a - relocation unless TC_FORCE_RELOCATION returns 1. */ - if (TC_FORCE_RELOCATION (fixp)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); -#ifdef UNDEFINED_DIFFERENCE_OK - if (fixp->fx_subsy != NULL) - symbol_mark_used_in_reloc (fixp->fx_subsy); -#endif - } - continue; - } - - /* If it's one of these sections, assume the symbol is - definitely going to be output. The code in - md_estimate_size_before_relax in tc-mips.c uses this test - as well, so if you change this code you should look at that - code. */ - if (bfd_is_und_section (symsec) - || bfd_is_com_section (symsec)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); -#ifdef UNDEFINED_DIFFERENCE_OK - /* We have the difference of an undefined symbol and some - other symbol. Make sure to mark the other symbol as used - in a relocation so that it will always be output. */ - if (fixp->fx_subsy) - symbol_mark_used_in_reloc (fixp->fx_subsy); -#endif + /* The fixup_segment routine normally will not use this + symbol in a relocation. */ continue; } @@ -819,116 +857,50 @@ adjust_reloc_syms (abfd, sec, xxx) this will always be correct. */ if (symsec != sec && ! S_IS_LOCAL (sym)) { - boolean linkonce; - - linkonce = false; -#ifdef BFD_ASSEMBLER - if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) - != 0) - linkonce = true; -#endif -#ifdef OBJ_ELF - /* The GNU toolchain uses an extension for ELF: a section - beginning with the magic string .gnu.linkonce is a - linkonce section. */ - if (strncmp (segment_name (symsec), ".gnu.linkonce", - sizeof ".gnu.linkonce" - 1) == 0) - linkonce = true; -#endif - - if (linkonce) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); -#ifdef UNDEFINED_DIFFERENCE_OK - if (fixp->fx_subsy != NULL) - symbol_mark_used_in_reloc (fixp->fx_subsy); -#endif - continue; - } - } - - /* Since we're reducing to section symbols, don't attempt to reduce - anything that's already using one. */ - if (symbol_section_p (sym)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; - } - -#ifdef BFD_ASSEMBLER - /* We can never adjust a reloc against a weak symbol. If we - did, and the weak symbol was overridden by a real symbol - somewhere else, then our relocation would be pointing at - the wrong area of memory. */ - if (S_IS_WEAK (sym)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; + if ((symsec->flags & SEC_LINK_ONCE) != 0 + || (IS_ELF + /* The GNU toolchain uses an extension for ELF: a + section beginning with the magic string + .gnu.linkonce is a linkonce section. */ + && strncmp (segment_name (symsec), ".gnu.linkonce", + sizeof ".gnu.linkonce" - 1) == 0)) + continue; } /* Never adjust a reloc against local symbol in a merge section with non-zero addend. */ if ((symsec->flags & SEC_MERGE) != 0 && fixp->fx_offset != 0) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; - } + continue; /* Never adjust a reloc against TLS local symbol. */ if ((symsec->flags & SEC_THREAD_LOCAL) != 0) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; - } -#endif - - /* Is there some other reason we can't adjust this one? (E.g., - call/bal links in i960-bout symbols.) */ -#ifdef obj_fix_adjustable - if (! obj_fix_adjustable (fixp)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; - } -#endif - - /* Is there some other (target cpu dependent) reason we can't adjust - this one? (E.g. relocations involving function addresses on - the PA. */ -#ifdef tc_fix_adjustable - if (! tc_fix_adjustable (fixp)) - { - symbol_mark_used_in_reloc (fixp->fx_addsy); - continue; - } -#endif - - /* If the section symbol isn't going to be output, the relocs - at least should still work. If not, figure out what to do - when we run into that case. + continue; - We refetch the segment when calling section_symbol, rather + /* We refetch the segment when calling section_symbol, rather than using symsec, because S_GET_VALUE may wind up changing the section when it calls resolve_symbol_value. */ fixp->fx_offset += S_GET_VALUE (sym); fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym)); - symbol_mark_used_in_reloc (fixp->fx_addsy); #ifdef DEBUG5 fprintf (stderr, "\nadjusted fixup:\n"); print_fixup (fixp); #endif } - else - { - /* There was no symbol required by this relocation. However, - BFD doesn't really handle relocations without symbols well. - So fake up a local symbol in the absolute section. */ - fixp->fx_addsy = section_symbol (absolute_section); - } dump_section_relocs (abfd, sec, stderr); } +static void +fix_segment (abfd, sec, xxx) + bfd *abfd ATTRIBUTE_UNUSED; + asection *sec; + PTR xxx ATTRIBUTE_UNUSED; +{ + segment_info_type *seginfo = seg_info (sec); + + fixup_segment (seginfo->fix_root, sec); +} + static void write_relocs (abfd, sec, xxx) bfd *abfd; @@ -947,8 +919,6 @@ write_relocs (abfd, sec, xxx) if (seginfo == NULL) return; - fixup_segment (seginfo->fix_root, sec); - n = 0; for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) n++; @@ -1926,6 +1896,15 @@ write_object_file () bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0); +#ifdef tc_frob_file_before_fix + tc_frob_file_before_fix (); +#endif +#ifdef obj_frob_file_before_fix + obj_frob_file_before_fix (); +#endif + + bfd_map_over_sections (stdoutput, fix_segment, (char *) 0); + /* Set up symbol table, and write it out. */ if (symbol_rootP) { @@ -1995,13 +1974,14 @@ write_object_file () want section symbols. Otherwise, we skip local symbols and symbols that the frob_symbol macros told us to punt, but we keep such symbols if they are used in relocs. */ - if ((! EMIT_SECTION_SYMBOLS - && symbol_section_p (symp)) + if (symp == abs_section_sym + || (! EMIT_SECTION_SYMBOLS + && symbol_section_p (symp)) /* Note that S_IS_EXTERN and S_IS_LOCAL are not always opposites. Sometimes the former checks flags and the latter examines the name... */ || (!S_IS_EXTERN (symp) - && (S_IS_LOCAL (symp) || punt) + && (punt || S_IS_LOCAL (symp)) && ! symbol_used_in_reloc_p (symp))) { symbol_remove (symp, &symbol_rootP, &symbol_lastP); @@ -2109,7 +2089,7 @@ relax_frag (segment, fragP, stretch) #endif know (sym_frag != NULL); #endif - know (!(S_GET_SEGMENT (symbolP) == absolute_section) + know (S_GET_SEGMENT (symbolP) != absolute_section || sym_frag == &zero_address_frag); target += S_GET_VALUE (symbolP); @@ -2555,10 +2535,6 @@ relax_segment (segment_frag_root, segment) #if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) -#ifndef TC_RELOC_RTSYM_LOC_FIXUP -#define TC_RELOC_RTSYM_LOC_FIXUP(X) (1) -#endif - /* fixup_segment() Go through all the fixS's in a segment and see which ones can be @@ -2576,13 +2552,19 @@ fixup_segment (fixP, this_segment) segT this_segment; { long seg_reloc_count = 0; - symbolS *add_symbolP; - symbolS *sub_symbolP; valueT add_number; - int pcrel, plt; fragS *fragP; segT add_symbol_segment = absolute_section; + if (fixP != NULL && abs_section_sym == NULL) + { +#ifndef BFD_ASSEMBLER + abs_section_sym = &abs_symbol; +#else + abs_section_sym = section_symbol (absolute_section); +#endif + } + /* If the linker is doing the relaxing, we must not do any fixups. Well, strictly speaking that's not true -- we could do any that @@ -2592,7 +2574,21 @@ fixup_segment (fixP, this_segment) if (linkrelax && TC_LINKRELAX_FIXUP (this_segment)) { for (; fixP; fixP = fixP->fx_next) - seg_reloc_count++; + if (!fixP->fx_done) + { + if (fixP->fx_addsy == NULL) + { + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; + } + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + seg_reloc_count++; + } TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); return seg_reloc_count; } @@ -2606,267 +2602,145 @@ fixup_segment (fixP, this_segment) fragP = fixP->fx_frag; know (fragP); - add_symbolP = fixP->fx_addsy; #ifdef TC_VALIDATE_FIX TC_VALIDATE_FIX (fixP, this_segment, skip); #endif - sub_symbolP = fixP->fx_subsy; add_number = fixP->fx_offset; - pcrel = fixP->fx_pcrel; - plt = fixP->fx_plt; - if (add_symbolP != NULL - && symbol_mri_common_p (add_symbolP)) + if (fixP->fx_addsy != NULL + && symbol_mri_common_p (fixP->fx_addsy)) { - know (add_symbolP->sy_value.X_op == O_symbol); - add_number += S_GET_VALUE (add_symbolP); + know (fixP->fx_addsy->sy_value.X_op == O_symbol); + add_number += S_GET_VALUE (fixP->fx_addsy); fixP->fx_offset = add_number; - add_symbolP = fixP->fx_addsy = - symbol_get_value_expression (add_symbolP)->X_add_symbol; + fixP->fx_addsy + = symbol_get_value_expression (fixP->fx_addsy)->X_add_symbol; } - if (add_symbolP) - add_symbol_segment = S_GET_SEGMENT (add_symbolP); + if (fixP->fx_addsy != NULL) + add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy); - if (sub_symbolP) + if (fixP->fx_subsy != NULL) { - resolve_symbol_value (sub_symbolP); - if (add_symbolP == NULL || add_symbol_segment == absolute_section) + segT sub_symbol_segment; + resolve_symbol_value (fixP->fx_subsy); + sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy); + if (fixP->fx_addsy != NULL + && sub_symbol_segment == add_symbol_segment + && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment)) { - if (add_symbolP != NULL) - { - add_number += S_GET_VALUE (add_symbolP); - add_symbolP = NULL; - fixP->fx_addsy = NULL; - } - - /* It's just -sym. */ - if (S_GET_SEGMENT (sub_symbolP) == absolute_section) - { - add_number -= S_GET_VALUE (sub_symbolP); - fixP->fx_subsy = NULL; - } - else if (pcrel - && S_GET_SEGMENT (sub_symbolP) == this_segment) - { - /* Should try converting to a constant. */ - goto bad_sub_reloc; - } - else - bad_sub_reloc: - as_bad_where (fixP->fx_file, fixP->fx_line, - _("negative of non-absolute symbol `%s'"), - S_GET_NAME (sub_symbolP)); - } - else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment - && SEG_NORMAL (add_symbol_segment)) - { - /* Difference of 2 symbols from same segment. - Can't make difference of 2 undefineds: 'value' means - something different for N_UNDF. */ -#ifdef TC_I960 - /* Makes no sense to use the difference of 2 arbitrary symbols - as the target of a call instruction. */ - if (fixP->fx_tcbit) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("callj to difference of two symbols")); -#endif /* TC_I960 */ - add_number += (S_GET_VALUE (add_symbolP) - - S_GET_VALUE (sub_symbolP)); + add_number += S_GET_VALUE (fixP->fx_addsy); + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + /* If the back-end code has selected a pc-relative + reloc, adjust the value to be pc-relative. */ if (1 #ifdef TC_M68K /* See the comment below about 68k weirdness. */ && 0 #endif - && pcrel) - add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); - - add_symbolP = NULL; - pcrel = 0; /* No further pcrel processing. */ - - /* Let the target machine make the final determination - as to whether or not a relocation will be needed to - handle this fixup. */ - if (!TC_FORCE_RELOCATION_SECTION (fixP, this_segment)) - { - fixP->fx_pcrel = 0; - fixP->fx_addsy = NULL; - fixP->fx_subsy = NULL; - } + && fixP->fx_pcrel) + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_addsy = NULL; + fixP->fx_subsy = NULL; + fixP->fx_pcrel = 0; } - else + else if (sub_symbol_segment == absolute_section + && !TC_FORCE_RELOCATION_SUB_ABS (fixP)) { - /* Different segments in subtraction. */ - know (!(S_IS_EXTERNAL (sub_symbolP) - && (S_GET_SEGMENT (sub_symbolP) == absolute_section))); - - if ((S_GET_SEGMENT (sub_symbolP) == absolute_section)) - add_number -= S_GET_VALUE (sub_symbolP); + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + fixP->fx_subsy = NULL; + } + else if (sub_symbol_segment == this_segment + && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP)) + { + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; -#ifdef DIFF_EXPR_OK - else if (S_GET_SEGMENT (sub_symbolP) == this_segment) - { - /* Make it pc-relative. */ - if (0 + /* Make it pc-relative. If the back-end code has not + selected a pc-relative reloc, cancel the adjustment + we do later on all pc-relative relocs. */ + if (0 #ifdef TC_M68K - /* Do this for m68k even if it's already described - as pc-relative. On the m68k, an operand of - "pc@(foo-.-2)" should address "foo" in a - pc-relative mode. */ - || 1 -#endif - || !pcrel) - { - add_number += MD_PCREL_FROM_SECTION (fixP, - this_segment); - pcrel = 1; - fixP->fx_pcrel = 1; - } - - add_number -= S_GET_VALUE (sub_symbolP); - sub_symbolP = 0; - fixP->fx_subsy = 0; - } -#endif -#ifdef UNDEFINED_DIFFERENCE_OK - /* The PA needs this for PIC code generation. We basically - don't want to do anything if we have the difference of two - symbols at this point. */ - else if (1) - { - /* Leave it alone. */ - } -#endif -#ifdef BFD_ASSEMBLER - else if (fixP->fx_r_type == BFD_RELOC_GPREL32 - || fixP->fx_r_type == BFD_RELOC_GPREL16) - { - /* Leave it alone. */ - } -#endif - else - { - char buf[50]; - sprint_value (buf, fragP->fr_address + fixP->fx_where); - as_bad_where (fixP->fx_file, fixP->fx_line, - _("subtraction of two symbols in different sections `%s' {%s section} - `%s' {%s section} at file address %s"), - S_GET_NAME (add_symbolP), - segment_name (S_GET_SEGMENT (add_symbolP)), - S_GET_NAME (sub_symbolP), - segment_name (S_GET_SEGMENT (sub_symbolP)), - buf); - } + /* Do this for m68k even if it's already described + as pc-relative. On the m68k, an operand of + "pc@(foo-.-2)" should address "foo" in a + pc-relative mode. */ + || 1 +#endif + || !fixP->fx_pcrel) + add_number += MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_subsy = NULL; + fixP->fx_pcrel = 1; + } + else if (!TC_VALIDATE_FIX_SUB (fixP)) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("can't resolve `%s' {%s section} - `%s' {%s section}"), + fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0", + segment_name (add_symbol_segment), + S_GET_NAME (fixP->fx_subsy), + segment_name (sub_symbol_segment)); } } - if (add_symbolP) + if (fixP->fx_addsy) { - if (add_symbol_segment == this_segment && pcrel && !plt - && TC_RELOC_RTSYM_LOC_FIXUP (fixP)) + if (add_symbol_segment == this_segment + && !TC_FORCE_RELOCATION_LOCAL (fixP)) { /* This fixup was made when the symbol's segment was SEG_UNKNOWN, but it is now in the local segment. So we know how to do the address without relocation. */ -#ifdef TC_I960 - /* reloc_callj() may replace a 'call' with a 'calls' or a - 'bal', in which cases it modifies *fixP as appropriate. - In the case of a 'calls', no further work is required, - and *fixP has been set up to make the rest of the code - below a no-op. */ - reloc_callj (fixP); -#endif /* TC_I960 */ - - add_number += S_GET_VALUE (add_symbolP); - add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); - /* Lie. Don't want further pcrel processing. */ - pcrel = 0; - - /* Let the target machine make the final determination - as to whether or not a relocation will be needed to - handle this fixup. */ - if (!TC_FORCE_RELOCATION (fixP)) - { - fixP->fx_pcrel = 0; - fixP->fx_addsy = NULL; - } + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + if (fixP->fx_pcrel) + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_addsy = NULL; + fixP->fx_pcrel = 0; } - else + else if (add_symbol_segment == absolute_section + && !TC_FORCE_RELOCATION_ABS (fixP)) { - if (add_symbol_segment == absolute_section - && ! pcrel) - { -#ifdef TC_I960 - /* See comment about reloc_callj() above. */ - reloc_callj (fixP); -#endif /* TC_I960 */ - add_number += S_GET_VALUE (add_symbolP); - - /* Let the target machine make the final determination - as to whether or not a relocation will be needed to - handle this fixup. */ - - if (!TC_FORCE_RELOCATION (fixP)) - { - fixP->fx_addsy = NULL; - add_symbolP = NULL; - } - } - else if (add_symbol_segment == undefined_section + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + fixP->fx_addsy = NULL; + } + else if (add_symbol_segment != undefined_section #ifdef BFD_ASSEMBLER - || bfd_is_com_section (add_symbol_segment) + && ! bfd_is_com_section (add_symbol_segment) #endif - ) - { -#ifdef TC_I960 - if ((int) fixP->fx_bit_fixP == 13) - { - /* This is a COBR instruction. They have only a - 13-bit displacement and are only to be used - for local branches: flag as error, don't generate - relocation. */ - as_bad_where (fixP->fx_file, fixP->fx_line, - _("can't use COBR format with external label")); - fixP->fx_addsy = NULL; - fixP->fx_done = 1; - continue; - } /* COBR. */ -#endif /* TC_I960 */ - -#ifdef OBJ_COFF -#ifdef TE_I386AIX - if (S_IS_COMMON (add_symbolP)) - add_number += S_GET_VALUE (add_symbolP); -#endif /* TE_I386AIX */ -#endif /* OBJ_COFF */ - ++seg_reloc_count; - } - else - { - seg_reloc_count++; - if (TC_FIX_ADJUSTABLE (fixP)) - add_number += S_GET_VALUE (add_symbolP); - } - } + && MD_APPLY_SYM_VALUE (fixP)) + add_number += S_GET_VALUE (fixP->fx_addsy); } - if (pcrel) + if (fixP->fx_pcrel) { add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); - if (add_symbolP == 0) + if (!fixP->fx_done && fixP->fx_addsy == NULL) { -#ifndef BFD_ASSEMBLER - fixP->fx_addsy = &abs_symbol; -#else - fixP->fx_addsy = section_symbol (absolute_section); -#endif - symbol_mark_used_in_reloc (fixP->fx_addsy); - ++seg_reloc_count; + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; } } if (!fixP->fx_done) md_apply_fix3 (fixP, &add_number, this_segment); + if (!fixP->fx_done) + { + ++seg_reloc_count; + if (fixP->fx_addsy == NULL) + fixP->fx_addsy = abs_section_sym; + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + } + if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0) { if (fixP->fx_size < sizeof (valueT)) diff --git a/gas/write.h b/gas/write.h index 451215d7e81..3a3b5856530 100644 --- a/gas/write.h +++ b/gas/write.h @@ -158,6 +158,7 @@ struct fix typedef struct fix fixS; extern int finalize_syms; +extern symbolS *abs_section_sym; #ifndef BFD_ASSEMBLER extern char *next_object_file_charP; -- 2.30.2