diff options
author | Alan Modra <amodra@gmail.com> | 2014-12-12 22:53:46 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-12-12 23:35:50 +1030 |
commit | 6cabe1ea460c54c17ac877b2541eccf91d6b4b9c (patch) | |
tree | 84b29c5ddba5350b966e8bb9a2b97b2914579caa /bfd/elflink.c | |
parent | 21daaaaffcbda47b724858dd99ee2082043ef2da (diff) | |
download | binutils-6cabe1ea460c54c17ac877b2541eccf91d6b4b9c.zip binutils-6cabe1ea460c54c17ac877b2541eccf91d6b4b9c.tar.gz binutils-6cabe1ea460c54c17ac877b2541eccf91d6b4b9c.tar.bz2 |
Copy relocations against protected symbols
Copy relocs are used in a scheme to avoid dynamic text relocations in
non-PIC executables that refer to variables defined in shared
libraries. The idea is to have the linker define any such variable in
the executable, with a copy reloc copying the initial value, then have
both the executable and shared library refer to the executable copy.
If the shared library defines the variable as protected then we have
two copies of the variable being used.
PR 15228
* elflink.c (_bfd_elf_adjust_dynamic_copy): Add "info" param.
Error on copy relocs against protected symbols.
(elf_merge_st_other): Set h->protected_def.
* elf-bfd.h (struct elf_link_hash_entry): Add "protected_def".
(_bfd_elf_adjust_dynamic_copy): Update prototype.
* elf-m10300.c (_bfd_mn10300_elf_adjust_dynamic_symbol): Update
_bfd_elf_adjust_dynamic_copy call.
* elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Likewise.
* elf32-cr16.c (_bfd_cr16_elf_adjust_dynamic_symbol): Likewise.
* elf32-cris.c (elf_cris_adjust_dynamic_symbol): Likewise.
* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
* elf32-i370.c (i370_elf_adjust_dynamic_symbol): Likewise.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
* elf32-lm32.c (lm32_elf_adjust_dynamic_symbol): Likewise.
* elf32-m32r.c (m32r_elf_adjust_dynamic_symbol): Likewise.
* elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
* elf32-metag.c (elf_metag_adjust_dynamic_symbol): Likewise.
* elf32-or1k.c (or1k_elf_adjust_dynamic_symbol): Likewise.
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
* elf32-sh.c (sh_elf_adjust_dynamic_symbol): Likewise.
* elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol): Likewise.
* elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol): Likewise.
* elf32-vax.c (elf_vax_adjust_dynamic_symbol): Likewise.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
* elf64-sh64.c (sh64_elf64_adjust_dynamic_symbol): Likewise.
* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
* elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol): Likewise.
* elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
* elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol): Likewise.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index b023ec5..a01daf2 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -873,6 +873,8 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, if (symvis - 1 < hvis - 1) h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1)); } + else if (definition && ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT) + h->protected_def = 1; } /* This function is called when we want to merge a new symbol with an @@ -2637,7 +2639,8 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) DYNBSS. */ bfd_boolean -_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h, +_bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info, + struct elf_link_hash_entry *h, asection *dynbss) { unsigned int power_of_two; @@ -2676,6 +2679,14 @@ _bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h, /* Increment the size of DYNBSS to make room for the symbol. */ dynbss->size += h->size; + if (h->protected_def) + { + info->callbacks->einfo + (_("%P: copy reloc against protected `%T' is invalid\n"), + h->root.root.string); + return FALSE; + } + return TRUE; } |