From 335d35c8bc7d8983c69b2e1502d5db61f992b3f4 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 30 Nov 1993 21:43:15 +0000 Subject: [PATCH] * write.c (TC_FORCE_RELOCATION): Provide a default definition. (fixup_segment): Allow the target machine to specify that a relocation must be generated for a particular fixup. Remove #ifndef TC_HPPA hack. * config/tc-hppa.h (TC_FORCE_RELOCATION): Define. * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to be NULL. Only fixup_segment is supposed to do that. (hppa_force_relocation): New function. --- gas/ChangeLog | 13 +++++ gas/config/tc-hppa.c | 35 +++++++++++- gas/write.c | 125 ++++++++++++++++++++++++------------------- 3 files changed, 117 insertions(+), 56 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index be9da7498ac..22dd3cb765d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +Tue Nov 30 13:40:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * write.c (TC_FORCE_RELOCATION): Provide a default definition. + (fixup_segment): Allow the target machine to specify that a + relocation must be generated for a particular fixup. Remove + #ifndef TC_HPPA hack. + + * config/tc-hppa.h (TC_FORCE_RELOCATION): Define. + + * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to + be NULL. Only fixup_segment is supposed to do that. + (hppa_force_relocation): New function. + Tue Nov 30 11:21:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * Makefile.in (stabs.o): Added dependencies. diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index e588ca89abc..6ee3ac2bc92 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -3102,7 +3102,6 @@ md_apply_fix_1 (fixP, val) dis_assemble_12 (result, &w1, &w); result = ((w1 << 2) | w); - fixP->fx_addsy = NULL; break; #define stub_needed(CALLER, CALLEE) \ @@ -3129,7 +3128,6 @@ md_apply_fix_1 (fixP, val) sign_unext ((new_val - 8) >> 2, 17, &result); dis_assemble_17 (result, &w1, &w2, &w); result = ((w2 << 2) | (w1 << 16) | w); - fixP->fx_addsy = NULL; break; #undef too_far @@ -6346,6 +6344,39 @@ hppa_fix_adjustable (fixp) return 0; } +/* Return nonzero if the fixup in FIXP will require a relocation, + even it if appears that the fixup could be completely handled + within GAS. */ + +int +hppa_force_relocation (fixp) + fixS *fixp; +{ + struct hppa_fix_struct *hppa_fixp = fixp->tc_fix_data; + +#ifdef OBJ_SOM + if (fixp->fx_r_type == R_HPPA_ENTRY || fixp->fx_r_type == R_HPPA_EXIT) + return 1; +#endif + +#define stub_needed(CALLER, CALLEE) \ + ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) + + /* It is necessary to force PC-relative calls/jumps to have a relocation + entry if they're going to need either a argument relocation or long + call stub. FIXME. Can't we need the same for absolute calls? */ + if (fixp->fx_pcrel + && (stub_needed (((obj_symbol_type *) + fixp->fx_addsy->bsym)->tc_data.hppa_arg_reloc, + hppa_fixp->fx_arg_reloc))) + return 1; + +#undef stub_needed + + /* No need (yet) to force another relocations to be emitted. */ + return 0; +} + /* Now for some ELF specific code. FIXME. */ #ifdef OBJ_ELF static symext_chainS *symext_rootP; diff --git a/gas/write.c b/gas/write.c index f27b5e1b2f9..9e0ba8ed46d 100644 --- a/gas/write.c +++ b/gas/write.c @@ -30,6 +30,10 @@ #define NOP_OPCODE 0x00 #endif +#ifndef TC_FORCE_RELOCATION +#define TC_FORCE_RELOCATION(FIXP) 0 +#endif + #ifndef WORKING_DOT_WORD extern CONST int md_short_jump_size; extern CONST int md_long_jump_size; @@ -638,9 +642,7 @@ write_relocs (abfd, sec, xxx) if (fixp->fx_where + fixp->fx_size > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset) abort (); - /* Pass bogus address so that when bfd_perform_relocation adds - `address' back in, it'll come up with `data', which is where - we want it to operate. */ + if (reloc->howto->partial_inplace == false && reloc->howto->pcrel_offset == true && reloc->howto->pc_relative == true) @@ -648,6 +650,9 @@ write_relocs (abfd, sec, xxx) /* bfd_perform_relocation screws this up */ reloc->addend += reloc->address; } + /* Pass bogus address so that when bfd_perform_relocation adds + `address' back in, it'll come up with `data', which is where + we want it to operate. */ s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address, sec, stdoutput); switch (s) @@ -1288,10 +1293,6 @@ write_object_file () #endif /* VMS */ #else /* BFD_ASSEMBLER */ -#ifdef obj_check_file_symbols - obj_check_file_symbols (); -#endif - bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *)0); /* Set up symbol table, and write it out. */ @@ -1329,60 +1330,58 @@ write_object_file () symp->bsym->flags, segment_name (symp->bsym->section)); #endif - if (! symp->sy_used_in_reloc) - { + #ifdef obj_frob_symbol - { - int punt = 0; - obj_frob_symbol (symp, punt); - if (punt) - goto punt_it; - } + { + int punt = 0; + obj_frob_symbol (symp, punt); + if (punt) + goto punt_it; + } #endif #ifdef tc_frob_symbol - { - int punt = 0; - tc_frob_symbol (symp, punt); - if (punt) - goto punt_it; - } + { + int punt = 0; + tc_frob_symbol (symp, punt); + if (punt) + goto punt_it; + } #endif - } /* If we don't want to keep this symbol, splice it out of the chain now. */ - if (! symp->sy_used_in_reloc - && S_IS_LOCAL (symp)) + if (S_IS_LOCAL (symp)) { - symbolS *prev, *next; -#if defined (obj_frob_symbol) || defined (tc_frob_symbol) punt_it: -#endif - prev = symbol_previous (symp); - next = symbol_next (symp); + if (! symp->sy_used_in_reloc) + { + symbolS *prev, *next; + prev = symbol_previous (symp); + next = symbol_next (symp); #ifdef DEBUG_SYMS - verify_symbol_chain_2 (symp); + verify_symbol_chain_2 (symp); #endif - if (prev) - { - symbol_next (prev) = next; - symp = prev; - } - else if (symp == symbol_rootP) - symbol_rootP = next; - else - abort (); - if (next) - symbol_previous (next) = prev; - else - symbol_lastP = prev; + if (prev) + { + symbol_next (prev) = next; + symp = prev; + } + else if (symp == symbol_rootP) + symbol_rootP = next; + else + abort (); + if (next) + symbol_previous (next) = prev; + else + symbol_lastP = prev; #ifdef DEBUG_SYMS - if (prev) - verify_symbol_chain_2 (prev); - else if (next) - verify_symbol_chain_2 (next); + if (prev) + verify_symbol_chain_2 (prev); + else if (next) + verify_symbol_chain_2 (next); #endif - continue; + continue; + } } /* Make sure we really got a value for the symbol. */ @@ -1896,7 +1895,12 @@ fixup_segment (fixP, this_segment_type) S_GET_VALUE (sub_symbolP); add_symbolP = NULL; - fixP->fx_addsy = NULL; + + /* 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; } else { @@ -1960,9 +1964,12 @@ fixup_segment (fixP, this_segment_type) add_number += S_GET_VALUE (add_symbolP); add_number -= md_pcrel_from (fixP); pcrel = 0; /* Lie. Don't want further pcrel processing. */ -#ifndef TC_HPPA - fixP->fx_addsy = NULL; /* No relocations please. */ -#endif + + /* 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; } else { @@ -1973,7 +1980,12 @@ fixup_segment (fixP, this_segment_type) reloc_callj (fixP); #endif /* TC_I960 */ add_number += S_GET_VALUE (add_symbolP); - fixP->fx_addsy = NULL; + + /* 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 @@ -1991,7 +2003,12 @@ fixup_segment (fixP, this_segment_type) * relocation. */ as_bad ("can't use COBR format with external label"); - fixP->fx_addsy = NULL; /* No relocations please. */ + + /* 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; continue; } /* COBR */ #endif /* TC_I960 */ -- 2.30.2