Copy relocations against protected symbols
authorAlan Modra <amodra@gmail.com>
Fri, 12 Dec 2014 12:23:46 +0000 (22:53 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 12 Dec 2014 13:05:50 +0000 (23:35 +1030)
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.

29 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf-m10300.c
bfd/elf32-arm.c
bfd/elf32-cr16.c
bfd/elf32-cris.c
bfd/elf32-hppa.c
bfd/elf32-i370.c
bfd/elf32-i386.c
bfd/elf32-lm32.c
bfd/elf32-m32r.c
bfd/elf32-m68k.c
bfd/elf32-metag.c
bfd/elf32-or1k.c
bfd/elf32-ppc.c
bfd/elf32-s390.c
bfd/elf32-sh.c
bfd/elf32-tic6x.c
bfd/elf32-tilepro.c
bfd/elf32-vax.c
bfd/elf64-ppc.c
bfd/elf64-s390.c
bfd/elf64-sh64.c
bfd/elf64-x86-64.c
bfd/elflink.c
bfd/elfnn-aarch64.c
bfd/elfxx-mips.c
bfd/elfxx-sparc.c
bfd/elfxx-tilegx.c

index 9443507f243fe9935958bb5e8929907541633a30..0db2820ed7b9cfdc25325834f3ca89e861162441 100644 (file)
@@ -1,3 +1,39 @@
+2014-12-12  Alan Modra  <amodra@gmail.com>
+
+       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.
+
 2014-12-11  Keith Seitz  <keiths@redhat.com>
 
        * elf.c (elf_parse_notes): Define convenience macro
index 6ce70bcf8c6f7a31da6aadcff065577e8c4913d6..5e53cbab060223fece46675f25a157169df9c375 100644 (file)
@@ -196,6 +196,8 @@ struct elf_link_hash_entry
   unsigned int pointer_equality_needed : 1;
   /* Symbol is a unique global symbol.  */
   unsigned int unique_global : 1;
+  /* Symbol is defined with non-default visibility.  */
+  unsigned int protected_def : 1;
 
   /* String table index in .dynstr if this is a dynamic symbol.  */
   unsigned long dynstr_index;
@@ -2026,7 +2028,7 @@ extern bfd_boolean _bfd_elf_link_output_relocs
    struct elf_link_hash_entry **);
 
 extern bfd_boolean _bfd_elf_adjust_dynamic_copy
-  (struct elf_link_hash_entry *, asection *);
+  (struct bfd_link_info *, struct elf_link_hash_entry *, asection *);
 
 extern bfd_boolean _bfd_elf_dynamic_symbol_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
