This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: A very "strange" bug in gcc 2.96
- To: "H . J . Lu" <hjl at lucon dot org>
- Subject: Re: A very "strange" bug in gcc 2.96
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Mon, 22 May 2000 22:06:10 +1000 (EST)
- cc: Ian Lance Taylor <ian at zembu dot com>, "Eric W. Biederman" <eric at biederman dot org>, Ulrich Drepper <drepper at redhat dot com>, Andreas Schwab <schwab at suse dot de>, Geoff Keating <geoffk at cygnus dot com>, Mark Mitchell <mark at codesourcery dot com>, egcs at egcs dot cygnus dot com, binutils at sourceware dot cygnus dot com
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;