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] RFC: Clearing st_value of PLT SHN_UNDEF symbols if pointer equality not needed


Hi!

If some function is only called from the binary and its address is never
taken, ld unnecessarily pessimizes code.
Say shared library has:
int foo () { return 1; }
int bar () { return 2; }
void *ptrs[] = { foo, bar };
and binary has:
extern int foo (), bar ();
void *ptr = foo;
int main (void) { foo (); bar (); return 0; }
In this case, both ptrs[] members point to PLT slots in the binary.
This is necessary for foo pointer, but certainly not for bar, as its
address is never taken in the binary.  There is just call bar
(or call bar@plt) in the binary.
The code assumes that all R_386_PLT32 and R_386_PC32 relocs don't need
pointer equality while other relocs need it.  Although one can hack up
assembly which would take care about pointer equality even with these
relocs, I don't think ld needs to support that.
What do you think?

2003-11-17  Jakub Jelinek  <jakub@redhat.com>

	* elf-bfd.h (ELF_LINK_POINTER_EQUALITY_NEEDED): Define new flag.
	* elf.c (_bfd_elf_link_hash_copy_indirect): Copy it.
	* elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
	(elf_i386_check_relocs): Set it.
	(elf_i386_finish_dynamic_symbol): If it is not set,
	clear st_value of SHN_UNDEF symbol.

--- bfd/elf-bfd.h.jj	2003-11-17 09:20:51.000000000 +0100
+++ bfd/elf-bfd.h	2003-11-17 09:32:59.000000000 +0100
@@ -200,6 +200,9 @@ struct elf_link_hash_entry
 #define ELF_LINK_DYNAMIC_DEF 020000
   /* Symbol is weak in all shared objects.  */
 #define ELF_LINK_DYNAMIC_WEAK 040000
+  /* Symbol is referenced with a relocation where C/C++ pointer equality
+     matters.  */
+#define ELF_LINK_POINTER_EQUALITY_NEEDED 0100000
 };
 
 /* Will references to this symbol always reference the symbol
--- bfd/elf.c.jj	2003-11-17 09:20:55.000000000 +0100
+++ bfd/elf.c	2003-11-17 10:04:04.000000000 +0100
@@ -1359,7 +1359,8 @@ _bfd_elf_link_hash_copy_indirect (const 
      & (ELF_LINK_HASH_REF_DYNAMIC
 	| ELF_LINK_HASH_REF_REGULAR
 	| ELF_LINK_HASH_REF_REGULAR_NONWEAK
-	| ELF_LINK_NON_GOT_REF));
+	| ELF_LINK_NON_GOT_REF
+	| ELF_LINK_POINTER_EQUALITY_NEEDED));
 
   if (ind->root.type != bfd_link_hash_indirect)
     return;
--- bfd/elf32-i386.c.jj	2003-11-17 09:20:58.000000000 +0100
+++ bfd/elf32-i386.c	2003-11-17 10:02:59.000000000 +0100
@@ -770,7 +770,8 @@ elf_i386_copy_indirect_symbol (const str
     dir->elf_link_hash_flags |=
       (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
 				   | ELF_LINK_HASH_REF_REGULAR
-				   | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+				   | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+				   | ELF_LINK_POINTER_EQUALITY_NEEDED));
   else
     _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
@@ -1000,6 +1001,8 @@ elf_i386_check_relocs (bfd *abfd,
 	      /* We may need a .plt entry if the function this reloc
 		 refers to is in a shared lib.  */
 	      h->plt.refcount += 1;
+	      if (r_type != R_386_PC32)
+		h->elf_link_hash_flags |= ELF_LINK_POINTER_EQUALITY_NEEDED;
 	    }
 
 	  /* If we are creating a shared library, and this is a reloc
@@ -3003,11 +3006,16 @@ elf_i386_finish_dynamic_symbol (bfd *out
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
 	{
 	  /* Mark the symbol as undefined, rather than as defined in
-	     the .plt section.  Leave the value alone.  This is a clue
+	     the .plt section.  Leave the value if there were any
+	     relocations where pointer equality matters (this is a clue
 	     for the dynamic linker, to make function pointer
 	     comparisons work between an application and shared
-	     library.  */
+	     library), otherwise set it to zero.  If a function is only
+	     called from a binary, there is no need to slow down
+	     shared libraries because of that.  */
 	  sym->st_shndx = SHN_UNDEF;
+	  if ((h->elf_link_hash_flags & ELF_LINK_POINTER_EQUALITY_NEEDED) == 0)
+	    sym->st_value = 0;
 	}
     }
 

	Jakub


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