This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] x86: Clear extern_protected_data for GNU_PROPERTY_NO_COPY_ON_PROTECTED


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=73784fa565bd66f1ac165816c03e5217b7d67bbc

commit 73784fa565bd66f1ac165816c03e5217b7d67bbc
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Aug 23 10:15:39 2017 -0700

    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.

Diff:
---
 bfd/ChangeLog                       |   7 +++
 bfd/elf32-i386.c                    | 116 +++++++++++++++++++++---------------
 bfd/elf64-x86-64.c                  | 114 ++++++++++++++++++++---------------
 ld/ChangeLog                        |   9 +++
 ld/testsuite/ld-i386/i386.exp       |   1 +
 ld/testsuite/ld-i386/protected7.d   |  13 ++++
 ld/testsuite/ld-i386/protected7.s   |  31 ++++++++++
 ld/testsuite/ld-x86-64/protected8.d |  13 ++++
 ld/testsuite/ld-x86-64/protected8.s |  31 ++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp   |   1 +
 10 files changed, 241 insertions(+), 95 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3d09aa4..c7ce75d 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 d5477c4..1009c17 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 8a6bd62..244db80 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 0859f70..c499de7 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 27d622e..3c5de02 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 0000000..aafa2d8
--- /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 0000000..bc2bc91
--- /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 0000000..22a36ac
--- /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 0000000..314433d
--- /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 4631157..0b795df 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"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]