aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf-bfd.h3
-rw-r--r--bfd/elf.c3
-rw-r--r--bfd/elf32-i386.c14
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
diff --git a/bfd/elf.c b/bfd/elf.c
index e6965af..31003d7 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 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;
}
}