From c6585bbb101d8e377478a01b64d75d9d415dbd01 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 22 Nov 2003 10:45:44 +0000 Subject: [PATCH] 2003-11-22 Jakub Jelinek * 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/ChangeLog | 9 +++++++++ bfd/elf-bfd.h | 3 +++ bfd/elf.c | 3 ++- bfd/elf32-i386.c | 14 +++++++++++--- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 69d676ff31..9010d72188 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2003-11-22 Jakub Jelinek + + * 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. + 2003-11-20 Jim Blandy * cpu-powerpc.c (powerpc_compatible): Any ISA in the PowerPC diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d5965d3ffb..5cb7efaa17 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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 diff --git a/bfd/elf.c b/bfd/elf.c index e6965af375..31003d7508 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1359,7 +1359,8 @@ _bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed, | ELF_LINK_HASH_REF_REGULAR | ELF_LINK_HASH_REF_REGULAR_NONWEAK | ELF_LINK_NON_GOT_REF - | ELF_LINK_HASH_NEEDS_PLT)); + | ELF_LINK_HASH_NEEDS_PLT + | ELF_LINK_POINTER_EQUALITY_NEEDED)); if (ind->root.type != bfd_link_hash_indirect) return; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 9814543e96..8adaa0faac 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -771,7 +771,8 @@ elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed, (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); } @@ -1001,6 +1002,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 @@ -3004,11 +3007,16 @@ elf_i386_finish_dynamic_symbol (bfd *output_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; } }