public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/3] RISC-V: Extract the ld code which are too complicated, and may be reused.
@ 2023-03-25  0:41 Nelson Chu
  2023-03-25  0:41 ` [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol Nelson Chu
  2023-03-25  0:41 ` [PATCH 3/3] RISC-V: PR28789, Reject R_RISCV_PCREL relocations with ABS symbol in PIC/PIE Nelson Chu
  0 siblings, 2 replies; 4+ messages in thread
From: Nelson Chu @ 2023-03-25  0:41 UTC (permalink / raw)
  To: binutils, jim.wilson.gcc, palmer; +Cc: nelson

These types of codes are different for each target, I am not sure what are the
best for RISC-V, so extract them out may be more easy to compare what's the
difference.

bfd/
    * elfnn-riscv.c (RISCV_NEED_DYNAMIC_RELOC): New defined.  Extracted
    from riscv_elf_check_relocs, to see if dynamic reloc is needed for the
    specific relocation.
    (RISCV_GENERATE_DYNAMIC_RELOC): New defined.  Extracted from
    riscv_elf_relocate_section, to see if R_RISCV_32/64 need to generate
    dynamic relocation.
    (RISCV_COPY_INPUT_RELOC): New defined.  Extracted from
    riscv_elf_relocate_section, to see if R_RISCV_32/64 need to copy itslef
    tp output file.
    (RISCV_RESOLVED_LOCALLY): New defined.  Extracted from
    riscv_elf_relocate_section, to see if R_RISCV_GOT_HI20 can be resolved
    locally.
---
 bfd/elfnn-riscv.c | 156 ++++++++++++++++++++++++----------------------
 1 file changed, 82 insertions(+), 74 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1200e6b11b5..59e949a2cb5 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -38,6 +38,79 @@
 #define CHAR_BIT 8
 #endif
 
+/* True if dynamic relocation is needed.  If we are creating a shared library,
+   and this is a reloc against a global symbol, or a non PC relative reloc
+   against a local symbol, then we need to copy the reloc into the shared
+   library.  However, if we are linking with -Bsymbolic, we do not need to
+   copy a reloc against a global symbol which is defined in an object we are
+   including in the link (i.e., DEF_REGULAR is set).
+
+   At this point we have not seen all the input files, so it is possible that
+   DEF_REGULAR is not set now but will be set later (it is never cleared).
+   In case of a weak definition, DEF_REGULAR may be cleared later by a strong
+   definition in a shared library.  We account for that possibility below by
+   storing information in the relocs_copied field of the hash table entry.
+   A similar situation occurs when creating shared libraries and symbol
+   visibility changes render the symbol local.
+
+   If on the other hand, we are creating an executable, we may need to keep
+   relocations for symbols satisfied by a dynamic library if we manage to
+   avoid copy relocs for the symbol.
+
+   Generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the
+   non-code section (R_RISCV_32/R_RISCV_64).  */
+#define RISCV_NEED_DYNAMIC_RELOC(PCREL, INFO, H, SEC) \
+  ((bfd_link_pic (INFO) \
+    && ((SEC)->flags & SEC_ALLOC) != 0 \
+    && (!(PCREL) \
+	|| ((H) != NULL \
+	    && (!(INFO)->symbolic \
+		|| (H)->root.type == bfd_link_hash_defweak \
+		|| !(H)->def_regular)))) \
+   || (!bfd_link_pic (INFO) \
+       && ((SEC)->flags & SEC_ALLOC) != 0 \
+       && (H) != NULL \
+       && ((H)->root.type == bfd_link_hash_defweak \
+	   || !(H)->def_regular)) \
+   || (!bfd_link_pic (INFO) \
+       && (H) != NULL \
+       && (H)->type == STT_GNU_IFUNC \
+       && ((SEC)->flags & SEC_CODE) == 0))
+
+/* True if dynamic relocation should be generated.  */
+#define RISCV_GENERATE_DYNAMIC_RELOC(PCREL, INFO, H, RESOLVED_TO_ZERO) \
+  ((bfd_link_pic (INFO) \
+    && ((H) == NULL \
+	|| (ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT && !(RESOLVED_TO_ZERO)) \
+	|| (H)->root.type != bfd_link_hash_undefweak) \
+    && (!(PCREL) \
+	|| !SYMBOL_CALLS_LOCAL ((INFO), (H)))) \
+   || (!bfd_link_pic (INFO) \
+       && (H) != NULL \
+       && (H)->dynindx != -1 \
+       && !(H)->non_got_ref \
+       && (((H)->def_dynamic && !(H)->def_regular) \
+	   || (H)->root.type == bfd_link_hash_undefweak \
+	   || (H)->root.type == bfd_link_hash_undefined)))
+
+/* True if this input relocation should be copied to output.  H->dynindx
+   may be -1 if this symbol was marked to become local.  */
+#define RISCV_COPY_INPUT_RELOC(INFO, H) \
+  ((H) != NULL \
+   && (H)->dynindx != -1 \
+   && (!bfd_link_pic (INFO) \
+       || !SYMBOLIC_BIND ((INFO), (H)) \
+       || !(H)->def_regular))
+
+/* True if this is actually a static link, or it is a -Bsymbolic link
+   and the symbol is defined locally, or the symbol was forced to be
+   local because of a version file.  */
+#define RISCV_RESOLVED_LOCALLY(INFO, H) \
+  (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (elf_hash_table (INFO)->dynamic_sections_created, \
+				     bfd_link_pic (INFO), (H)) \
+   || (bfd_link_pic (INFO) \
+       && SYMBOL_REFERENCES_LOCAL ((INFO), (H))))
+
 /* Internal relocations used exclusively by the relaxation pass.  */
 #define R_RISCV_DELETE (R_RISCV_max + 1)
 
@@ -835,48 +908,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		}
 	    }
 
