[v4,7/9] RISC-V: Unify TLS handling in check_relocs.

Message ID 20240220175556.304692-8-ishitatsuyuki@gmail.com
State Unresolved
Headers
Series RISC-V: Implement TLS Descriptors. |

Checks

Context Check Description
snail/binutils-gdb-check warning Git am fail log

Commit Message

Tatsuyuki Ishi Feb. 20, 2024, 5:55 p.m. UTC
  With the introduction of transition, multiple relocation types may map to
GOT_TLS_IE or GOT_TLS_LE and it makes more sense to unify the code path to
perform checks common to them.

bfd/
	* elfnn-riscv.c (riscv_elf_check_relocs): Merge switch cases for
	TLS relocs.
---
 bfd/elfnn-riscv.c | 64 +++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 27 deletions(-)
  

Patch

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1594856ccef..1fbb0698ce1 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -662,6 +662,24 @@  riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+static char
+riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
+{
+  switch (r_type)
+    {
+      case R_RISCV_TLS_GD_HI20:
+	return GOT_TLS_GD;
+      case R_RISCV_TLS_GOT_HI20:
+	return GOT_TLS_IE;
+      case R_RISCV_TLSDESC_HI20:
+	return GOT_TLSDESC;
+      case R_RISCV_TPREL_HI20:
+	return GOT_TLS_LE;
+      default:
+	abort ();
+    }
+}
+
 static bool
 riscv_elf_record_tls_type (bfd *abfd, struct bfd_link_info *info,
 			   struct elf_link_hash_entry *h,
@@ -843,19 +861,26 @@  riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       switch (r_type)
 	{
-	case R_RISCV_TLS_GD_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_GD))
-	    return false;
-	  break;
+	  case R_RISCV_TLS_GD_HI20:
+	  case R_RISCV_TLS_GOT_HI20:
+	  case R_RISCV_TLSDESC_HI20:
+	  case R_RISCV_TPREL_HI20:
+	    {
+	      char tls_type = riscv_elf_tls_type_from_hi_reloc (r_type);
 
-	case R_RISCV_TLS_GOT_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_IE))
-	    return false;
-	  break;
+	      /* Local exec is only allowed for executables.  */
+	      if (tls_type == GOT_TLS_LE && !bfd_link_executable (info))
+		return bad_static_reloc (abfd, r_type, h);
+
+	      if (tls_type != GOT_TLS_LE
+		  && !riscv_elf_record_got_reference (abfd, info, h, r_symndx))
+		return false;
+	      if ((tls_type != GOT_TLS_LE || h != NULL)
+		  && !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+						 tls_type))
+		return false;
+	      break;
+	    }
 
 	case R_RISCV_GOT_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
@@ -864,12 +889,6 @@  riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
-	case R_RISCV_TLSDESC_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLSDESC))
-	    return false;
-	  break;
 
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
@@ -953,15 +972,6 @@  riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  goto static_reloc;
 
-	case R_RISCV_TPREL_HI20:
-	  /* This is not allowed in the pic, but okay in pie.  */
-	  if (!bfd_link_executable (info))
-	    return bad_static_reloc (abfd, r_type, h);
-	  if (h != NULL
-	      && !riscv_elf_record_tls_type (abfd, info, h, r_symndx, GOT_TLS_LE))
-	    return false;
-	  break;
-
 	case R_RISCV_HI20:
 	  if (bfd_link_pic (info))
 	    return bad_static_reloc (abfd, r_type, h);