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.
This commit is contained in:
H.J. Lu 2017-08-23 10:15:39 -07:00
parent 6e41ddec97
commit 73784fa565
10 changed files with 244 additions and 98 deletions

View File

@ -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> 2017-08-23 Alan Modra <amodra@gmail.com>
PR 21988 PR 21988

View File

@ -6780,66 +6780,90 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
unsigned int plt_alignment, features; unsigned int plt_alignment, features;
struct elf_i386_link_hash_table *htab; struct elf_i386_link_hash_table *htab;
bfd *pbfd; bfd *pbfd;
bfd *ebfd = NULL;
elf_property *prop;
features = 0; features = 0;
if (info->ibt) if (info->ibt)
features = GNU_PROPERTY_X86_FEATURE_1_IBT; features = GNU_PROPERTY_X86_FEATURE_1_IBT;
if (info->shstk) if (info->shstk)
features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
if (features)
/* 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 (ebfd != NULL)
{ {
/* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and if (features)
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;
}
}
if (pbfd == NULL && ebfd != NULL)
{ {
/* 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, prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_X86_FEATURE_1_AND, GNU_PROPERTY_X86_FEATURE_1_AND,
4); 4);
prop->u.number = features; prop->u.number |= features;
prop->pr_kind = property_number; prop->pr_kind = property_number;
sec = bfd_make_section_with_flags (ebfd, /* Create the GNU property note section if needed. */
NOTE_GNU_PROPERTY_SECTION_NAME, if (pbfd == NULL)
(SEC_ALLOC {
| SEC_LOAD sec = bfd_make_section_with_flags (ebfd,
| SEC_IN_MEMORY NOTE_GNU_PROPERTY_SECTION_NAME,
| SEC_READONLY (SEC_ALLOC
| SEC_HAS_CONTENTS | SEC_LOAD
| SEC_DATA)); | SEC_IN_MEMORY
if (sec == NULL) | SEC_READONLY
info->callbacks->einfo (_("%F: failed to create GNU property section\n")); | 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)) if (!bfd_set_section_alignment (ebfd, sec, 2))
goto error_alignment; {
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); 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 if (sec != NULL
&& !bfd_set_section_alignment (sec->owner, sec, && !bfd_set_section_alignment (sec->owner, sec,
plt_alignment)) plt_alignment))
{ goto error_alignment;
error_alignment:
info->callbacks->einfo (_("%F%A: failed to align section\n"),
sec);
}
} }
return pbfd; return pbfd;

View File

@ -7302,71 +7302,91 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
unsigned int plt_alignment, features; unsigned int plt_alignment, features;
struct elf_x86_64_link_hash_table *htab; struct elf_x86_64_link_hash_table *htab;
bfd *pbfd; bfd *pbfd;
bfd *ebfd = NULL;
elf_property *prop;
features = 0; features = 0;
if (info->ibt) if (info->ibt)
features = GNU_PROPERTY_X86_FEATURE_1_IBT; features = GNU_PROPERTY_X86_FEATURE_1_IBT;
if (info->shstk) if (info->shstk)
features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
if (features)
/* 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 (ebfd != NULL)
{ {
/* Turn on GNU_PROPERTY_X86_FEATURE_1_IBT and if (features)
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;
}
}
if (pbfd == NULL && ebfd != NULL)
{ {
/* 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, prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_X86_FEATURE_1_AND, GNU_PROPERTY_X86_FEATURE_1_AND,
4); 4);
prop->u.number = features; prop->u.number |= features;
prop->pr_kind = property_number; prop->pr_kind = property_number;
sec = bfd_make_section_with_flags (ebfd, /* Create the GNU property note section if needed. */
NOTE_GNU_PROPERTY_SECTION_NAME, if (pbfd == NULL)
(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: sec = bfd_make_section_with_flags (ebfd,
info->callbacks->einfo (_("%F%A: failed to align section\n"), NOTE_GNU_PROPERTY_SECTION_NAME,
sec); (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"));
elf_section_type (sec) = SHT_NOTE; 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);
}
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); pbfd = _bfd_elf_link_setup_gnu_properties (info);

View File

@ -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> 2017-08-23 Alan Modra <amodra@gmail.com>
* testsuite/ld-gc/pr19161.d: Don't xfail hppa. * testsuite/ld-gc/pr19161.d: Don't xfail hppa.

View File

@ -308,6 +308,7 @@ run_dump_test "protected4"
run_dump_test "protected5" run_dump_test "protected5"
run_dump_test "protected6a" run_dump_test "protected6a"
run_dump_test "protected6b" run_dump_test "protected6b"
run_dump_test "protected7"
run_dump_test "tlspie1" run_dump_test "tlspie1"
run_dump_test "tlspie2" run_dump_test "tlspie2"
run_dump_test "tlspie3a" run_dump_test "tlspie3a"

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -291,6 +291,7 @@ run_dump_test "protected6a"
run_dump_test "protected6b" run_dump_test "protected6b"
run_dump_test "protected7a" run_dump_test "protected7a"
run_dump_test "protected7b" run_dump_test "protected7b"
run_dump_test "protected8"
run_dump_test "tlsle1" run_dump_test "tlsle1"
run_dump_test "tlspie1" run_dump_test "tlspie1"
run_dump_test "tlspie2a" run_dump_test "tlspie2a"