This is the mail archive of the binutils@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]

[PATCH] x86-64: Move PIC check for PC-relative relocations back


commit 83924b3846361f2f76f9a6e7b5afa01c0eebbd4f
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

moved PIC check for PC-relative relocations to elf_x86_64_check_relocs.
Since linker defined symbols may not be processed at the time, we need
to move the back to elf_x86_64_relocate_section.

bfd/

PR ld/24905
* elf64-x86-64.c (elf_x86_64_check_relocs): Move PIC check for
PC-relative relocations back to ...
(elf_x86_64_relocate_section): Here.

ld/testsuite/

PR ld/24905
* ld-x86-64/pr24905-x32.d: New file.
* ld-x86-64/pr24905.d: Likewise.
* ld-x86-64/pr24905.s: Likewise.
* ld-x86-64/pr24905.t: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run pr24905 and pr24905-x32.


-- 
H.J.
From ba2907f2058d207d1adba4c3753bfda8a9502c33 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 15 Aug 2019 14:56:00 -0700
Subject: [PATCH] x86-64: Move PIC check for PC-relative relocations back

commit 83924b3846361f2f76f9a6e7b5afa01c0eebbd4f
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

moved PIC check for PC-relative relocations to elf_x86_64_check_relocs.
Since linker defined symbols may not be processed at the time, we need
to move the back to elf_x86_64_relocate_section.

bfd/

	PR ld/24905
	* elf64-x86-64.c (elf_x86_64_check_relocs): Move PIC check for
	PC-relative relocations back to ...
	(elf_x86_64_relocate_section): Here.

ld/testsuite/

	PR ld/24905
	* ld-x86-64/pr24905-x32.d: New file.
	* ld-x86-64/pr24905.d: Likewise.
	* ld-x86-64/pr24905.s: Likewise.
	* ld-x86-64/pr24905.t: Likewise.
	* testsuite/ld-x86-64/x86-64.exp: Run pr24905 and pr24905-x32.
---
 bfd/elf64-x86-64.c                   | 149 +++++++++++++--------------
 ld/testsuite/ld-x86-64/pr24905-x32.d |   8 ++
 ld/testsuite/ld-x86-64/pr24905.d     |   7 ++
 ld/testsuite/ld-x86-64/pr24905.s     |   6 ++
 ld/testsuite/ld-x86-64/pr24905.t     |   1 +
 ld/testsuite/ld-x86-64/x86-64.exp    |   2 +
 6 files changed, 94 insertions(+), 79 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pr24905-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/pr24905.d
 create mode 100644 ld/testsuite/ld-x86-64/pr24905.s
 create mode 100644 ld/testsuite/ld-x86-64/pr24905.t

diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 34180c7552..e5c8003a68 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1864,7 +1864,6 @@ 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);
@@ -2136,13 +2135,6 @@ 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;
@@ -2166,11 +2158,13 @@ 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
@@ -2234,69 +2228,6 @@ check_pic:
 		}
 	    }
 
-	  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
-		       && !h->root.linker_def
-		       && !h->root.ldscript_def
-		       && 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,
@@ -2497,6 +2428,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
       bfd_boolean relative_reloc;
       bfd_boolean converted_reloc;
       bfd_boolean need_copy_reloc_in_pie;
+      bfd_boolean no_copyreloc_p;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type == (int) R_X86_64_GNU_VTINHERIT
@@ -3137,14 +3069,73 @@ 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.  */
+	  no_copyreloc_p
+	    = (info->nocopyreloc
+	       || (h != NULL
+		   && !h->root.linker_def
+		   && !h->root.ldscript_def
+		   && eh->def_protected
+		   && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
+
+	  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
+			&& (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, input_bfd, input_section,
+					    h, NULL, NULL, howto);
+	    }
 	  /* Since x86-64 has PC-relative PLT, we can use PLT in PIE
 	     as function address.  */
-	  if (h != NULL
-	      && (input_section->flags & SEC_CODE) == 0
-	      && bfd_link_pie (info)
-	      && h->type == STT_FUNC
-	      && !h->def_regular
-	      && h->def_dynamic)
+	  else 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.  */
 
diff --git a/ld/testsuite/ld-x86-64/pr24905-x32.d b/ld/testsuite/ld-x86-64/pr24905-x32.d
new file mode 100644
index 0000000000..e2c6a73076
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24905-x32.d
@@ -0,0 +1,8 @@
+#source: pr24905.s
+#as: --x32
+#ld: -shared -melf32_x86_64 $srcdir/$subdir/pr24905.t
+#nm: -n
+
+#...
+[0-9a-f]* t EXTERNAL_SYM
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr24905.d b/ld/testsuite/ld-x86-64/pr24905.d
new file mode 100644
index 0000000000..f11834f12b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24905.d
@@ -0,0 +1,7 @@
+#as: --64
+#ld: -shared -melf_x86_64 $srcdir/$subdir/pr24905.t
+#nm: -n
+
+#...
+[0-9a-f]* t EXTERNAL_SYM
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr24905.s b/ld/testsuite/ld-x86-64/pr24905.s
new file mode 100644
index 0000000000..73a5d58032
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24905.s
@@ -0,0 +1,6 @@
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	leaq	EXTERNAL_SYM(%rip), %rdi
+	.hidden	EXTERNAL_SYM
diff --git a/ld/testsuite/ld-x86-64/pr24905.t b/ld/testsuite/ld-x86-64/pr24905.t
new file mode 100644
index 0000000000..5e7dbd371f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr24905.t
@@ -0,0 +1 @@
+PROVIDE_HIDDEN(EXTERNAL_SYM = ADDR(.text));
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index d815e5d633..b13cc7df0e 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -458,6 +458,8 @@ run_dump_test "pr24458c"
 run_dump_test "pr24458c-x32"
 run_dump_test "pr24721"
 run_dump_test "pr24721-x32"
+run_dump_test "pr24905"
+run_dump_test "pr24905-x32"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return
-- 
2.20.1


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