[PATCH v2 3/8] RISC-V: Resolve the TEXTREL warning and redundant R_RISCV_NONE for IFUNC.

Nelson Chu nelson.chu@sifive.com
Fri Aug 7 03:57:08 GMT 2020


The R_RISCV_PCREL reloc refers to IFUNC symbol may cause redundant
R_RISCV_NONE relocs in the text section.  Then ld will issue the
TEXTREL warning to tell users that it may result in a segfault at
runtime.  To resolve this problem, do not let R_RISCV_PCREL fall
through to the static_reloc check in the riscv_elf_check_relocs.
For now, we should only check static_reloc for R_RISCV_32 and R_RISCV_64.

	bfd/
	* elfnn-riscv.c (riscv_elf_check_relocs): Do not let
	R_RISCV_PCREL fall through to the static_reloc check.

	ld/
	testsuite/ld-riscv-elf/ifunc-2.d: Remove the TEXTREL warning.
---
 bfd/elfnn-riscv.c                   | 32 +++++++++++++++++++-------------
 ld/testsuite/ld-riscv-elf/ifunc-2.d |  1 -
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 94ee184..c37351c 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -722,24 +722,30 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  h->plt.refcount += 1;
 	  break;
 
+	case R_RISCV_PCREL_HI20:
+	  if (h != NULL
+	      && h->type == STT_GNU_IFUNC)
+	    {
+	      h->non_got_ref = 1;
+	      h->pointer_equality_needed = 1;
+
+	      /* We don't use the PCREL_HI20 in the data section,
+		 so we always need the plt when it refers to
+		 IFUNC symbol.  */
+	      h->plt.refcount += 1;
+	    }
+	  /* Fall through.  */
+
 	case R_RISCV_JAL:
 	case R_RISCV_BRANCH:
 	case R_RISCV_RVC_BRANCH:
 	case R_RISCV_RVC_JUMP:
-	  /* In shared libraries, these relocs are known to bind locally.  */
+	  /* In shared libraries and pie, these relocs are known to
+	     bind locally.  */
 	  if (bfd_link_pic (info))
 	    break;
 	  goto static_reloc;
 
-	case R_RISCV_PCREL_HI20:
-	  /* In shared libraries, these relocs are known to bind locally,
-	     except IFUNC symbol.  */
-	  if (bfd_link_pic (info)
-	      && (h == NULL
-		  || h->type != STT_GNU_IFUNC))
-	    break;
-	  goto static_reloc;
-
 	case R_RISCV_TPREL_HI20:
 	  if (!bfd_link_executable (info))
 	    return bad_static_reloc (abfd, r_type, h);
@@ -802,14 +808,14 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	     symbol.
 
 	     Generate dynamic pointer relocation against STT_GNU_IFUNC
-	     symbol in the non-code section.  */
+	     symbol in the non-code section (R_RISCV_32/R_RISCV_64).  */
 	  reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type);
 
 	  if ((bfd_link_pic (info)
 	       && (sec->flags & SEC_ALLOC) != 0
-	       && ((r != NULL && ! r->pc_relative)
+	       && ((r != NULL && !r->pc_relative)
 		   || (h != NULL
-		       && (! info->symbolic
+		       && (!info->symbolic
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
 	      || (!bfd_link_pic (info)
diff --git a/ld/testsuite/ld-riscv-elf/ifunc-2.d b/ld/testsuite/ld-riscv-elf/ifunc-2.d
index 49320bd..ae96e8c 100644
--- a/ld/testsuite/ld-riscv-elf/ifunc-2.d
+++ b/ld/testsuite/ld-riscv-elf/ifunc-2.d
@@ -1,7 +1,6 @@
 #target: [check_shared_lib_support]
 #ld: -shared --hash-style=sysv
 #objdump: -dw
-#warning: GNU indirect functions with DT_TEXTREL may result in a segfault at runtime; recompile with -fPIC
 
 #...
 0+[0-9a-f]+ <foo>:
-- 
2.7.4



More information about the Binutils mailing list