Keep a reloc for jumps to weak and external symbols.
authorAlan Modra <amodra@gmail.com>
Mon, 22 May 2000 11:38:43 +0000 (11:38 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 22 May 2000 11:38:43 +0000 (11:38 +0000)
gas/ChangeLog
gas/config/tc-i386.c

index a03ab1294b2517040df9ede53a89cbe8d5f83fe4..d9aabdd5a6b630ab3b4b9bde68cc696bf7b950bc 100644 (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>
 
        * stabs.c (aout_process_stab): Make global.
index b131e41abf261c854a20dc8fd3b973a83877f4b1..64a2797040f0e2dd167528cfc619c928e76be95c 100644 (file)
@@ -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;