This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Downgrade linker error on protected symbols in .dynbss to a warning
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Binutils <binutils at sourceware dot org>, Richard Henderson <rth at redhat dot com>
- Date: Tue, 14 Apr 2015 04:16:12 -0700
- Subject: Re: Downgrade linker error on protected symbols in .dynbss to a warning
- Authentication-results: sourceware.org; auth=none
- References: <20150410115859 dot GM27812 at bubble dot grove dot modra dot org> <CAMe9rOrppvHdxMm-3x=7XaJQzW50dT4jkO-DRWRJxYhTtU6OPw at mail dot gmail dot com> <20150410132126 dot GN27812 at bubble dot grove dot modra dot org> <CAMe9rOrMJMvcqaPG0wRyY5O0Q_WC=-DBrZwOJboS_5Otw3Y5GA at mail dot gmail dot com> <20150410145906 dot GO27812 at bubble dot grove dot modra dot org> <CAMe9rOoU=pCmLVL5-snT6LgAXzFL0mBQAxwoSOqENDUyg8jhOA at mail dot gmail dot com> <CAMe9rOpEbuyWBRH1ycjcoSmeEEgcqBZCEsF7HnOS=dLJ6bRm6g at mail dot gmail dot com> <CAMe9rOrmrmQOrYgEGfJVoU8O74X+0KQruOqK98RxbzRbRtwUwA at mail dot gmail dot com> <20150413033246 dot GD15800 at bubble dot grove dot modra dot org> <CAMe9rOrvx9F13aQddq48RpoLV6c3zKJ=fjB6r+n7s=b_dYQcJA at mail dot gmail dot com> <20150414020938 dot GA23244 at bubble dot grove dot modra dot org>
On Mon, Apr 13, 2015 at 7:09 PM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, Apr 13, 2015 at 04:55:47AM -0700, H.J. Lu wrote:
>> On Sun, Apr 12, 2015 at 8:32 PM, Alan Modra <amodra@gmail.com> wrote:
>> > On Sat, Apr 11, 2015 at 08:27:58AM -0700, H.J. Lu wrote:
>> >> On Fri, Apr 10, 2015 at 4:52 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> >> > I will add a linker switch, -z extern-protected-data, to control
>> >> > linker behavior.
>> >>
>> >> Here is a patch to add such an option. OK for master?
>> >
>> > Why is this option needed?
>> >
>>
>> To work around the GCC bug. Otherwise, we got
>>
>> [hjl@gnu-tools-1 pr17709]$ cat bar.c
>> int a;
>>
>> __attribute__((visibility("protected"))) int a;
>>
>> void
>> bar ()
>> {
>> a = 30;
>> }
>> [hjl@gnu-tools-1 pr17709]$ make libbar.so
>> gcc -m32 -fPIC -c -o bar.o bar.c
>> ./ld -m elf_i386 -shared -o libbar.so bar.o
>> ./ld: bar.o: relocation R_386_GOTOFF against protected data `a' can
>> not be used when making a shared object
>
> I presume this isn't gcc-5. So for code generated by older versions
> of gcc you now emit an error when linking shared libraries that access
> protected visibility variables? And the reason you emit an error when
> building the shared library is that you'd like everyone to use gcc-5?
>
> I really dislike the way this whole saga is playing out. Especially
> since you know that there is absolutely nothing wrong with using
> R_386_GOTOFF against protected visibility data. In fact, code using a
> relative access is more efficient, and I wouldn't be surprised if
> someone raises a gcc-5 regression over *not* using R_386_GOTOFF in a
> shared library making heavy use of protected visibility.
>
> If you want to go ahead with this patch, you need to make it x86
> specific. -z extern-protected-data is not appropriate as a general
> ld option.
>
This is what I checked in.
--
H.J.
From 889c2a67967f7047c245779a0a0fd8ba8796846e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 14 Apr 2015 04:12:55 -0700
Subject: [PATCH] Add -z noextern-protected-data to ld for ELF/x86
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.
---
bfd/ChangeLog | 9 +++++++++
bfd/elflink.c | 9 +++++++--
include/ChangeLog | 5 +++++
include/bfdlink.h | 5 +++++
ld/ChangeLog | 26 ++++++++++++++++++++++++++
ld/emulparams/elf32_x86_64.sh | 1 +
ld/emulparams/elf_i386.sh | 1 +
ld/emulparams/elf_i386_be.sh | 1 +
ld/emulparams/elf_i386_chaos.sh | 1 +
ld/emulparams/elf_i386_ldso.sh | 1 +
ld/emulparams/elf_i386_vxworks.sh | 1 +
ld/emulparams/elf_k1om.sh | 1 +
ld/emulparams/elf_l1om.sh | 1 +
ld/emulparams/elf_x86_64.sh | 7 +++++--
ld/emulparams/extern_protected_data.sh | 9 +++++++++
ld/ld.texinfo | 8 ++++++++
ld/ldmain.c | 1 +
ld/testsuite/ChangeLog | 8 ++++++++
ld/testsuite/ld-i386/i386.exp | 1 +
ld/testsuite/ld-i386/protected6b.d | 6 ++++++
ld/testsuite/ld-x86-64/protected6b.d | 6 ++++++
ld/testsuite/ld-x86-64/x86-64.exp | 1 +
22 files changed, 105 insertions(+), 4 deletions(-)
create mode 100644 ld/emulparams/extern_protected_data.sh
create mode 100644 ld/testsuite/ld-i386/protected6b.d
create mode 100644 ld/testsuite/ld-x86-64/protected6b.d
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 55c37f0..056833e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elflink.c b/bfd/elflink.c
index e3d1abe..ea9246b 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/ChangeLog b/include/ChangeLog
index 35da015..7d4919d 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 6a02a3c..1b15826 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/ChangeLog b/ld/ChangeLog
index bcad3f9..3e944fe 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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 ';'.
diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
index 11d17ad..8fd96fb 100644
--- a/ld/emulparams/elf32_x86_64.sh
+++ b/ld/emulparams/elf32_x86_64.sh
@@ -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"
diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
index 2ebfaac..ae87f6b 100644
--- a/ld/emulparams/elf_i386.sh
+++ b/ld/emulparams/elf_i386.sh
@@ -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
diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh
index 1e27faa..06a80c7 100644
--- a/ld/emulparams/elf_i386_be.sh
+++ b/ld/emulparams/elf_i386_be.sh
@@ -1,3 +1,4 @@
+. ${srcdir}/emulparams/extern_protected_data.sh
SCRIPT_NAME=elf
OUTPUT_FORMAT="elf32-i386"
NO_RELA_RELOCS=yes
diff --git a/ld/emulparams/elf_i386_chaos.sh b/ld/emulparams/elf_i386_chaos.sh
index b3005e1..c59dbce 100644
--- a/ld/emulparams/elf_i386_chaos.sh
+++ b/ld/emulparams/elf_i386_chaos.sh
@@ -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
diff --git a/ld/emulparams/elf_i386_ldso.sh b/ld/emulparams/elf_i386_ldso.sh
index e1a2cb7..7fd08fe 100644
--- a/ld/emulparams/elf_i386_ldso.sh
+++ b/ld/emulparams/elf_i386_ldso.sh
@@ -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
diff --git a/ld/emulparams/elf_i386_vxworks.sh b/ld/emulparams/elf_i386_vxworks.sh
index 61839c8..306e8d3 100644
--- a/ld/emulparams/elf_i386_vxworks.sh
+++ b/ld/emulparams/elf_i386_vxworks.sh
@@ -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
diff --git a/ld/emulparams/elf_k1om.sh b/ld/emulparams/elf_k1om.sh
index 00bf2ca..0cd606a 100644
--- a/ld/emulparams/elf_k1om.sh
+++ b/ld/emulparams/elf_k1om.sh
@@ -1,4 +1,5 @@
. ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
SCRIPT_NAME=elf
ELFSIZE=64
OUTPUT_FORMAT="elf64-k1om"
diff --git a/ld/emulparams/elf_l1om.sh b/ld/emulparams/elf_l1om.sh
index abf59f1..1964e85 100644
--- a/ld/emulparams/elf_l1om.sh
+++ b/ld/emulparams/elf_l1om.sh
@@ -1,4 +1,5 @@
. ${srcdir}/emulparams/plt_unwind.sh
+. ${srcdir}/emulparams/extern_protected_data.sh
SCRIPT_NAME=elf
ELFSIZE=64
OUTPUT_FORMAT="elf64-l1om"
diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
index 984e5e9..a304771 100644
--- a/ld/emulparams/elf_x86_64.sh
+++ b/ld/emulparams/elf_x86_64.sh
@@ -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
index 0000000..fd4bd3b
--- /dev/null
+++ b/ld/emulparams/extern_protected_data.sh
@@ -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;
+'
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 5384c98..4348c88 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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.
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 6674a80..2ecb92d 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/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 8b45279..b35eb83 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 0c0fd96..f214d89 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 0000000..5642c60
--- /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 0000000..8b44331
--- /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 213a4c0..8352ad9 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"
--
2.1.0