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/binutils-2_32-branch] x86-64: Restore PIC check for PCREL reloc against protected symbol


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

commit db949bdcfb536f09b70cd7f57371c96042c4f216
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Feb 5 18:45:23 2019 -0800

    x86-64: Restore PIC check for PCREL reloc against protected symbol
    
    commit bd7ab16b4537788ad53521c45469a1bdae84ad4a
    Author: H.J. Lu <hjl.tools@gmail.com>
    Date:   Tue Feb 13 07:34:22 2018 -0800
    
        x86-64: Generate branch with PLT32 relocation
    
    removed check R_X86_64_PC32 relocation against protected symbols in
    shared objects.  Since elf_x86_64_check_relocs is called after we
    have seen all input files, we can check for PC-relative relocations in
    elf_x86_64_check_relocs.  We should not allow PC-relative relocations
    against protected symbols since address of protected function and
    location of protected data may not be in the shared object.
    
    bfd/
    
    	PR ld/24151
    	* elf64-x86-64.c (elf_x86_64_need_pic): Check
    	SYMBOL_DEFINED_NON_SHARED_P instead of def_regular.
    	(elf_x86_64_relocate_section): Move PIC check for PC-relative
    	relocations to ...
    	(elf_x86_64_check_relocs): Here.
    	(elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P
    	to check if a symbol is defined in a non-shared object.
    	* elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New.
    
    ld/
    
    	PR ld/24151
    	* testsuite/ld-x86-64/pr24151a-x32.d: New file.
    	* testsuite/ld-x86-64/pr24151a.d: Likewise.
    	* testsuite/ld-x86-64/pr24151a.s: Likewise.
    	* testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
    
    (cherry picked from commit 83924b3846361f2f76f9a6e7b5afa01c0eebbd4f)

Diff:
---
 bfd/ChangeLog                         |  12 +++
 bfd/elf64-x86-64.c                    | 133 ++++++++++++++++++++--------------
 bfd/elfxx-x86.h                       |   7 ++
 ld/ChangeLog                          |   8 ++
 ld/testsuite/ld-x86-64/pr24151a-x32.d |   4 +
 ld/testsuite/ld-x86-64/pr24151a.d     |   3 +
 ld/testsuite/ld-x86-64/pr24151a.s     |   9 +++
 ld/testsuite/ld-x86-64/x86-64.exp     |   2 +
 8 files changed, 124 insertions(+), 54 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0973c6e..f95a484 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2019-02-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/24151
+	* elf64-x86-64.c (elf_x86_64_need_pic): Check
+	SYMBOL_DEFINED_NON_SHARED_P instead of def_regular.
+	(elf_x86_64_relocate_section): Move PIC check for PC-relative
+	relocations to ...
+	(elf_x86_64_check_relocs): Here.
+	(elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P
+	to check if a symbol is defined in a non-shared object.
+	* elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New.
+
 2019-02-08  Alan Modra  <amodra@gmail.com>
 
 	* elf32-ppc.c (ppc_elf_relocate_section): Add %X to "unsupported
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index c7d8bca..6a4b366 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1426,7 +1426,7 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
 	  break;
 	}
 
-      if (!h->def_regular && !h->def_dynamic)
+      if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic)
 	und = _("undefined ");
     }
   else
@@ -1855,6 +1855,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       const char *name;
       bfd_boolean size_reloc;
       bfd_boolean converted_reloc;
+      bfd_boolean do_check_pic;
 
       r_symndx = htab->r_sym (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -2130,6 +2131,13 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  size_reloc = TRUE;
 	  goto do_size;
 
+	case R_X86_64_PC8:
+	case R_X86_64_PC16:
+	case R_X86_64_PC32:
+	case R_X86_64_PC32_BND:
+	  do_check_pic = TRUE;
+	  goto check_pic;
+
 	case R_X86_64_32:
 	  if (!ABI_64_P (abfd))
 	    goto pointer;
@@ -2153,13 +2161,11 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 					&x86_64_elf_howto_table[r_type]);
 	  /* Fall through.  */
 
