From a161fe53205dbc69d42f5a123b2b04346724b2de Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 5 Sep 2002 00:01:18 +0000 Subject: gas reloc rewrite. --- gas/config/tc-sh.h | 97 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 33 deletions(-) (limited to 'gas/config/tc-sh.h') diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index ffe948a..6ff45c8 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)) -- cgit v1.1