index f29025d5d92a0c9e6e3828c7816e38bd0844263c..1dbb2f9b262842aa200786133a611499daaa755f 100644 (file)
@@ -5024,7 +5024,7 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Set the sizes of the dynamic sections.  */
index 1ff562cf77242e2ba7431634ff7fd205eebe3bc1..5b2f66f0f910cee507396bd908ea5a422b733d8c 100644 (file)
@@ -13339,7 +13339,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index f16f1c628a2dbbc604989181a033f5f5ced47387..6dadcc1d9eab31f8237fd5a4f3da0892e46e921b 100644 (file)
@@ -2437,7 +2437,7 @@ _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Set the sizes of the dynamic sections.  */
index 9b2b956c8af998ef9c2e4add93686363fb84d60f..c516b2f26e58da841ff4ddb68ebed7c6d37f68d9 100644 (file)
@@ -3054,7 +3054,7 @@ elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Adjust our "subclass" elements for an indirect symbol.  */
index 0588ebbfcdf332c9de5b87beeaa6fae5f1adfbbd..abc712402c335497793c537ba2aad8ed082bae19 100644 (file)
@@ -1915,7 +1915,7 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   sec = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (eh, sec);
+  return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
 }
 
 /* Allocate space in the .plt for entries that won't have relocations.
index c9ed6e0260ff15493195350e9fd181d9bb134755..e28c2576102be93f6ff54430ff20c49604c97a7a 100644 (file)
@@ -534,7 +534,7 @@ i370_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 \f
 /* Increment the index of a dynamic symbol by a given amount.  Called
index 2bd7f43ade71980517453d0bf1f0c58eaae863ce..e0eef28e21301248d6dfa75f8f7fd0ab9758e95d 100644 (file)
@@ -2229,7 +2229,7 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index e694055a9bd4aea676b60bea087baee21ac8a927..5f2b6b8f25e84dbd435354f00f1cc7ba160677ba 100644 (file)
@@ -1892,7 +1892,7 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 8dba9f0a3e515e0f0f0c4ee7c6c31597023b1d1c..e6b45ab0907212a0d5f6ce97130fa7f05e5cc61c 100644 (file)
@@ -1919,7 +1919,7 @@ m32r_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 0058da442df5a04d6fd8f3b5b0367e6a12ca9b14..9a42288db5656f2714579d91a5c89adf12ae76e3 100644 (file)
@@ -3237,7 +3237,7 @@ elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Set the sizes of the dynamic sections.  */
index 47ca5debe830d90f42be11b50ad1e16187c63409..a68b51cd9b6f8b551cb6d6b3ea53bfc60b3b2652 100644 (file)
@@ -2587,7 +2587,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (eh, s);
+  return _bfd_elf_adjust_dynamic_copy (info, eh, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 5cf29e133a9f9b0d51c5945d7f4fb504bca495c4..e5b7bad252fe71f0732016973a580c8d9b949e68 100644 (file)
@@ -2187,7 +2187,7 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index b4d20753cf7b7efffd17015010a164e41b735031..8429e8f95b7ff23764b3118482f2c218d654205a 100644 (file)
@@ -5628,7 +5628,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 \f
 /* Generate a symbol to mark plt call stubs.  For non-PIC code the sym is
index ebcb028b86b95f6bb8c8a6a72c9e3caf08715366..07e594f295787b0f26e879c2c21cff1b61375103 100644 (file)
@@ -1762,7 +1762,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 44a3aa7875ede7449df3d23cca80b35ebb0341ba..a737044964d283f6a1e42b06fa1aec0ee7ab429f 100644 (file)
@@ -2919,7 +2919,7 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 8381cfa76430830c37928a4e930b455c3f3356fa..9f17979554c7902cc4ebb79d162803822892eb23 100644 (file)
@@ -2168,7 +2168,7 @@ elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 static bfd_boolean
index b9a31d5c4767da1db174d2fc6f05741bfa2dda86..095992429ad25ec151d1384b16c76a5d471cc654 100644 (file)
@@ -2189,7 +2189,7 @@ tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdynbss);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 1f418672424a879eb46f4755e55babf369c5deb5..05e65e970938f85a26a768fec8b83a1c6a8e76a6 100644 (file)
@@ -1043,7 +1043,7 @@ elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* This function is called via elf_link_hash_traverse.  It resets GOT
index cb58df18d111908e09bde09cedd963e3b59a828a..26ae9ed65719b3323c2b0922d1835138f68707de 100644 (file)
@@ -7121,7 +7121,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->dynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* If given a function descriptor symbol, hide both the function code
index b2f1aa59fd6d424023f3172222e79e48f3aa88c5..9a874f2b7499eed770c4292a68a8d136901d5874 100644 (file)
@@ -1707,7 +1707,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index 311d7c3e84481e891f3e66444486671789a54372..74979293169ab70c1311ff266d9bbbbb62332abf 100644 (file)
@@ -3381,7 +3381,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* This function is called via sh_elf_link_hash_traverse if we are
index 64b4634fb420388a7ed5dde1ca9c3179e683cea0..40a2a8767b68f50986dcbadb5152fca830066e6f 100644 (file)
@@ -2445,7 +2445,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index b023ec5a5a53e18dafbb37668a4293dc70d34db3..a01daf2fdff9f4953e71978025ba39243dd62967 100644 (file)
@@ -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;
 }
 
index 0879db97be80ae76db1034477bc673fb3897f1ae..4f0e0c630d8b3ad9929f55f3a68f59bcea36d675 100644 (file)
@@ -5542,7 +5542,7 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 
 }
 
index 81128491f64642674c97d844eb7dcaaf73951eba..db403b3a00f49bb640a3779155feeb4273a35b02 100644 (file)
@@ -9215,7 +9215,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      dynamic will now refer to the local copy instead.  */
   hmips->possibly_dynamic_relocs = 0;
 
-  return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdynbss);
 }
 \f
 /* This function is called after all the input files have been read,
index d5f92d467173db3b0789e1e75e8fb41aa241ed48..a56493f7d66a509041b487599957f9ce0bdc02bb 100644 (file)
@@ -2211,7 +2211,7 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
index e206bc72d6b5bdc1283d61d6a7bdf2b3baa53c5e..90f4395d7ca5711cd7beb55633e9f0484698412e 100644 (file)
@@ -2456,7 +2456,7 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdynbss);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for