summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-04-11 07:34:49 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-04-11 08:20:08 -0700
commit4edbf4492560418a8981389f2a121f5d413c2956 (patch)
treede531e6b8dbe702b803efa05f67964ae90ded387
parente3c0e327923e27c7d96e6e44e22e10998ff158d7 (diff)
downloadbinutils-gdb-users/hjl/pr17709.tar.gz
Add -z [no]extern-protected-data to ldusers/hjl/pr17709
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 options override linker backend default. When -z noextern-protected-data is used, updates on protected data symbols by another module may not be visibile to the resulting shared library. bfd/ * 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/ * bfdlink.h (bfd_link_info): Add extern_protected_data. ld/ * ld.texinfo: Document "-z [no]extern-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". * emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Handle "-z [no]extern-protected-data". ld/testsuite/ * 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.
-rw-r--r--bfd/elflink.c9
-rw-r--r--include/bfdlink.h5
-rw-r--r--ld/emultempl/elf32.em4
-rw-r--r--ld/ld.texinfo13
-rw-r--r--ld/ldmain.c1
-rw-r--r--ld/lexsup.c4
-rw-r--r--ld/testsuite/ld-i386/i386.exp1
-rw-r--r--ld/testsuite/ld-i386/protected6b.d6
-rw-r--r--ld/testsuite/ld-x86-64/protected6b.d6
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp1
10 files changed, 48 insertions, 2 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 98d31080bca..5d45687c36b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 6a02a3c43bf..1b1582600a3 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -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. */
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 5db5a93c671..3f9903519a4 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2335,6 +2335,10 @@ fragment <<EOF
link_info.error_textrel = FALSE;
else if (strcmp (optarg, "textoff") == 0)
link_info.error_textrel = FALSE;
+ else if (strcmp (optarg, "extern-protected-data") == 0)
+ link_info.extern_protected_data = 1;
+ else if (strcmp (optarg, "noextern-protected-data") == 0)
+ link_info.extern_protected_data = 0;
EOF
fi
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 5384c98bd15..62be2f9e306 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1054,6 +1054,12 @@ shared libraries are still allowed.
@item execstack
Marks the object as requiring executable stack.
+@item extern-protected-data
+Treat protected data symbol as external when building shared library.
+Address of protected data defined in the shared library may be external,
+i.e., due to copy relocation. This option overrides linker backend
+default.
+
@item global
This option is only meaningful when building a shared object. It makes
the symbols defined by this shared object available for symbol resolution
@@ -1107,6 +1113,13 @@ Marks the object can not be dumped by @code{dldump}.
@item noexecstack
Marks the object as not requiring executable stack.
+@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.
+
@item text
Treat DT_TEXTREL in shared object as error.
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 6674a80c894..2ecb92d00bf 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -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 = ':';
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 4a71ba41cb0..adad7a80731 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1677,6 +1677,10 @@ elf_shlib_list_options (FILE *file)
fprintf (file, _("\
-z nocombreloc Don't merge dynamic relocs into one section\n"));
fprintf (file, _("\
+ -z extern-protected-data Treat protected data symbol as external\n"));
+ fprintf (file, _("\
+ -z noextern-protected-data Don't treat protected data symbol as external\n"));
+ fprintf (file, _("\
-z global Make symbols in DSO available for subsequently\n\
loaded objects\n"));
fprintf (file, _("\
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 0c0fd96b5f7..f214d896ecc 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -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
index 00000000000..5642c60251c
--- /dev/null
+++ b/ld/testsuite/ld-i386/protected6b.d
@@ -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
index 00000000000..8b443312d11
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected6b.d
@@ -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.
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 213a4c03bab..8352ad9591d 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -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"