summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-08-23 10:15:39 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-08-23 10:15:58 -0700
commit73784fa565bd66f1ac165816c03e5217b7d67bbc (patch)
tree00a650b903a28e8c12a40a7a836c5bf5baf9c92a
parent6e41ddec97d402c6c150701da0f70d40bd6ed5ca (diff)
downloadbinutils-gdb-73784fa565bd66f1ac165816c03e5217b7d67bbc.tar.gz
x86: Clear extern_protected_data for GNU_PROPERTY_NO_COPY_ON_PROTECTED
When GNU_PROPERTY_NO_COPY_ON_PROTECTED is set, it indicates that there are no copy relocations against protected data symbols. When linker sees GNU_PROPERTY_NO_COPY_ON_PROTECTED on any input relocatable file, it sets extern_protected_data to FALSE. bfd/ * elf32-i386.c (elf_i386_link_setup_gnu_properties): Set extern_protected_data to FALSE if GNU_PROPERTY_NO_COPY_ON_PROTECTED is set on any input relocatable file. * elf64-x86-64.c (elf_x86_64_link_setup_gnu_properties): Likewise. ld/ * testsuite/ld-i386/i386.exp: Run protected7. * testsuite/ld-i386/protected7.d: New file. * testsuite/ld-i386/protected7.s: Likewise. * testsuite/ld-x86-64/protected8.d: Likewise. * testsuite/ld-x86-64/protected8.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run protected8.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-i386.c116
-rw-r--r--bfd/elf64-x86-64.c114
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/testsuite/ld-i386/i386.exp1
-rw-r--r--ld/testsuite/ld-i386/protected7.d13
-rw-r--r--ld/testsuite/ld-i386/protected7.s31
-rw-r--r--ld/testsuite/ld-x86-64/protected8.d13
-rw-r--r--ld/testsuite/ld-x86-64/protected8.s31
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp1
10 files changed, 241 insertions, 95 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3d09aa4c94f..c7ce75d379b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2017-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_link_setup_gnu_properties): Set
+ extern_protected_data to FALSE if GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ is set on any input relocatable file.
+ * elf64-x86-64.c (elf_x86_64_link_setup_gnu_properties): Likewise.
+
2017-08-23 Alan Modra <amodra@gmail.com>
PR 21988
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index d5477c42153..1009c17ff21 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -6780,66 +6780,90 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
unsigned int plt_alignment, features;
struct elf_i386_link_hash_table *htab;
bfd *pbfd;
+ bfd *ebfd = NULL;
+ elf_property *prop;
features = 0;
if (info->ibt)
features = GNU_PROPERTY_X86_FEATURE_1_IBT;
if (info->shstk)
features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
- if (features)
- {
- /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- bfd *ebfd = NULL;
- elf_property *prop;
-
- for (pbfd = info->input_bfds;
- pbfd != NULL;
- pbfd = pbfd->link.next)
- if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
- && bfd_count_sections (pbfd) != 0)
- {
- ebfd = pbfd;
- if (elf_properties (pbfd) != NULL)
- {
- /* Find a normal input file with GNU property note. */
- prop = _bfd_elf_get_property (pbfd,
- GNU_PROPERTY_X86_FEATURE_1_AND,
- 4);
- /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- prop->u.number |= features;
- prop->pr_kind = property_number;
- break;
- }
- }
+ /* Find a normal input file with GNU property note. */
+ for (pbfd = info->input_bfds;
+ pbfd != NULL;
+ pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && bfd_count_sections (pbfd) != 0)
+ {
+ ebfd = pbfd;
- if (pbfd == NULL && ebfd != NULL)
+ if (elf_properties (pbfd) != NULL)
+ break;
+ }
+
+ if (ebfd != NULL)
+ {
+ if (features)
{
- /* Create GNU_PROPERTY_X86_FEATURE_1_IBT if needed. */
+ /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
+ GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_X86_FEATURE_1_AND,
4);
- prop->u.number = features;
+ prop->u.number |= features;
prop->pr_kind = property_number;
- sec = bfd_make_section_with_flags (ebfd,
- NOTE_GNU_PROPERTY_SECTION_NAME,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_HAS_CONTENTS
- | SEC_DATA));
- if (sec == NULL)
- info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
+ /* Create the GNU property note section if needed. */
+ if (pbfd == NULL)
+ {
+ sec = bfd_make_section_with_flags (ebfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS
+ | SEC_DATA));
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
- if (!bfd_set_section_alignment (ebfd, sec, 2))
- goto error_alignment;
+ if (!bfd_set_section_alignment (ebfd, sec, 2))
+ {
+error_alignment:
+ info->callbacks->einfo (_("%F%A: failed to align section\n"),
+ sec);
+ }
- elf_section_type (sec) = SHT_NOTE;
+ elf_section_type (sec) = SHT_NOTE;
+ }
}
+
+ /* Check GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
+ for (; pbfd != NULL; pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && (pbfd->flags
+ & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
+ {
+ elf_property_list *p;
+
+ /* The property list is sorted in order of type. */
+ for (p = elf_properties (pbfd); p != NULL; p = p->next)
+ {
+ if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ == p->property.pr_type)
+ {
+ /* Clear extern_protected_data if
+ GNU_PROPERTY_NO_COPY_ON_PROTECTED is
+ set on any input relocatable file. */
+ info->extern_protected_data = FALSE;
+ break;
+ }
+ else if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ < p->property.pr_type)
+ break;
+ }
+ }
}
pbfd = _bfd_elf_link_setup_gnu_properties (info);
@@ -7116,11 +7140,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
if (sec != NULL
&& !bfd_set_section_alignment (sec->owner, sec,
plt_alignment))
- {
-error_alignment:
- info->callbacks->einfo (_("%F%A: failed to align section\n"),
- sec);
- }
+ goto error_alignment;
}
return pbfd;
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 8a6bd6285c8..244db80ed61 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -7302,71 +7302,91 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
unsigned int plt_alignment, features;
struct elf_x86_64_link_hash_table *htab;
bfd *pbfd;
+ bfd *ebfd = NULL;
+ elf_property *prop;
features = 0;
if (info->ibt)
features = GNU_PROPERTY_X86_FEATURE_1_IBT;
if (info->shstk)
features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
- if (features)
- {
- /* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- bfd *ebfd = NULL;
- elf_property *prop;
-
- for (pbfd = info->input_bfds;
- pbfd != NULL;
- pbfd = pbfd->link.next)
- if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
- && bfd_count_sections (pbfd) != 0)
- {
- ebfd = pbfd;
- if (elf_properties (pbfd) != NULL)
- {
- /* Find a normal input file with GNU property note. */
- prop = _bfd_elf_get_property (pbfd,
- GNU_PROPERTY_X86_FEATURE_1_AND,
- 4);
- /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- prop->u.number |= features;
- prop->pr_kind = property_number;
- break;
- }
- }
+ /* Find a normal input file with GNU property note. */
+ for (pbfd = info->input_bfds;
+ pbfd != NULL;
+ pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && bfd_count_sections (pbfd) != 0)
+ {
+ ebfd = pbfd;
+
+ if (elf_properties (pbfd) != NULL)
+ break;
+ }
- if (pbfd == NULL && ebfd != NULL)
+ if (ebfd != NULL)
+ {
+ if (features)
{
- /* Create GNU_PROPERTY_X86_FEATURE_1_IBT if needed. */
+ /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
+ GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_X86_FEATURE_1_AND,
4);
- prop->u.number = features;
+ prop->u.number |= features;
prop->pr_kind = property_number;
- sec = bfd_make_section_with_flags (ebfd,
- NOTE_GNU_PROPERTY_SECTION_NAME,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_HAS_CONTENTS
- | SEC_DATA));
- if (sec == NULL)
- info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
-
- if (!bfd_set_section_alignment (ebfd, sec,
- ABI_64_P (ebfd) ? 3 : 2))
+ /* Create the GNU property note section if needed. */
+ if (pbfd == NULL)
{
+ sec = bfd_make_section_with_flags (ebfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS
+ | SEC_DATA));
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
+
+ if (!bfd_set_section_alignment (ebfd, sec,
+ ABI_64_P (ebfd) ? 3 : 2))
+ {
error_alignment:
- info->callbacks->einfo (_("%F%A: failed to align section\n"),
- sec);
- }
+ info->callbacks->einfo (_("%F%A: failed to align section\n"),
+ sec);
+ }
- elf_section_type (sec) = SHT_NOTE;
+ elf_section_type (sec) = SHT_NOTE;
+ }
}
+
+ /* Check GNU_PROPERTY_NO_COPY_ON_PROTECTED. */
+ for (; pbfd != NULL; pbfd = pbfd->link.next)
+ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
+ && (pbfd->flags
+ & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
+ {
+ elf_property_list *p;
+
+ /* The property list is sorted in order of type. */
+ for (p = elf_properties (pbfd); p != NULL; p = p->next)
+ {
+ if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ == p->property.pr_type)
+ {
+ /* Clear extern_protected_data if
+ GNU_PROPERTY_NO_COPY_ON_PROTECTED is
+ set on any input relocatable file. */
+ info->extern_protected_data = FALSE;
+ break;
+ }
+ else if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
+ < p->property.pr_type)
+ break;
+ }
+ }
}
pbfd = _bfd_elf_link_setup_gnu_properties (info);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0859f70cbe8..c499de7cd86 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2017-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * testsuite/ld-i386/i386.exp: Run protected7.
+ * testsuite/ld-i386/protected7.d: New file.
+ * testsuite/ld-i386/protected7.s: Likewise.
+ * testsuite/ld-x86-64/protected8.d: Likewise.
+ * testsuite/ld-x86-64/protected8.s: Likewise.
+ * testsuite/ld-x86-64/x86-64.exp: Run protected8.
+
2017-08-23 Alan Modra <amodra@gmail.com>
* testsuite/ld-gc/pr19161.d: Don't xfail hppa.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 27d622eab42..3c5de021b2b 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -308,6 +308,7 @@ run_dump_test "protected4"
run_dump_test "protected5"
run_dump_test "protected6a"
run_dump_test "protected6b"
+run_dump_test "protected7"
run_dump_test "tlspie1"
run_dump_test "tlspie2"
run_dump_test "tlspie3a"
diff --git a/ld/testsuite/ld-i386/protected7.d b/ld/testsuite/ld-i386/protected7.d
new file mode 100644
index 00000000000..aafa2d81b35
--- /dev/null
+++ b/ld/testsuite/ld-i386/protected7.d
@@ -0,0 +1,13 @@
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: 8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] 00 00 mov 0x[a-f0-9]+\(%ecx\),%eax
+[ ]*[a-f0-9]+: c3 ret
+#pass
diff --git a/ld/testsuite/ld-i386/protected7.s b/ld/testsuite/ld-i386/protected7.s
new file mode 100644
index 00000000000..bc2bc919584
--- /dev/null
+++ b/ld/testsuite/ld-i386/protected7.s
@@ -0,0 +1,31 @@
+ .protected foo
+.globl foo
+ .data
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 1
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ movl foo@GOTOFF(%ecx), %eax
+ ret
+ .size bar, .-bar
+
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f /* name length. */
+ .long 3f - 1f /* data length. */
+ /* NT_GNU_PROPERTY_TYPE_0 */
+ .long 5 /* note type. */
+0:
+ .asciz "GNU" /* vendor name. */
+1:
+ .p2align 2
+ /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+ .long 2 /* pr_type. */
+ .long 0 /* pr_datasz. */
+ .p2align 2
+3:
diff --git a/ld/testsuite/ld-x86-64/protected8.d b/ld/testsuite/ld-x86-64/protected8.d
new file mode 100644
index 00000000000..22a36ac4c8f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected8.d
@@ -0,0 +1,13 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%eax # [a-f0-9]+ <foo>
+[ ]*[a-f0-9]+: c3 retq *
+#pass
diff --git a/ld/testsuite/ld-x86-64/protected8.s b/ld/testsuite/ld-x86-64/protected8.s
new file mode 100644
index 00000000000..314433d0d19
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected8.s
@@ -0,0 +1,31 @@
+ .protected foo
+.globl foo
+ .data
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 1
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ movl foo(%rip), %eax
+ ret
+ .size bar, .-bar
+
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f /* name length. */
+ .long 3f - 2f /* data length. */
+ /* NT_GNU_PROPERTY_TYPE_0 */
+ .long 5 /* note type. */
+0: .asciz "GNU" /* vendor name. */
+1:
+ .p2align 3
+2:
+ /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+ .long 2 /* pr_type. */
+ .long 0 /* pr_datasz. */
+ .p2align 3
+3:
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 46311577e4b..0b795df60bb 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -291,6 +291,7 @@ run_dump_test "protected6a"
run_dump_test "protected6b"
run_dump_test "protected7a"
run_dump_test "protected7b"
+run_dump_test "protected8"
run_dump_test "tlsle1"
run_dump_test "tlspie1"
run_dump_test "tlspie2a"