-	  /* If we are creating a shared library, and this is a reloc
-	     against a global symbol, or a non PC relative reloc
-	     against a local symbol, then we need to copy the reloc
-	     into the shared library.  However, if we are linking with
-	     -Bsymbolic, we do not need to copy a reloc against a
-	     global symbol which is defined in an object we are
-	     including in the link (i.e., DEF_REGULAR is set).  At
-	     this point we have not seen all the input files, so it is
-	     possible that DEF_REGULAR is not set now but will be set
-	     later (it is never cleared).  In case of a weak definition,
-	     DEF_REGULAR may be cleared later by a strong definition in
-	     a shared library.  We account for that possibility below by
-	     storing information in the relocs_copied field of the hash
-	     table entry.  A similar situation occurs when creating
-	     shared libraries and symbol visibility changes render the
-	     symbol local.
-
-	     If on the other hand, we are creating an executable, we
-	     may need to keep relocations for symbols satisfied by a
-	     dynamic library if we manage to avoid copy relocs for the
-	     symbol.
-
-	     Generate dynamic pointer relocation against STT_GNU_IFUNC
-	     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)
-		   || (h != NULL
-		       && (!info->symbolic
-			   || h->root.type == bfd_link_hash_defweak
-			   || !h->def_regular))))
-	      || (!bfd_link_pic (info)
-		  && (sec->flags & SEC_ALLOC) != 0
-		  && h != NULL
-		  && (h->root.type == bfd_link_hash_defweak
-		      || !h->def_regular))
-	      || (!bfd_link_pic (info)
-		  && h != NULL
-		  && h->type == STT_GNU_IFUNC
-		  && (sec->flags & SEC_CODE) == 0))
+	  reloc_howto_type *r = riscv_elf_rtype_to_howto (abfd, r_type);
+	  if (RISCV_NEED_DYNAMIC_RELOC (r->pc_relative, info, h, sec))
 	    {
 	      struct elf_dyn_relocs *p;
 	      struct elf_dyn_relocs **head;
@@ -2329,23 +2362,14 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_GOT_HI20:
 	  if (h != NULL)
 	    {
-	      bool dyn, pic;
-
 	      off = h->got.offset;
 	      BFD_ASSERT (off != (bfd_vma) -1);
-	      dyn = elf_hash_table (info)->dynamic_sections_created;
-	      pic = bfd_link_pic (info);
 
-	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h)
-		  || (pic && SYMBOL_REFERENCES_LOCAL (info, h)))
+	      if (RISCV_RESOLVED_LOCALLY (info, h))
 		{
-		  /* This is actually a static link, or it is a
-		     -Bsymbolic link and the symbol is defined
-		     locally, or the symbol was forced to be local
-		     because of a version file.  We must initialize
-		     this entry in the global offset table.  Since the
-		     offset must always be a multiple of the word size,
-		     we use the least significant bit to record whether
+		  /* We must initialize this entry in the global offset table.
+		     Since the offset must always be a multiple of the word
+		     size, we use the least significant bit to record whether
 		     we have initialized it already.
 
 		     When doing a dynamic link, we create a .rela.got
@@ -2610,21 +2634,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
-	  if ((bfd_link_pic (info)
-	       && (h == NULL
-		   || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		       && !resolved_to_zero)
-		   || h->root.type != bfd_link_hash_undefweak)
-	       && (!howto->pc_relative
-		   || !SYMBOL_CALLS_LOCAL (info, h)))
-	      || (!bfd_link_pic (info)
-		  && h != NULL
-		  && h->dynindx != -1
-		  && !h->non_got_ref
-		  && ((h->def_dynamic
-		       && !h->def_regular)
-		      || h->root.type == bfd_link_hash_undefweak
-		      || h->root.type == bfd_link_hash_undefined)))
+	  if (RISCV_GENERATE_DYNAMIC_RELOC (howto->pc_relative, info, h,
+					    resolved_to_zero))
 	    {
 	      Elf_Internal_Rela outrel;
 	      asection *sreloc;
@@ -2643,10 +2654,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 
 	      if (skip_dynamic_relocation)
 		memset (&outrel, 0, sizeof outrel);
-	      else if (h != NULL && h->dynindx != -1
-		       && !(bfd_link_pic (info)
-			    && SYMBOLIC_BIND (info, h)
-			    && h->def_regular))
+	      else if (RISCV_COPY_INPUT_RELOC (info, h))
 		{
 		  outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
 		  outrel.r_addend = rel->r_addend;
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol.
  2023-03-25  0:41 [PATCH 1/3] RISC-V: Extract the ld code which are too complicated, and may be reused Nelson Chu
@ 2023-03-25  0:41 ` Nelson Chu
  2023-03-30  0:12   ` Nelson Chu
  2023-03-25  0:41 ` [PATCH 3/3] RISC-V: PR28789, Reject R_RISCV_PCREL relocations with ABS symbol in PIC/PIE Nelson Chu
  1 sibling, 1 reply; 4+ messages in thread
From: Nelson Chu @ 2023-03-25  0:41 UTC (permalink / raw)
  To: binutils, jim.wilson.gcc, palmer; +Cc: nelson

There are two improvements, which are all referenced to aarch64,

* R_RISCV_32 with non ABS symbol cannot be used under RV64 when making
  shard objects.

* Don't need dynamic relocation for R_RISCV_32/64 under RV32/RV64 when
  making shared objects, if the referenced symbol is local ABS symbol.

However, considering this link,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/341

Seems like we should makes all R_RISCV_32/64 relocs with ABS symbol
that don't need any dynamic relocations when making the shared objects.
But anyway, I just sync the current behavior as aarch64 ld, in case
there are any unexpected behaviors happen.

Passed the gcc/binutils regressions in riscv-gnu-toolchain.

bfd/
    * elfnn-riscv.c (riscv_elf_check_relocs): Only allow R_RISCV_32 with ABS
    symbol under RV64.
    (riscv_elf_relocate_section): R_RISCV_32/64 with local ABS symbol under
    RV32/RV64 doesn't need any dynamic relocation when making shared objects.
    I just make the implementations similar to other targets, so that will be
    more easy to mainatain.
ld/
    * testsuite/ld-riscv-elf/data-reloc*: New testcases.
    * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Added new data-reloc* testcases,
    and need to make ifunc-seperate* testcases work for rv32.
    * testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s: Likewise.
    * testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s: Likewise.
---
 bfd/elfnn-riscv.c                             | 61 ++++++++++++++++---
 .../ld-riscv-elf/data-reloc-rv32-pic.d        | 21 +++++++
 .../ld-riscv-elf/data-reloc-rv32-pie.d        | 18 ++++++
 .../ld-riscv-elf/data-reloc-rv32-symbolic.d   | 21 +++++++
 .../ld-riscv-elf/data-reloc-rv64-abs32-pic.d  | 13 ++++
 .../ld-riscv-elf/data-reloc-rv64-addr32-pic.d |  4 ++
 .../ld-riscv-elf/data-reloc-rv64-pic.d        | 21 +++++++
 .../ld-riscv-elf/data-reloc-rv64-pie.d        | 21 +++++++
 .../ld-riscv-elf/data-reloc-rv64-symbolic.d   | 21 +++++++
 .../data-reloc-rv64-undef32-pic.d             |  4 ++
 ld/testsuite/ld-riscv-elf/data-reloc.s        | 22 +++++++
 .../ifunc-seperate-caller-nonplt.s            |  2 +-
 .../ld-riscv-elf/ifunc-seperate-caller-plt.s  |  2 +-
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    | 15 +++++
 14 files changed, 236 insertions(+), 10 deletions(-)
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
 create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 59e949a2cb5..00f034a6751 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -734,6 +734,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       unsigned int r_type;
       unsigned int r_symndx;
       struct elf_link_hash_entry *h;
+      bool is_abs_symbol = false;
 
       r_symndx = ELFNN_R_SYM (rel->r_info);
       r_type = ELFNN_R_TYPE (rel->r_info);
@@ -753,6 +754,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  if (isym == NULL)
 	    return false;
 
+	  is_abs_symbol = isym->st_shndx == SHN_ABS ? true : false;
+
 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
 	    {
@@ -778,6 +781,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  while (h->root.type == bfd_link_hash_indirect
 		 || h->root.type == bfd_link_hash_warning)
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+	  is_abs_symbol = bfd_is_abs_symbol (&h->root) ? true : false;
 	}
 
       if (h != NULL)
@@ -879,13 +884,31 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case R_RISCV_HI20:
 	  if (bfd_link_pic (info))
 	    return bad_static_reloc (abfd, r_type, h);
-	  /* Fall through.  */
+	  goto static_reloc;
+
+	case R_RISCV_32:
+	  if (ARCH_SIZE > 32
+	      && bfd_link_pic (info)
+	      && (sec->flags & SEC_ALLOC) != 0)
+	    {
+	      if (is_abs_symbol)
+		break;
+
+	      reloc_howto_type *r_t = riscv_elf_rtype_to_howto (abfd, r_type);
+	      _bfd_error_handler
+		(_("%pB: relocation %s against non-absolute symbol `%s' can "
+		   "not be used in RVNN when making a shared object"),
+		 abfd, r_t ? r_t->name : _("<unknown>"),
+		 h != NULL ? h->root.root.string : "a local symbol");
+	      bfd_set_error (bfd_error_bad_value);
+	      return false;
+	    }
+	  goto static_reloc;
 
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
 	case R_RISCV_RELATIVE:
 	case R_RISCV_64:
