This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] i386: resolve references to hidden/internal globalsymbols internally
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Thu, 03 Jun 2004 17:09:17 +0200
- Subject: [PATCH] i386: resolve references to hidden/internal globalsymbols internally
Since these can't be overridden, retaining externally visible references
to them is useless. Eliminating them on x86 and x86-64 permits short
jumps to be used in place of full-width ones, and could also help
suppress emission of non-conforming relocation types (if the intended
generic part of the change wouldn't have side effects that required me
to disable it again). Built and regression tested on i686-pc-linux-gnu
and x86_64-unknown-linux-gnu.
2004-06-03 Jan Beulich <jbeulich@novell.com>
* gas/symbols.c: There would be no need to keep references to
internal
or hidden symbols in S_FORCE_RELOC, if the callers protected
themselves against discarding relocations with side effects.
* gas/config/tc-i386.c: Same for md_estimate_size_before_relax.
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/config/tc-i386.c 2004-04-20
14:17:14.000000000 +0200
+++ 2004-06-03.09.12/gas/config/tc-i386.c 2004-06-03
10:22:33.663347560 +0200
@@ -4380,6 +4380,20 @@
fragS *fragP;
segT segment;
{
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ elf_symbol_type *elfsym;
+
+ if (IS_ELF && S_IS_EXTERNAL (fragP->fr_symbol))
+ {
+ asymbol *bfdsym = symbol_get_bfdsym (fragP->fr_symbol);
+
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+ assert (elfsym);
+ }
+ else
+ elfsym = NULL;
+#endif
+
/* We've already got fragP->fr_subtype right; all we have to do is
check for un-relaxable symbols. On an ELF system, we can't
relax
an externally visible symbol, because it may be overridden by a
@@ -4387,7 +4401,9 @@
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|| (OUTPUT_FLAVOR == bfd_target_elf_flavour
- && (S_IS_EXTERNAL (fragP->fr_symbol)
+ && ((S_IS_EXTERNAL (fragP->fr_symbol)
+ && elfsym->internal_elf_sym.st_other != STV_HIDDEN
+ && elfsym->internal_elf_sym.st_other != STV_INTERNAL)
|| S_IS_WEAK (fragP->fr_symbol)))
#endif
)
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/symbols.c 2004-05-11
17:53:47.000000000 +0200
+++ 2004-06-03.09.12/gas/symbols.c 2004-06-03 17:02:00.303864392
+0200
@@ -1772,13 +1772,44 @@
int
S_FORCE_RELOC (symbolS *s, int strict)
{
+#if 0/*defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)*/
+ While generally correct, this and the similarly framed code
fragments
+ below cause, if enabled, relocations to be dropped that should not
be (i.e.
+ BFD_RELOC_X86_64_GOTPCREL) because the side effects of using a
certain
+ relocation type is not accounted for in generic_force_reloc (in
write.c)
+ except for the vtable relocations. GOT references, at least, would
have
+ to fall into this category, too, but there does not seem to be a
flag in
+ struct fix to indicate such side effects (maybe fx_plt really is,
but then
+ it is grossly misnamed), nor does it seem reasonable to enumerate
all such
+ relocations in generic_force_reloc.
+ elf_symbol_type *elfsym;
+#endif
+
if (LOCAL_SYMBOL_CHECK (s))
return ((struct local_symbol *) s)->lsy_section ==
undefined_section;
+#if 0/*defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)*/
+ if (IS_ELF && (s->bsym->flags & BSF_GLOBAL))
+ {
+ asymbol *bfdsym = symbol_get_bfdsym (s);
+
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+ assert (elfsym);
+ }
+ else
+ elfsym = NULL;
+#endif
+
return ((strict
&& ((s->bsym->flags & BSF_WEAK) != 0
|| (EXTERN_FORCE_RELOC
- && (s->bsym->flags & BSF_GLOBAL) != 0)))
+ && (s->bsym->flags & BSF_GLOBAL) != 0
+#if 0/*defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)*/
+ && (elfsym == NULL
+ || (elfsym->internal_elf_sym.st_other !=
STV_HIDDEN
+ && elfsym->internal_elf_sym.st_other !=
STV_INTERNAL))
+#endif
+ )))
|| s->bsym->section == undefined_section
|| bfd_is_com_section (s->bsym->section));
}