diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | bfd/elf.c | 3 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 14 |
4 files changed, 25 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 69d676f..9010d72 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2003-11-22 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. + 2003-11-20 Jim Blandy <jimb@redhat.com> * cpu-powerpc.c (powerpc_compatible): Any ISA in the PowerPC diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d5965d3..5cb7efa 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 @@ -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 9814543..8adaa0f 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; } } |