-	case R_RISCV_32:
 	  /* Fall through.  */
 
 	static_reloc:
@@ -2630,6 +2653,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  break;
 
 	case R_RISCV_32:
+	  /* Non ABS symbol should be blocked in check_relocs.  */
+	  if (ARCH_SIZE > 32)
+	    break;
+	  /* Fall through.  */
+
 	case R_RISCV_64:
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
@@ -2639,7 +2667,6 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    {
 	      Elf_Internal_Rela outrel;
 	      asection *sreloc;
-	      bool skip_static_relocation, skip_dynamic_relocation;
 
 	      /* When generating a shared object, these relocations
 		 are copied into the output file to be resolved at run
@@ -2648,26 +2675,44 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	      outrel.r_offset =
 		_bfd_elf_section_offset (output_bfd, info, input_section,
 					 rel->r_offset);
-	      skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
-	      skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
+	      bool skip = false;
+	      bool relocate = false;
+	      if (outrel.r_offset == (bfd_vma) -1)
+		skip = true;
+	      else if (outrel.r_offset == (bfd_vma) -2)
+		{
+		  skip = true;
+		  relocate = true;
+		}
+	      else if (h != NULL && bfd_is_abs_symbol (&h->root))
+		{
+		  /* Don't need dynamic reloc when the ABS symbol is
+		     non-dynamic or forced to local.  Maybe just use
+		     SYMBOL_REFERENCES_LOCAL to check?  */
+		  skip = (h->forced_local || (h->dynindx == -1));
+		  relocate = skip;
+		}
+
 	      outrel.r_offset += sec_addr (input_section);
 
-	      if (skip_dynamic_relocation)
-		memset (&outrel, 0, sizeof outrel);
+	      if (skip)
+		memset (&outrel, 0, sizeof outrel);	/* R_RISCV_NONE.  */
 	      else if (RISCV_COPY_INPUT_RELOC (info, h))
 		{
+		  /* Maybe just use !SYMBOL_REFERENCES_LOCAL to check?  */
 		  outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
 		  outrel.r_addend = rel->r_addend;
 		}
 	      else
 		{
+		  /* This symbol is local, or marked to become local.  */
 		  outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
 		  outrel.r_addend = relocation + rel->r_addend;
 		}
 
 	      sreloc = elf_section_data (input_section)->sreloc;
 	      riscv_elf_append_rela (output_bfd, sreloc, &outrel);
