aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2000-05-22 11:38:43 +0000
committerAlan Modra <amodra@gmail.com>2000-05-22 11:38:43 +0000
commitb98ef1471759a163fe92ed584e01df9a2505cca9 (patch)
treec3b439120b6537d14b59f4b869552884d1e87607
parent74b7792f0fcae41f7c7da524527b7261a3fd68c4 (diff)
downloadgdb-b98ef1471759a163fe92ed584e01df9a2505cca9.zip
gdb-b98ef1471759a163fe92ed584e01df9a2505cca9.tar.gz
gdb-b98ef1471759a163fe92ed584e01df9a2505cca9.tar.bz2
Keep a reloc for jumps to weak and external symbols.
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-i386.c26
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;