Add -z noextern-protected-data to ld for ELF/x86
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 14 Apr 2015 11:12:55 +0000 (04:12 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 14 Apr 2015 11:13:11 +0000 (04:13 -0700)
Address of protected data defined in the shared library may be external,
i.e., due to copy relocation.  By default, linker backend checks if
relocations against protected data symbols are valid for building shared
library and issues an error if relocation isn't allowed.  The new option
override linker backend default.  When -z noextern-protected-data is used,
updates on protected data symbols by another module won't be visibile
to the resulting shared library.  This option is specific to ELF/i386
and ELF/x86-64.

bfd/

PR ld/pr17709
* elflink.c (_bfd_elf_adjust_dynamic_copy): Check
info->extern_protected_data when warning copy relocs against
protected symbols.
(_bfd_elf_symbol_refs_local_p): Check info->extern_protected_data
when checking protected non-function symbols.

include/

PR ld/pr17709
* bfdlink.h (bfd_link_info): Add extern_protected_data.

ld/

PR ld/pr17709
* ld.texinfo: Document "-z noextern-protected-data".
* ldmain.c (main): Initialize link_info.extern_protected_data
to -1.
* lexsup.c (elf_shlib_list_options): Add
"-z [no]extern-protected-data".
* emulparams/elf32_x86_64.sh: Source extern_protected_data.sh.
* emulparams/elf_i386.sh: Likewise.
* emulparams/elf_i386_be.sh: Likewise.
* emulparams/elf_i386_chaos.sh: Likewise.
* emulparams/elf_i386_ldso.sh: Likewise.
* emulparams/elf_i386_vxworks.sh: Likewise.
* emulparams/elf_k1om.sh: Likewise.
* emulparams/elf_l1om.sh: Likewise.
* emulparams/elf_x86_64.sh: Source extern_protected_data.sh.
(PARSE_AND_LIST_OPTIONS): Renamed to ...
(PARSE_AND_LIST_OPTIONS_BNDPLT): This.
(PARSE_AND_LIST_ARGS_CASE_Z): Renamed to ...
(PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT): This.
(PARSE_AND_LIST_OPTIONS): Append $PARSE_AND_LIST_OPTIONS_BNDPLT.
(PARSE_AND_LIST_ARGS_CASE_Z): Append
$PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT.
* emulparams/extern_protected_data.sh: New file.

ld/testsuite/

PR ld/pr17709
* ld-i386/i386.exp: Run protected6b.
* ld-i386/protected6b.d: New file.
* ld-x86-64/protected6b.d: Likewise.
* ld-x86-64/x86-64.exp:  Run protected6b.

22 files changed:
bfd/ChangeLog
bfd/elflink.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/emulparams/elf32_x86_64.sh
ld/emulparams/elf_i386.sh
ld/emulparams/elf_i386_be.sh
ld/emulparams/elf_i386_chaos.sh
ld/emulparams/elf_i386_ldso.sh
ld/emulparams/elf_i386_vxworks.sh
ld/emulparams/elf_k1om.sh
ld/emulparams/elf_l1om.sh
ld/emulparams/elf_x86_64.sh
ld/emulparams/extern_protected_data.sh [new file with mode: 0644]
ld/ld.texinfo
ld/ldmain.c
ld/testsuite/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/protected6b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/protected6b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 55c37f03959d5ff8758235cbac92845fdf07ba94..056833e6562c0a9b1d2c83f3038fd0d55a822499 100644 (file)
@@ -1,3 +1,12 @@
+2015-04-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/pr17709
+       * elflink.c (_bfd_elf_adjust_dynamic_copy): Check
+       info->extern_protected_data when warning copy relocs against
+       protected symbols.
+       (_bfd_elf_symbol_refs_local_p): Check info->extern_protected_data
+       when checking protected non-function symbols.
+
 2015-04-13  John Baldwin  <jhb@FreeBSD.org>
 
        * elf.c (elfcore_grok_note): Recognize NT_X86_XSTATE on
index e3d1abe348ab01e66227cb5612ad980cafde710f..ea9246b6562933ab825a5dd1494743cf989f8c4d 100644 (file)
@@ -2675,7 +2675,9 @@ _bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info,
 
   /* No error if extern_protected_data is true.  */
   if (h->protected_def
-      && !get_elf_backend_data (dynbss->owner)->extern_protected_data)
+      && (!info->extern_protected_data
+         || (info->extern_protected_data < 0
+             && !get_elf_backend_data (dynbss->owner)->extern_protected_data)))
     info->callbacks->einfo
       (_("%P: copy reloc against protected `%T' is dangerous\n"),
        h->root.root.string);
@@ -2837,7 +2839,10 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
 
   /* If extern_protected_data is false, STV_PROTECTED non-function
      symbols are local.  */