-	      if (skip_static_relocation)
+	      if (!relocate)
 		continue;
 	    }
 	  break;
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
new file mode 100644
index 00000000000..13f34e052b7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
@@ -0,0 +1,21 @@
+#source: data-reloc.s
+#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
+#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+    8000:	00000000          	.word	0x00000000
+			8000: R_RISCV_32	addr_globl
+
+0+8004 <addr_local>:
+	...
+			8004: R_RISCV_RELATIVE	\*ABS\*\+0x8004
+			8008: R_RISCV_32	abs
+    800c:	00000200          	.word	0x00000200
+    8010:	00000000          	.word	0x00000000
+			8010: R_RISCV_32	undef
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
new file mode 100644
index 00000000000..1e8f35a9c18
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
@@ -0,0 +1,18 @@
+#source: data-reloc.s
+#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1
+#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+    8000:	00000000          	.word	0x00000000
+			8000: R_RISCV_RELATIVE	\*ABS\*\+0x8000
+
+0+8004 <addr_local>:
+    8004:	00000000          	.word	0x00000000
+			8004: R_RISCV_RELATIVE	\*ABS\*\+0x8004
+    8008:	00000100          	.word	0x00000100
+    800c:	00000200          	.word	0x00000200
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
new file mode 100644
index 00000000000..5c947e2b93b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
@@ -0,0 +1,21 @@
+#source: data-reloc.s
+#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
+#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+    8000:	00000000          	.word	0x00000000
+			8000: R_RISCV_RELATIVE	\*ABS\*\+0x8000
+
+0+8004 <addr_local>:
+	...
+			8004: R_RISCV_RELATIVE	\*ABS\*\+0x8004
+			8008: R_RISCV_RELATIVE	\*ABS\*\+0x100
+    800c:	00000200          	.word	0x00000200
+    8010:	00000000          	.word	0x00000000
+			8010: R_RISCV_32	undef
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
new file mode 100644
index 00000000000..1d3686de353
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
@@ -0,0 +1,13 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __abs__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <.text>:
+    8000:	00000100          	.word	0x00000100
+    8004:	00000200          	.word	0x00000200
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
new file mode 100644
index 00000000000..39b50e33044
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
@@ -0,0 +1,4 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __addr__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0  -shared
+#error: .*relocation R_RISCV_32 against non-absolute symbol `addr_globl' can not be used in RV64 when making a shared object.*
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
new file mode 100644
index 00000000000..dab0ccc9260
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
@@ -0,0 +1,21 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+	...
+			8000: R_RISCV_64	addr_globl
+
+0+8008 <addr_local>:
+	...
+			8008: R_RISCV_RELATIVE	\*ABS\*\+0x8008
+			8010: R_RISCV_64	abs
+    8018:	00000200          	.word	0x00000200
+	...
+			8020: R_RISCV_64	undef
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
new file mode 100644
index 00000000000..fd6c470f680
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
@@ -0,0 +1,21 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+	...
+			8000: R_RISCV_RELATIVE	\*ABS\*\+0x8000
+
+0+8008 <addr_local>:
+	...
+			8008: R_RISCV_RELATIVE	\*ABS\*\+0x8008
+    8010:	00000100          	.word	0x00000100
+    8014:	00000000          	.word	0x00000000
+    8018:	00000200          	.word	0x00000200
+    801c:	00000000          	.word	0x00000000
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
new file mode 100644
index 00000000000..5d41f869b72
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
@@ -0,0 +1,21 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
+#objdump: -dR
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+8000 <addr_globl>:
+	...
+			8000: R_RISCV_RELATIVE	\*ABS\*\+0x8000
+
+0+8008 <addr_local>:
+	...
+			8008: R_RISCV_RELATIVE	\*ABS\*\+0x8008
+			8010: R_RISCV_RELATIVE	\*ABS\*\+0x100
+    8018:	00000200          	.word	0x00000200
+	...
+			8020: R_RISCV_64	undef
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
new file mode 100644
index 00000000000..e5de484142c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
@@ -0,0 +1,4 @@
+#source: data-reloc.s
+#as: -march=rv64i -mabi=lp64 -defsym __undef__=1
+#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0  -shared
+#error: .*relocation R_RISCV_32 against non-absolute symbol `undef' can not be used in RV64 when making a shared object.*
diff --git a/ld/testsuite/ld-riscv-elf/data-reloc.s b/ld/testsuite/ld-riscv-elf/data-reloc.s
new file mode 100644
index 00000000000..37151500f77
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/data-reloc.s
@@ -0,0 +1,22 @@
+	.macro	DATA symbol
+.ifdef __64_bit__
+	.quad	\symbol
+.else
+	.word	\symbol
+.endif
+	.endm
+.ifdef __addr__
+	.globl  addr_globl
+addr_globl:
+	DATA	addr_globl
+addr_local:
+	DATA	addr_local
+.endif
+.ifdef __abs__
+	.hidden abs_local
+	DATA	abs
+	DATA	abs_local
+.endif
+.ifdef __undef__
+	DATA	undef
+.endif
diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
index 23c7254ad5b..df0d33b97e2 100644
--- a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
+++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
@@ -20,4 +20,4 @@ main:
 
 	.data
 foo_addr:
-	.long	foo
+	.quad	foo
diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
index 8aa64034706..cc1608a9803 100644
--- a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
+++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
@@ -23,4 +23,4 @@ main:
 
 	.data
 foo_addr:
-	.long	foo
+	.quad	foo
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 5dd6144efd3..1b2a5ce2cb2 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -217,6 +217,16 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "shared-lib-nopic-03"
     run_dump_test "shared-lib-nopic-04"
 
+    run_dump_test "data-reloc-rv64-pic"
+    run_dump_test "data-reloc-rv64-pie"
+    run_dump_test "data-reloc-rv64-symbolic"
+    run_dump_test "data-reloc-rv32-pic"
+    run_dump_test "data-reloc-rv32-pie"
+    run_dump_test "data-reloc-rv32-symbolic"
+    run_dump_test "data-reloc-rv64-abs32-pic"
+    run_dump_test "data-reloc-rv64-addr32-pic"
+    run_dump_test "data-reloc-rv64-undef32-pic"
+
     # IFUNC testcases.
     # Check IFUNC by single type relocs.
     run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