-	case R_X86_64_PC8:
-	case R_X86_64_PC16:
-	case R_X86_64_PC32:
-	case R_X86_64_PC32_BND:
 	case R_X86_64_PC64:
 	case R_X86_64_64:
 pointer:
+	  do_check_pic = FALSE;
+check_pic:
 	  if (eh != NULL && (sec->flags & SEC_CODE) != 0)
 	    eh->zero_undefweak |= 0x2;
 	  /* We are called after all symbols have been resolved.  Only
@@ -2223,6 +2229,67 @@ pointer:
 		}
 	    }
 
+	  if (do_check_pic)
+	    {
+	      /* Don't complain about -fPIC if the symbol is undefined
+	         when building executable unless it is unresolved weak
+		 symbol, references a dynamic definition in PIE or
+		 -z nocopyreloc is used.  */
+	      bfd_boolean no_copyreloc_p
+		= (info->nocopyreloc
+		   || (h != NULL
+		       && eh->def_protected
+		       && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
+	      if ((sec->flags & SEC_ALLOC) != 0
+		  && (sec->flags & SEC_READONLY) != 0
+		  && h != NULL
+		  && ((bfd_link_executable (info)
+		       && ((h->root.type == bfd_link_hash_undefweak
+			    && (eh == NULL
+				|| !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
+								     eh)))
+			   || (bfd_link_pie (info)
+			       && !SYMBOL_DEFINED_NON_SHARED_P (h)
+			       && h->def_dynamic)
+			   || (no_copyreloc_p
+			       && h->def_dynamic
+			       && !(h->root.u.def.section->flags & SEC_CODE))))
+		      || bfd_link_dll (info)))
+		{
+		  bfd_boolean fail = FALSE;
+		  if (SYMBOL_REFERENCES_LOCAL_P (info, h))
+		    {
+		      /* Symbol is referenced locally.  Make sure it is
+			 defined locally.  */
+		      fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
+		    }
+		  else if (bfd_link_pie (info))
+		    {
+		      /* We can only use PC-relative relocations in PIE
+			 from non-code sections.  */
+		      if (h->type == STT_FUNC
+			  && (sec->flags & SEC_CODE) != 0)
+			fail = TRUE;
+		    }
+		  else if (no_copyreloc_p || bfd_link_dll (info))
+		    {
+		      /* Symbol doesn't need copy reloc and isn't
+			 referenced locally.  Don't allow PC-relative
+			 relocations against default and protected
+			 symbols since address of protected function
+			 and location of protected data may not be in
+			 the shared object.   */
+		      fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+			      || ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
+		    }
+
+		  if (fail)
+		    return elf_x86_64_need_pic (info, abfd, sec, h,
+						symtab_hdr, isym,
+						&x86_64_elf_howto_table[r_type]);
+		}
+	    }
+
 	  size_reloc = FALSE;
 do_size:
 	  if (NEED_DYNAMIC_RELOCATION_P (info, TRUE, h, sec, r_type,
@@ -3065,56 +3132,14 @@ use_plt:
 	case R_X86_64_PC16:
 	case R_X86_64_PC32:
 	case R_X86_64_PC32_BND:
-	  /* Don't complain about -fPIC if the symbol is undefined when
-	     building executable unless it is unresolved weak symbol,
-	     references a dynamic definition in PIE or -z nocopyreloc
-	     is used.  */
-	  if ((input_section->flags & SEC_ALLOC) != 0
-	      && (input_section->flags & SEC_READONLY) != 0
-	      && h != NULL
-	      && ((bfd_link_executable (info)
-		   && ((h->root.type == bfd_link_hash_undefweak
-			&& !resolved_to_zero)
-		       || (bfd_link_pie (info)
-			   && !h->def_regular
-			   && h->def_dynamic)
-		       || ((info->nocopyreloc
-			    || (eh->def_protected
-				&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
-			   && h->def_dynamic
-			   && !(h->root.u.def.section->flags & SEC_CODE))))
-		  || bfd_link_dll (info)))
-	    {
-	      bfd_boolean fail = FALSE;
-	      if (SYMBOL_REFERENCES_LOCAL_P (info, h))
-		{
-		  /* Symbol is referenced locally.  Make sure it is
-		     defined locally.  */
-		  fail = !(h->def_regular || ELF_COMMON_DEF_P (h));
-		}
-	      else if (!(bfd_link_pie (info)
-			 && (h->needs_copy || eh->needs_copy)))
-		{
-		  /* Symbol doesn't need copy reloc and isn't referenced
-		     locally.  Address of protected function may not be
-		     reachable at run-time.  */
-		  fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-			  || (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED
-			      && h->type == STT_FUNC));
-		}
-
-	      if (fail)
-		return elf_x86_64_need_pic (info, input_bfd, input_section,
-					    h, NULL, NULL, howto);
-	    }
 	  /* Since x86-64 has PC-relative PLT, we can use PLT in PIE
 	     as function address.  */
-	  else if (h != NULL
-		   && (input_section->flags & SEC_CODE) == 0
-		   && bfd_link_pie (info)
-		   && h->type == STT_FUNC
-		   && !h->def_regular
-		   && h->def_dynamic)
+	  if (h != NULL
+	      && (input_section->flags & SEC_CODE) == 0
+	      && bfd_link_pie (info)
+	      && h->type == STT_FUNC
+	      && !h->def_regular
+	      && h->def_dynamic)
 	    goto use_plt;
 	  /* Fall through.  */
 
@@ -4271,7 +4296,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
       else if (bfd_link_pic (info)
 	       && SYMBOL_REFERENCES_LOCAL_P (info, h))
 	{
-	  if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
+	  if (!SYMBOL_DEFINED_NON_SHARED_P (h))
 	    return FALSE;
 	  BFD_ASSERT((h->got.offset & 1) != 0);
 	  rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index dce24dc..28d540b 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -161,6 +161,13 @@
        || (ELF_ST_VISIBILITY ((H)->other) \
 	   && (H)->root.type == bfd_link_hash_undefweak))
 
+/* TRUE if this symbol isn't defined by a shared object.  */
+#define SYMBOL_DEFINED_NON_SHARED_P(H) \
+  ((H)->def_regular \
+   || (H)->root.linker_def \
+   || (H)->root.ldscript_def \
+   || ELF_COMMON_DEF_P (H))
+
 /* TRUE if relative relocation should be generated.  GOT reference to
    global symbol in PIC will lead to dynamic symbol.  It becomes a
    problem when "time" or "times" is defined as a variable in an
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 44bea4c..1d9e57e 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2019-02-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/24151
+	* testsuite/ld-x86-64/pr24151a-x32.d: New file.
+	* testsuite/ld-x86-64/pr24151a.d: Likewise.
+	* testsuite/ld-x86-64/pr24151a.s: Likewise.
+	* testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
+
 2019-02-02  Nick Clifton  <nickc@redhat.com>
 
 	* configure: Regenerate.
diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
new file mode 100644
index 0000000..130611d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
@@ -0,0 +1,4 @@
+#source: pr24151a.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
new file mode 100644
index 0000000..783b85a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24151a.d
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr24151a.s b/ld/testsuite/ld-x86-64/pr24151a.s
new file mode 100644
index 0000000..e4ec7c8
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24151a.s
@@ -0,0 +1,9 @@
+	.text
+	.globl	bar
+	.type	bar,@function
+bar:
+	movl	$30, foo(%rip)
+	.size	bar, .-bar
+	.protected foo
+	.type	foo,@object
+	.comm	foo,4,4
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 86b163f..5eb5565 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -424,6 +424,8 @@ run_dump_test "pr23486d-x32"
 run_dump_test "pr23854"
 run_dump_test "pr23930"
 run_dump_test "pr23930-x32"
+run_dump_test "pr24151a"
+run_dump_test "pr24151a-x32"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return


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