This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: A very "strange" bug in gcc 2.96


The folowing patch should fix this x86 gas bug for x86.  x86 looks to
be the only architecture affected.

I committed it to the trunk, and it should probably go to the 2.10 branch
too.  I'll give you a chance to fire off any unfavourable comments before
doing so.

Regards, Alan Modra
-- 
Linuxcare.  Support for the Revolution.

gas/ChangeLog
	* 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.

Index: config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.49
diff -u -p -r1.49 tc-i386.c
--- tc-i386.c	2000/05/13 12:49:55	1.49
+++ tc-i386.c	2000/05/22 11:29:46
@@ -1023,13 +1023,12 @@ 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))
+  if (S_IS_EXTERNAL (fixP->fx_addsy)
+      || S_IS_WEAK (fixP->fx_addsy))
     return 0;
-  if (S_IS_WEAK (fixP->fx_addsy))
-    return 0;
 #endif
   /* adjust_reloc_syms doesn't know about the GOT */
   if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
@@ -3765,12 +3764,19 @@ md_estimate_size_before_relax (fragP, se
   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)
-    {
-      /* symbol is undefined in this segment */
-      int code16 = fragP->fr_subtype & CODE16;
-      int size = code16 ? 2 : 4;
+     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, 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, se
 			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;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]