Keep a reloc for jumps to weak and external symbols.

This commit is contained in:
Alan Modra
2000-05-22 11:38:43 +00:00
parent 74b7792f0f
commit b98ef14717
2 changed files with 23 additions and 10 deletions

View File

@ -1,3 +1,10 @@
2000-05-22 Alan Modra <alan@linuxcare.com.au>
* config/tc-i386.c (tc_i386_fix_adjustable): Prevent adjustment
for OBJ_MAYBE_ELF too. Use S_IS_EXTERNAL instead of S_IS_EXTERN.
(md_estimate_size_before_relax): Ensure jumps to weak and
externally visible symbols are relocatable.
Sat May 20 16:41:55 2000 Hans-Peter Nilsson <hp@axis.com> Sat May 20 16:41:55 2000 Hans-Peter Nilsson <hp@axis.com>
* stabs.c (aout_process_stab): Make global. * stabs.c (aout_process_stab): Make global.

View File

@ -1023,12 +1023,11 @@ int
tc_i386_fix_adjustable (fixP) tc_i386_fix_adjustable (fixP)
fixS *fixP; fixS *fixP;
{ {
#if defined (OBJ_ELF) || defined (TE_PE) #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (TE_PE)
/* Prevent all adjustments to global symbols, or else dynamic /* Prevent all adjustments to global symbols, or else dynamic
linking will not work correctly. */ linking will not work correctly. */
if (S_IS_EXTERN (fixP->fx_addsy)) if (S_IS_EXTERNAL (fixP->fx_addsy)
return 0; || S_IS_WEAK (fixP->fx_addsy))
if (S_IS_WEAK (fixP->fx_addsy))
return 0; return 0;
#endif #endif
/* adjust_reloc_syms doesn't know about the GOT */ /* adjust_reloc_syms doesn't know about the GOT */
@ -3765,12 +3764,19 @@ md_estimate_size_before_relax (fragP, segment)
old_fr_fix = fragP->fr_fix; old_fr_fix = fragP->fr_fix;
opcode = (unsigned char *) fragP->fr_opcode; opcode = (unsigned char *) fragP->fr_opcode;
/* We've already got fragP->fr_subtype right; all we have to do is /* We've already got fragP->fr_subtype right; all we have to do is
check for un-relaxable symbols. */ check for un-relaxable symbols. On an ELF system, we can't relax
if (S_GET_SEGMENT (fragP->fr_symbol) != segment) an externally visible symbol, because it may be overridden by a
shared library. */
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (TE_PE)
|| S_IS_EXTERNAL (fragP->fr_symbol)
|| S_IS_WEAK (fragP->fr_symbol)
#endif
)
{ {
/* symbol is undefined in this segment */ /* Symbol is undefined in this segment, or we need to keep a
int code16 = fragP->fr_subtype & CODE16; reloc so that weak symbols can be overridden. */
int size = code16 ? 2 : 4; int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
#ifdef BFD_ASSEMBLER #ifdef BFD_ASSEMBLER
enum bfd_reloc_code_real reloc_type; enum bfd_reloc_code_real reloc_type;
#else #else
@ -3785,7 +3791,7 @@ md_estimate_size_before_relax (fragP, segment)
most of the time. ERY */ most of the time. ERY */
&& S_GET_SEGMENT(fragP->fr_symbol) == undefined_section) && S_GET_SEGMENT(fragP->fr_symbol) == undefined_section)
reloc_type = BFD_RELOC_386_PLT32; reloc_type = BFD_RELOC_386_PLT32;
else if (code16) else if (size == 2)
reloc_type = BFD_RELOC_16_PCREL; reloc_type = BFD_RELOC_16_PCREL;
else else
reloc_type = BFD_RELOC_32_PCREL; reloc_type = BFD_RELOC_32_PCREL;