@@ -270,6 +280,11 @@ if [istarget "riscv*-*-*"] {
     run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie
     run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic
 
+    # TODO: Make the following tests work under RV32.
+    if [istarget "riscv32-*-*"] {
+      return
+    }
+
     # Setup shared libraries.
     run_ld_link_tests {
        { "Build shared library for IFUNC non-PLT caller"
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] RISC-V: PR28789, Reject R_RISCV_PCREL relocations with ABS symbol in PIC/PIE.
  2023-03-25  0:41 [PATCH 1/3] RISC-V: Extract the ld code which are too complicated, and may be reused Nelson Chu
  2023-03-25  0:41 ` [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol Nelson Chu
@ 2023-03-25  0:41 ` Nelson Chu
  1 sibling, 0 replies; 4+ messages in thread
From: Nelson Chu @ 2023-03-25  0:41 UTC (permalink / raw)
  To: binutils, jim.wilson.gcc, palmer; +Cc: nelson, Palmer Dabbelt

From: Palmer Dabbelt <palmer@rivosinc.com>

The non-preemptible SHN_ABS symbol with a pc-relative relocation should be
disallowed when generating shared object (pic and pie).  Generally, the
following cases, which refer to pr25749, will cause a symbol be
non-preemptible,

* -pie, or -shared with -symbolic
* STV_HIDDEN, STV_INTERNAL, STV_PROTECTED
* Have dynamic symbol table, but without the symbol
* VER_NDX_LOCAL

However, PCREL_HI20/LO12 relocs are always bind locally when generating
shared object, so not only the non-preemptible absolute symbol need to
be disallowed, all absolute symbol references need but except that they
are defined in linker script.  If we also disallow the absolute symbol
in linker script, then the glibc-linux toolchain build failed, so regard
them as pc-relative symbols, just like what x86 did.

Maybe we should add this check for all pc-relative relocations, rather
than just handle in R_RISCV_PCREL relocs.  Ideally, since the value of
SHN_ABS symbol is a constant, only S - A relocations should be allowed
in the shared object, so only BFD_RELOC_8/16/32/64 are allowed, which
means R_RISCV_32/R_RISCV_64.

bfd/
    PR 28789
    * elfnn-riscv.c (riscv_elf_check_relocs): The absolute symbol cannot be
    referneced with pc-relative relocation when generating shared object.
ld/
    PR 28789
    * ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
    * ld/testsuite/ld-riscv-elf/pcrel-reloc*: New testcases.
---
 bfd/elfnn-riscv.c                             | 41 +++++++++++++++++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  7 ++++
 .../ld-riscv-elf/pcrel-reloc-abs-nopie.d      | 14 +++++++
 .../ld-riscv-elf/pcrel-reloc-abs-pie.d        |  5 +++
 ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s   |  2 +
 .../ld-riscv-elf/pcrel-reloc-rel-nopie.d      | 14 +++++++
 .../ld-riscv-elf/pcrel-reloc-rel-pie.d        | 14 +++++++
 ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s   |  9 ++++
 ld/testsuite/ld-riscv-elf/pcrel-reloc.s       |  5 +++
 9 files changed, 111 insertions(+)
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s
 create mode 100644 ld/testsuite/ld-riscv-elf/pcrel-reloc.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 00f034a6751..0dd9b27c8ae 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -862,6 +862,47 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		 ifunc symbol.  */
 	      h->plt.refcount += 1;
 	    }
+
+	  /* The non-preemptible absolute symbol shouldn't be referneced with
+	     pc-relative relocation when generating shared object.  However,
+	     PCREL_HI20/LO12 relocs are always bind locally when generating
+	     shared object, so all absolute symbol referenced need to be
+	     disallowed, except they are defined in linker script.
+
+	     Maybe we should add this check for all pc-relative relocations,
+	     please see pr28789 and pr25749 for details.  */
+	  if (bfd_link_pic (info)
+	      /* (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h))  */
+	      && is_abs_symbol)
+	    {
+	      if (h != NULL && (h)->root.ldscript_def)
+		/* Disallow the absolute symbol defined in linker script here
+		   will cause the glibc-linux toolchain build failed, so regard
+		   them as pc-relative symbols, just like what x86 did.  */
+		;
+	      else
+		{
+		  const char *name;
+		  if (h->root.root.string)
+		    name = h->root.root.string;
+		  else
+		    {
+		      Elf_Internal_Sym *sym;
+		      sym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd,
+						   r_symndx);
+		      name = bfd_elf_sym_name (abfd, symtab_hdr, sym, NULL);
+		    }
+
+		  reloc_howto_type *r_t =
+			riscv_elf_rtype_to_howto (abfd, r_type);
+		  _bfd_error_handler
+		    (_("%pB: relocation %s against absolute symbol `%s' can "
+		       "not be used when making a shared object"),
+		     abfd, r_t ? r_t->name : _("<unknown>"), name);
+		  bfd_set_error (bfd_error_bad_value);
+		  return false;
+		}
+	    }
 	  /* Fall through.  */
 
 	case R_RISCV_JAL:
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 1b2a5ce2cb2..43572c5286b 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -308,4 +308,11 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "ifunc-seperate-plt-pic"
     run_dump_test "ifunc-seperate-pcrel-pie"
     run_dump_test "ifunc-seperate-pcrel-pic"