-  if (!bed->extern_protected_data && !bed->is_function_type (h->type))
+  if ((!info->extern_protected_data
+       || (info->extern_protected_data < 0
+          && !bed->extern_protected_data))
+      && !bed->is_function_type (h->type))
     return TRUE;
 
   /* Function pointer equality tests may require that STV_PROTECTED
index 35da01586eacc299b136324b74cd4b7c68b6de6e..7d4919d1ef5401857303e07886c2d1bf8fe9fdc2 100644 (file)
@@ -1,3 +1,8 @@
+2015-04-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/pr17709
+       * bfdlink.h (bfd_link_info): Add extern_protected_data.
+
 2015-03-10  Matthew Wahab  <matthew.wahab@arm.com>
 
        PR ld/16572
index 6a02a3c43bfa747c0905178726e6e6e5f17c8e7f..1b1582600a38f4f377ab09286fa15015b0d4d0dd 100644 (file)
@@ -517,6 +517,11 @@ struct bfd_link_info
      relaxation returning true in *AGAIN.  */
   int relax_trip;
 
+  /* > 0 to treat protected data defined in the shared library as
+     reference external.  0 to treat it as internal.  -1 to let
+     backend to decide.  */
+  int extern_protected_data;
+
   /* Non-zero if auto-import thunks for DATA items in pei386 DLLs
      should be generated/linked against.  Set to 1 if this feature
      is explicitly requested by the user, -1 if enabled by default.  */
index bcad3f95f5eb1f282a262846ad277cd3bb27bcef..3e944feb8ed20ffead1d674b05da19a7b9b9ec51 100644 (file)
@@ -1,3 +1,29 @@
+2015-04-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/pr17709
+       * ld.texinfo: Document "-z noextern-protected-data".
+       * ldmain.c (main): Initialize link_info.extern_protected_data
+       to -1.
+       * lexsup.c (elf_shlib_list_options): Add
+       "-z [no]extern-protected-data".
+       * emulparams/elf32_x86_64.sh: Source extern_protected_data.sh.
+       * emulparams/elf_i386.sh: Likewise.
+       * emulparams/elf_i386_be.sh: Likewise.
+       * emulparams/elf_i386_chaos.sh: Likewise.
+       * emulparams/elf_i386_ldso.sh: Likewise.
+       * emulparams/elf_i386_vxworks.sh: Likewise.
+       * emulparams/elf_k1om.sh: Likewise.
+       * emulparams/elf_l1om.sh: Likewise.
+       * emulparams/elf_x86_64.sh: Source extern_protected_data.sh.
+       (PARSE_AND_LIST_OPTIONS): Renamed to ...
+       (PARSE_AND_LIST_OPTIONS_BNDPLT): This.
+       (PARSE_AND_LIST_ARGS_CASE_Z): Renamed to ...
+       (PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT): This.
+       (PARSE_AND_LIST_OPTIONS): Append $PARSE_AND_LIST_OPTIONS_BNDPLT.
+       (PARSE_AND_LIST_ARGS_CASE_Z): Append
+       $PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT.
+       * emulparams/extern_protected_data.sh: New file.
+
 2015-04-11  H.J. Lu  <hongjiu.lu@intel.com>
 
        * plugin.c (plugin_load_plugins): Removed an extra ';'.
index 11d17adb1dc272ffd7c459192f5afd4fc78e093c..8fd96fb7805b4717c128bc9f210377ff44739c06 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 ELFSIZE=32
 OUTPUT_FORMAT="elf32-x86-64"
index 2ebfaac8db6361ed21b4ad242c8d842587533e97..ae87f6b66176132bc11571a3b1783d2f17c8e7ab 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 OUTPUT_FORMAT="elf32-i386"
 NO_RELA_RELOCS=yes
index 1e27faacd08f4dc3694b3e5c2a535621856fc168..06a80c7ef3cf73ce2c82432d148ddc5a2924be86 100644 (file)
@@ -1,3 +1,4 @@
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 OUTPUT_FORMAT="elf32-i386"
 NO_RELA_RELOCS=yes
index b3005e194bd50f6db23dc4e421208831a558318d..c59dbce1402dce2026e4ac2608bdffe0b6929580 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf_chaos
 OUTPUT_FORMAT="elf32-i386"
 TEXT_START_ADDR=0x40000000
index e1a2cb7f5efd9824d2bbe06d66e9217b275afeae..7fd08fe865945be574f01f0bde26c47b77e56c5e 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 OUTPUT_FORMAT="elf32-i386"
 NO_RELA_RELOCS=yes
index 61839c8f48db2c2ee514602c2fbcb246eb096da5..306e8d3ee662ea1cce04554d99eedfa7e4e17909 100644 (file)
@@ -11,3 +11,4 @@ GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
 NO_SMALL_DATA=yes
 . ${srcdir}/emulparams/vxworks.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
index 00bf2cadec241b533568d1877e0131877804f28d..0cd606a2880ef963784c507eab4e95d2add65d30 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 ELFSIZE=64
 OUTPUT_FORMAT="elf64-k1om"
index abf59f163d6c3d5deafd5c0c9814e67e90759522..1964e857a073c689a5143708452e0c2de334ccd2 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 ELFSIZE=64
 OUTPUT_FORMAT="elf64-l1om"
