This is the mail archive of the binutils@sources.redhat.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]
Other format: [Raw text]

[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));
 }


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