diff options
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 26 |
2 files changed, 23 insertions, 10 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a03ab12..d9aabdd 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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> * stabs.c (aout_process_stab): Make global. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index b131e41..64a2797 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1023,12 +1023,11 @@ int tc_i386_fix_adjustable (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 linking will not work correctly. */ - if (S_IS_EXTERN (fixP->fx_addsy)) - return 0; - if (S_IS_WEAK (fixP->fx_addsy)) + if (S_IS_EXTERNAL (fixP->fx_addsy) + || S_IS_WEAK (fixP->fx_addsy)) return 0; #endif /* 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; opcode = (unsigned char *) fragP->fr_opcode; /* We've already got fragP->fr_subtype right; all we have to do is - check for un-relaxable symbols. */ - if (S_GET_SEGMENT (fragP->fr_symbol) != segment) + check for un-relaxable symbols. On an ELF system, we can't relax + 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 */ - int code16 = fragP->fr_subtype & CODE16; - int size = code16 ? 2 : 4; + /* Symbol is undefined in this segment, or we need to keep a + reloc so that weak symbols can be overridden. */ + int size = (fragP->fr_subtype & CODE16) ? 2 : 4; #ifdef BFD_ASSEMBLER enum bfd_reloc_code_real reloc_type; #else @@ -3785,7 +3791,7 @@ md_estimate_size_before_relax (fragP, segment) most of the time. ERY */ && S_GET_SEGMENT(fragP->fr_symbol) == undefined_section) reloc_type = BFD_RELOC_386_PLT32; - else if (code16) + else if (size == 2) reloc_type = BFD_RELOC_16_PCREL; else reloc_type = BFD_RELOC_32_PCREL; |