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


Hi!

This is a x86-64 version of my 2003-11-22 patch which was i386 only.
I believe compiler generated code will never depend on pointer equality
if it uses R_X86_64_PC32 or R_X86_64_PLT32 relocations.
In hand written assembly one can certainly use:
leaq foo(%rip), %rax
or .long foo-.
and then compare pointers, but there is no reason to do that
(in -fno-pic code mov $foo, %eax is shorter, in -mcmodel=medium
movabsq $foo, %rax is generated and in -fpic code, given that
foo is known not to be in the same executable or shared library
as the instruction, a GOTPCREL relocation is created instead).
Ok to commit?

2004-04-22  Jakub Jelinek  <jakub@redhat.com>

	* elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Copy also
	ELF_LINK_POINTER_EQUALITY_NEEDED.
	(elf64_x86_64_check_relocs): Set ELF_LINK_POINTER_EQUALITY_NEEDED
	if r_type is not R_X86_64_PC32.
	(elf64_x86_64_finish_dynamic_symbol): If
	ELF_LINK_POINTER_EQUALITY_NEEDED is not set, clear st_value of
	SHN_UNDEF symbols.

--- bfd/elf64-x86-64.c.jj	2004-04-22 16:40:52.000000000 +0200
+++ bfd/elf64-x86-64.c	2004-04-22 17:09:23.662915096 +0200
@@ -561,7 +561,8 @@ elf64_x86_64_copy_indirect_symbol (const
       (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
 				   | ELF_LINK_HASH_REF_REGULAR
 				   | ELF_LINK_HASH_REF_REGULAR_NONWEAK
-				   | ELF_LINK_HASH_NEEDS_PLT));
+				   | ELF_LINK_HASH_NEEDS_PLT
+				   | ELF_LINK_POINTER_EQUALITY_NEEDED));
   else
     _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
@@ -812,6 +813,8 @@ elf64_x86_64_check_relocs (bfd *abfd, st
 	      /* 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_X86_64_PC32)
+		h->elf_link_hash_flags |= ELF_LINK_POINTER_EQUALITY_NEEDED;
 	    }
 
 	  /* If we are creating a shared library, and this is a reloc
@@ -2519,11 +2522,16 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
       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]