+
+    # Tests related to mixing medany code into position-independent targets,
+    # where it's not always possible to generate correct addressing sequences.
+    run_dump_test "pcrel-reloc-rel-nopie"
+    run_dump_test "pcrel-reloc-rel-pie"
+    run_dump_test "pcrel-reloc-abs-nopie"
+    run_dump_test "pcrel-reloc-abs-pie"
 }
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d
new file mode 100644
index 00000000000..54026388b7a
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-nopie.d
@@ -0,0 +1,14 @@
+#source: pcrel-reloc.s
+#source: pcrel-reloc-abs.s
+#as: -march=rv64i -mabi=lp64
+#ld: -melf64lriscv --no-pie --no-relax
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <_start>:
+.*auipc.*
+.*lw.*# [0-9a-f]* <sym>
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d
new file mode 100644
index 00000000000..7f5eaa321f7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs-pie.d
@@ -0,0 +1,5 @@
+#source: pcrel-reloc.s
+#source: pcrel-reloc-abs.s
+#as: -march=rv64i -mabi=lp64
+#ld: -melf64lriscv --pie --no-relax
+#error: .*relocation R_RISCV_PCREL_HI20 against absolute symbol `sym' can not be used when making a shared objec.*t
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s
new file mode 100644
index 00000000000..1df32a1a3fb
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-abs.s
@@ -0,0 +1,2 @@
+.global sym
+.set sym,0x8000
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d
new file mode 100644
index 00000000000..ab2a3774cdd
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-nopie.d
@@ -0,0 +1,14 @@
+#source: pcrel-reloc.s
+#source: pcrel-reloc-rel.s
+#as: -march=rv64i -mabi=lp64
+#ld: -melf64lriscv --no-pie --no-relax
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <_start>:
+.*auipc.*
+.*lw.*# [0-9a-f]* <sym>
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d
new file mode 100644
index 00000000000..aec612d4d2c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel-pie.d
@@ -0,0 +1,14 @@
+#source: pcrel-reloc.s
+#source: pcrel-reloc-rel.s
+#as: -march=rv64i -mabi=lp64
+#ld: -melf64lriscv --pie --no-relax
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <_start>:
+.*auipc.*
+.*lw.*# [0-9a-f]* <sym>
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s
new file mode 100644
index 00000000000..fb0e6c09f22
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc-rel.s
@@ -0,0 +1,9 @@
+.data
+# Makes sure "sym" doesn't end up at the beginning of ".data", as that makes it
+# tough to then later detect it from scripts.
+.global buf
+buf:
+    .fill 8192, 4, 1
+.global sym
+sym:
+    .fill 8192, 4, 2
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-reloc.s b/ld/testsuite/ld-riscv-elf/pcrel-reloc.s
new file mode 100644
index 00000000000..db2103bafd1
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-reloc.s
@@ -0,0 +1,5 @@
+.text
+.global _start
+_start:
+    auipc t0, %pcrel_hi(sym)
+    lw t0, %pcrel_lo(_start)(t0)
-- 
2.37.1 (Apple Git-137.1)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol.
  2023-03-25  0:41 ` [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol Nelson Chu
@ 2023-03-30  0:12   ` Nelson Chu
  0 siblings, 0 replies; 4+ messages in thread
From: Nelson Chu @ 2023-03-30  0:12 UTC (permalink / raw)
  To: binutils, jim.wilson.gcc, palmer

At least passed the regressions of riscv-gnu-toolchain for this series
of patches, so committed them since they should be the correct way to
go.  The series of patches are listed as follows,
* RISC-V: Extract the ld code which are too complicated, and may be reused.
* RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol.
* RISC-V: PR28789, Reject R_RISCV_PCREL relocations with ABS symbol in PIC/PIE.

Thanks
Nelson

