]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: Clear extern_protected_data for GNU_PROPERTY_NO_COPY_ON_PROTECTED
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 23 Aug 2017 17:15:39 +0000 (10:15 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 23 Aug 2017 17:15:58 +0000 (10:15 -0700)
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.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/protected7.d [new file with mode: 0644]
ld/testsuite/ld-i386/protected7.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/protected8.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/protected8.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 3d09aa4c94fb1cdb2d20a2659005e28181e6b204..c7ce75d379be419ae6f332a8052b118654de1c12 100644 (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>
 
        PR 21988
index d5477c42153d7f050f6aeb6ba1336f258294dd60..1009c17ff21c1c28caf8b7b14e272abfa68abf60 100644 (file)
@@ -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;
index 8a6bd6285c866ce2c74a4c8a46f5a4a6c09d3cb2..244db80ed61a56bac4036f74690af778289b7d2c 100644 (file)
@@ -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);
index 0859f70cbe8d3bf03162c37607976fd9e3e11a55..c499de7cd8671d1aa259544e70977a6a223aa8c1 100644 (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>
 
        * testsuite/ld-gc/pr19161.d: Don't xfail hppa.
index 27d622eab424cb142e759844642332c8e80060f1..3c5de021b2b576b81d0011798aa3ca47029c18ff 100644 (file)
@@ -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 (file)
index 0000000..aafa2d8
--- /dev/null
@@ -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 (file)
index 0000000..bc2bc91
--- /dev/null
@@ -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 (file)
index 0000000..22a36ac
--- /dev/null
@@ -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 (file)
index 0000000..314433d
--- /dev/null
@@ -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:
index 46311577e4b2444e9d5551b61d625dcf6d538469..0b795df60bb4cf009806f104658966e84ecf8f90 100644 (file)
@@ -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"