index 984e5e92c460c6d39812442d9bf70e3d3df8cce2..a304771d9dfed33e0e7ad1bd5f4e52c84d44e096 100644 (file)
@@ -1,4 +1,5 @@
 . ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
 SCRIPT_NAME=elf
 ELFSIZE=64
 OUTPUT_FORMAT="elf64-x86-64"
@@ -36,14 +37,16 @@ case "$target" in
     case "$EMULATION_NAME" in
       *64*)
         LIBPATH_SUFFIX=64
-       PARSE_AND_LIST_OPTIONS='
+       PARSE_AND_LIST_OPTIONS_BNDPLT='
   fprintf (file, _("\
   -z bndplt                   Always generate BND prefix in PLT entries\n"));
 '
-       PARSE_AND_LIST_ARGS_CASE_Z='
+       PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT='
       else if (strcmp (optarg, "bndplt") == 0)
        link_info.bndplt = TRUE;
 '
+       PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_BNDPLT"
+       PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_BNDPLT"
         ;;
     esac
     ;;
diff --git a/ld/emulparams/extern_protected_data.sh b/ld/emulparams/extern_protected_data.sh
new file mode 100644 (file)
index 0000000..fd4bd3b
--- /dev/null
@@ -0,0 +1,9 @@
+PARSE_AND_LIST_OPTIONS='
+  fprintf (file, _("\
+  -z noextern-protected-data  Do not treat protected data symbol as external\n"));
+'
+
+PARSE_AND_LIST_ARGS_CASE_Z='
+      else if (strcmp (optarg, "noextern-protected-data") == 0)
+       link_info.extern_protected_data = FALSE;
+'
index 5384c98bd154f749cd3053b74f61fc64f9391d59..4348c8812b4111ed5a61f2b3c1d46af13dbbb115 100644 (file)
@@ -1146,6 +1146,14 @@ Specifying zero will override any default non-zero sized
 @item bndplt
 Always generate BND prefix in PLT entries. Supported for Linux/x86_64.
 
+@item noextern-protected-data
+Don't treat protected data symbol as external when building shared
+library.  This option overrides linker backend default.  It can be used
+to workaround incorrect relocations against protected data symbols
+generated by compiler.  Updates on protected data symbols by another
+module aren't visibile to the resulting shared library.  Supported for
+i386 and x86-64.
+
 @end table
 
 Other keywords are ignored for Solaris compatibility.
index 6674a80c89432a052ea5a7ff434007b207c2c183..2ecb92d00bf40a5a6396e870f6e211b6b8fa5f31 100644 (file)
@@ -285,6 +285,7 @@ main (int argc, char **argv)
   link_info.init_function = "_init";
   link_info.fini_function = "_fini";
   link_info.relax_pass = 1;
+  link_info.extern_protected_data = -1;
   link_info.pei386_auto_import = -1;
   link_info.spare_dynamic_tags = 5;
   link_info.path_separator = ':';
index 8b45279b0e87d1076f8be4b524398c717f5cae46..b35eb8314494ecc92e239c5ecc09013f0a20f30f 100644 (file)
@@ -1,3 +1,11 @@
+2015-04-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/pr17709
+       * ld-i386/i386.exp: Run protected6b.
+       * ld-i386/protected6b.d: New file.
+       * ld-x86-64/protected6b.d: Likewise.
+       * ld-x86-64/x86-64.exp:  Run protected6b.
+
 2015-04-11  H.J. Lu  <hongjiu.lu@intel.com>
 
        * ld-i386/i386.exp: Run protected6a.
index 0c0fd96b5f79d6059d04674e907753a3f4f2afb6..f214d896ecc412f634edf03aa242323991d04ca4 100644 (file)
@@ -237,6 +237,7 @@ run_dump_test "protected3"
 run_dump_test "protected4"
 run_dump_test "protected5"
 run_dump_test "protected6a"
+run_dump_test "protected6b"
 run_dump_test "tlspie1"
 run_dump_test "tlspie2"
 run_dump_test "nogot1"
diff --git a/ld/testsuite/ld-i386/protected6b.d b/ld/testsuite/ld-i386/protected6b.d
new file mode 100644 (file)
index 0000000..5642c60
--- /dev/null
@@ -0,0 +1,6 @@
+#source: protected6.s
+#as: --32
+#ld: -shared -melf_i386 -z noextern-protected-data
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected6b.d b/ld/testsuite/ld-x86-64/protected6b.d
new file mode 100644 (file)
index 0000000..8b44331
--- /dev/null
@@ -0,0 +1,6 @@
+#source: protected6.s
+#as: --64
+#ld: -shared -melf_x86_64 -z noextern-protected-data
+#readelf: -r
+
+There are no relocations in this file.
index 213a4c03bab3d4953aa8c875a7af3bd033780037..8352ad9591d0d6ba8cc4f9e811e9fb1a48ef6313 100644 (file)
@@ -221,6 +221,7 @@ run_dump_test "protected3-l1om"
 run_dump_test "protected4"
 run_dump_test "protected5"
 run_dump_test "protected6a"
+run_dump_test "protected6b"
 run_dump_test "protected7a"
 run_dump_test "protected7b"
 run_dump_test "tlsle1"