On Sat, Mar 25, 2023 at 8:41 AM Nelson Chu <nelson@rivosinc.com> wrote:
>
> There are two improvements, which are all referenced to aarch64,
>
> * R_RISCV_32 with non ABS symbol cannot be used under RV64 when making
>   shard objects.
>
> * Don't need dynamic relocation for R_RISCV_32/64 under RV32/RV64 when
>   making shared objects, if the referenced symbol is local ABS symbol.
>
> However, considering this link,
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/341
>
> Seems like we should makes all R_RISCV_32/64 relocs with ABS symbol
> that don't need any dynamic relocations when making the shared objects.
> But anyway, I just sync the current behavior as aarch64 ld, in case
> there are any unexpected behaviors happen.
>
> Passed the gcc/binutils regressions in riscv-gnu-toolchain.
>
> bfd/
>     * elfnn-riscv.c (riscv_elf_check_relocs): Only allow R_RISCV_32 with ABS
>     symbol under RV64.
>     (riscv_elf_relocate_section): R_RISCV_32/64 with local ABS symbol under
>     RV32/RV64 doesn't need any dynamic relocation when making shared objects.
>     I just make the implementations similar to other targets, so that will be
>     more easy to mainatain.
> ld/
>     * testsuite/ld-riscv-elf/data-reloc*: New testcases.
>     * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Added new data-reloc* testcases,
>     and need to make ifunc-seperate* testcases work for rv32.
>     * testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s: Likewise.
>     * testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s: Likewise.
> ---
>  bfd/elfnn-riscv.c                             | 61 ++++++++++++++++---
>  .../ld-riscv-elf/data-reloc-rv32-pic.d        | 21 +++++++
>  .../ld-riscv-elf/data-reloc-rv32-pie.d        | 18 ++++++
>  .../ld-riscv-elf/data-reloc-rv32-symbolic.d   | 21 +++++++
>  .../ld-riscv-elf/data-reloc-rv64-abs32-pic.d  | 13 ++++
>  .../ld-riscv-elf/data-reloc-rv64-addr32-pic.d |  4 ++
>  .../ld-riscv-elf/data-reloc-rv64-pic.d        | 21 +++++++
>  .../ld-riscv-elf/data-reloc-rv64-pie.d        | 21 +++++++
>  .../ld-riscv-elf/data-reloc-rv64-symbolic.d   | 21 +++++++
>  .../data-reloc-rv64-undef32-pic.d             |  4 ++
>  ld/testsuite/ld-riscv-elf/data-reloc.s        | 22 +++++++
>  .../ifunc-seperate-caller-nonplt.s            |  2 +-
>  .../ld-riscv-elf/ifunc-seperate-caller-plt.s  |  2 +-
>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    | 15 +++++
>  14 files changed, 236 insertions(+), 10 deletions(-)
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/data-reloc.s
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 59e949a2cb5..00f034a6751 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -734,6 +734,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>        unsigned int r_type;
>        unsigned int r_symndx;
>        struct elf_link_hash_entry *h;
> +      bool is_abs_symbol = false;
>
>        r_symndx = ELFNN_R_SYM (rel->r_info);
>        r_type = ELFNN_R_TYPE (rel->r_info);
> @@ -753,6 +754,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>           if (isym == NULL)
>             return false;
>
> +         is_abs_symbol = isym->st_shndx == SHN_ABS ? true : false;
> +
>           /* Check relocation against local STT_GNU_IFUNC symbol.  */
>           if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
>             {
> @@ -778,6 +781,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>           while (h->root.type == bfd_link_hash_indirect
>                  || h->root.type == bfd_link_hash_warning)
>             h = (struct elf_link_hash_entry *) h->root.u.i.link;
> +
> +         is_abs_symbol = bfd_is_abs_symbol (&h->root) ? true : false;
>         }
>
>        if (h != NULL)
> @@ -879,13 +884,31 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
>         case R_RISCV_HI20:
>           if (bfd_link_pic (info))
>             return bad_static_reloc (abfd, r_type, h);
> -         /* Fall through.  */
> +         goto static_reloc;
> +
> +       case R_RISCV_32:
> +         if (ARCH_SIZE > 32
> +             && bfd_link_pic (info)
> +             && (sec->flags & SEC_ALLOC) != 0)
> +           {
> +             if (is_abs_symbol)
> +               break;
> +
> +             reloc_howto_type *r_t = riscv_elf_rtype_to_howto (abfd, r_type);
> +             _bfd_error_handler
> +               (_("%pB: relocation %s against non-absolute symbol `%s' can "
> +                  "not be used in RVNN when making a shared object"),
> +                abfd, r_t ? r_t->name : _("<unknown>"),
> +                h != NULL ? h->root.root.string : "a local symbol");
> +             bfd_set_error (bfd_error_bad_value);
> +             return false;
> +           }
> +         goto static_reloc;
>
>         case R_RISCV_COPY:
>         case R_RISCV_JUMP_SLOT:
>         case R_RISCV_RELATIVE:
>         case R_RISCV_64:
> -       case R_RISCV_32:
>           /* Fall through.  */
>
>         static_reloc:
> @@ -2630,6 +2653,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
>           break;
>
>         case R_RISCV_32:
> +         /* Non ABS symbol should be blocked in check_relocs.  */
> +         if (ARCH_SIZE > 32)
> +           break;
> +         /* Fall through.  */
> +
>         case R_RISCV_64:
>           if ((input_section->flags & SEC_ALLOC) == 0)
>             break;
> @@ -2639,7 +2667,6 @@ riscv_elf_relocate_section (bfd *output_bfd,
>             {
>               Elf_Internal_Rela outrel;
>               asection *sreloc;
> -             bool skip_static_relocation, skip_dynamic_relocation;
>
>               /* When generating a shared object, these relocations
>                  are copied into the output file to be resolved at run
> @@ -2648,26 +2675,44 @@ riscv_elf_relocate_section (bfd *output_bfd,
>               outrel.r_offset =
>                 _bfd_elf_section_offset (output_bfd, info, input_section,
>                                          rel->r_offset);
> -             skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
> -             skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
> +             bool skip = false;
> +             bool relocate = false;
> +             if (outrel.r_offset == (bfd_vma) -1)
> +               skip = true;
> +             else if (outrel.r_offset == (bfd_vma) -2)
> +               {
> +                 skip = true;
> +                 relocate = true;
> +               }
> +             else if (h != NULL && bfd_is_abs_symbol (&h->root))
> +               {
> +                 /* Don't need dynamic reloc when the ABS symbol is
> +                    non-dynamic or forced to local.  Maybe just use
> +                    SYMBOL_REFERENCES_LOCAL to check?  */
> +                 skip = (h->forced_local || (h->dynindx == -1));
> +                 relocate = skip;
> +               }
> +
>               outrel.r_offset += sec_addr (input_section);
>
> -             if (skip_dynamic_relocation)
> -               memset (&outrel, 0, sizeof outrel);
> +             if (skip)
> +               memset (&outrel, 0, sizeof outrel);     /* R_RISCV_NONE.  */
>               else if (RISCV_COPY_INPUT_RELOC (info, h))
>                 {
> +                 /* Maybe just use !SYMBOL_REFERENCES_LOCAL to check?  */
>                   outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
>                   outrel.r_addend = rel->r_addend;
>                 }
>               else
>                 {
> +                 /* This symbol is local, or marked to become local.  */
>                   outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
>                   outrel.r_addend = relocation + rel->r_addend;
>                 }
>
>               sreloc = elf_section_data (input_section)->sreloc;
>               riscv_elf_append_rela (output_bfd, sreloc, &outrel);
> -             if (skip_static_relocation)
> +             if (!relocate)
>                 continue;
>             }
>           break;
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
> new file mode 100644
> index 00000000000..13f34e052b7
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
> @@ -0,0 +1,21 @@
> +#source: data-reloc.s
> +#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
> +#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +    8000:      00000000                .word   0x00000000
> +                       8000: R_RISCV_32        addr_globl
> +
> +0+8004 <addr_local>:
> +       ...
> +                       8004: R_RISCV_RELATIVE  \*ABS\*\+0x8004
> +                       8008: R_RISCV_32        abs
> +    800c:      00000200                .word   0x00000200
> +    8010:      00000000                .word   0x00000000
> +                       8010: R_RISCV_32        undef
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
> new file mode 100644
> index 00000000000..1e8f35a9c18
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
> @@ -0,0 +1,18 @@
> +#source: data-reloc.s
> +#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1
> +#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +    8000:      00000000                .word   0x00000000
> +                       8000: R_RISCV_RELATIVE  \*ABS\*\+0x8000
> +
> +0+8004 <addr_local>:
> +    8004:      00000000                .word   0x00000000
> +                       8004: R_RISCV_RELATIVE  \*ABS\*\+0x8004
> +    8008:      00000100                .word   0x00000100
> +    800c:      00000200                .word   0x00000200
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
> new file mode 100644
> index 00000000000..5c947e2b93b
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
> @@ -0,0 +1,21 @@
> +#source: data-reloc.s
> +#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
> +#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +    8000:      00000000                .word   0x00000000
> +                       8000: R_RISCV_RELATIVE  \*ABS\*\+0x8000
> +
> +0+8004 <addr_local>:
> +       ...
> +                       8004: R_RISCV_RELATIVE  \*ABS\*\+0x8004
> +                       8008: R_RISCV_RELATIVE  \*ABS\*\+0x100
> +    800c:      00000200                .word   0x00000200
> +    8010:      00000000                .word   0x00000000
> +                       8010: R_RISCV_32        undef
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
> new file mode 100644
> index 00000000000..1d3686de353
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
> @@ -0,0 +1,13 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __abs__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <.text>:
> +    8000:      00000100                .word   0x00000100
> +    8004:      00000200                .word   0x00000200
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
> new file mode 100644
> index 00000000000..39b50e33044
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
> @@ -0,0 +1,4 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __addr__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0  -shared
> +#error: .*relocation R_RISCV_32 against non-absolute symbol `addr_globl' can not be used in RV64 when making a shared object.*
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
> new file mode 100644
> index 00000000000..dab0ccc9260
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
> @@ -0,0 +1,21 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +       ...
> +                       8000: R_RISCV_64        addr_globl
> +
> +0+8008 <addr_local>:
> +       ...
> +                       8008: R_RISCV_RELATIVE  \*ABS\*\+0x8008
> +                       8010: R_RISCV_64        abs
> +    8018:      00000200                .word   0x00000200
> +       ...
> +                       8020: R_RISCV_64        undef
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
> new file mode 100644
> index 00000000000..fd6c470f680
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
> @@ -0,0 +1,21 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +       ...
> +                       8000: R_RISCV_RELATIVE  \*ABS\*\+0x8000
> +
> +0+8008 <addr_local>:
> +       ...
> +                       8008: R_RISCV_RELATIVE  \*ABS\*\+0x8008
> +    8010:      00000100                .word   0x00000100
> +    8014:      00000000                .word   0x00000000
> +    8018:      00000200                .word   0x00000200
> +    801c:      00000000                .word   0x00000000
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
> new file mode 100644
> index 00000000000..5d41f869b72
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
> @@ -0,0 +1,21 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
> +#objdump: -dR
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+8000 <addr_globl>:
> +       ...
> +                       8000: R_RISCV_RELATIVE  \*ABS\*\+0x8000
> +
> +0+8008 <addr_local>:
> +       ...
> +                       8008: R_RISCV_RELATIVE  \*ABS\*\+0x8008
> +                       8010: R_RISCV_RELATIVE  \*ABS\*\+0x100
> +    8018:      00000200                .word   0x00000200
> +       ...
> +                       8020: R_RISCV_64        undef
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
> new file mode 100644
> index 00000000000..e5de484142c
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
> @@ -0,0 +1,4 @@
> +#source: data-reloc.s
> +#as: -march=rv64i -mabi=lp64 -defsym __undef__=1
> +#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0  -shared
> +#error: .*relocation R_RISCV_32 against non-absolute symbol `undef' can not be used in RV64 when making a shared object.*
> diff --git a/ld/testsuite/ld-riscv-elf/data-reloc.s b/ld/testsuite/ld-riscv-elf/data-reloc.s
> new file mode 100644
> index 00000000000..37151500f77
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/data-reloc.s
> @@ -0,0 +1,22 @@
> +       .macro  DATA symbol
> +.ifdef __64_bit__
> +       .quad   \symbol
> +.else
> +       .word   \symbol
> +.endif
> +       .endm
> +.ifdef __addr__
> +       .globl  addr_globl
> +addr_globl:
> +       DATA    addr_globl
> +addr_local:
> +       DATA    addr_local
> +.endif
> +.ifdef __abs__
> +       .hidden abs_local
> +       DATA    abs
> +       DATA    abs_local
> +.endif
> +.ifdef __undef__
> +       DATA    undef
> +.endif
> diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
> index 23c7254ad5b..df0d33b97e2 100644
> --- a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
> +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s
> @@ -20,4 +20,4 @@ main:
>
>         .data
>  foo_addr:
> -       .long   foo
> +       .quad   foo
> diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
> index 8aa64034706..cc1608a9803 100644
> --- a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
> +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s
> @@ -23,4 +23,4 @@ main:
>
>         .data
>  foo_addr:
> -       .long   foo
> +       .quad   foo
> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> index 5dd6144efd3..1b2a5ce2cb2 100644
> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> @@ -217,6 +217,16 @@ if [istarget "riscv*-*-*"] {
>      run_dump_test "shared-lib-nopic-03"
>      run_dump_test "shared-lib-nopic-04"
>
> +    run_dump_test "data-reloc-rv64-pic"
> +    run_dump_test "data-reloc-rv64-pie"
> +    run_dump_test "data-reloc-rv64-symbolic"
> +    run_dump_test "data-reloc-rv32-pic"
> +    run_dump_test "data-reloc-rv32-pie"
> +    run_dump_test "data-reloc-rv32-symbolic"
> +    run_dump_test "data-reloc-rv64-abs32-pic"
> +    run_dump_test "data-reloc-rv64-addr32-pic"
> +    run_dump_test "data-reloc-rv64-undef32-pic"
> +
>      # IFUNC testcases.
>      # Check IFUNC by single type relocs.
>      run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
> @@ -270,6 +280,11 @@ if [istarget "riscv*-*-*"] {
>      run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie
>      run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic
>
> +    # TODO: Make the following tests work under RV32.
> +    if [istarget "riscv32-*-*"] {
> +      return
> +    }
> +
>      # Setup shared libraries.
>      run_ld_link_tests {
>         { "Build shared library for IFUNC non-PLT caller"
> --
> 2.37.1 (Apple Git-137.1)
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-03-30  0:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-25  0:41 [PATCH 1/3] RISC-V: Extract the ld code which are too complicated, and may be reused Nelson Chu
2023-03-25  0:41 ` [PATCH 2/3] RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol Nelson Chu
2023-03-30  0:12   ` Nelson Chu
2023-03-25  0:41 ` [PATCH 3/3] RISC-V: PR28789, Reject R_RISCV_PCREL relocations with ABS symbol in PIC/PIE Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).