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] [ARC] More fixes for TLS.


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

commit d07b621f4cc585607c7eee7cc58ce54a7dde52f5
Author: Cupertino Miranda <cmiranda@synopsys.com>
Date:   Thu Oct 4 10:17:03 2018 +0100

    [ARC] More fixes for TLS.
    
    Added warning for static TLS reloc.
    
    Fixed issue related to TLS and partial static linking of libraries:
      This issue was detected when throwing exceptions in C++ while linking with
      -static-libstdc++.
      TLS relocation from the libstdc++ wasn't being patched as local now that it was
      static linked with the executable.
    
    Fix for TLS with static and pie. Problem introduced by earlier patch:
      Fixes the following glibc tests:
       - elf/tst-tls1-static
    
    bfd/
        xxxx-xx-xx  Cupertino Miranda  <cmiranda@synopsys.com>
    
    	    * arc-got.h (arc_got_entry_type_for_reloc): Changed to
    	      correct static TLS relocs.
                * elf32-arc.c (elf_arc_check_relocs): Introduced warning to
    	      TLS relocs which require -fPIC.
    	      (arc_create_forced_local_got_entries_for_tls): Created.
    	      Traverses list of GOT entries to be resolved statically
    	      when needed.
    	      (elf_arc_finish_dynamic_sections): Changed. Calls
    	      arc_create_forced_local_got_entries_for_tls for each known
    	      possibly GOT symbol.

Diff:
---
 bfd/arc-got.h   |  33 +++++++++-------
 bfd/elf32-arc.c | 116 +++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 105 insertions(+), 44 deletions(-)

diff --git a/bfd/arc-got.h b/bfd/arc-got.h
index 69e9aa3..253578b 100644
--- a/bfd/arc-got.h
+++ b/bfd/arc-got.h
@@ -208,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto)
 		     __LINE__, name_for_global_symbol (H));		\
       }									\
     if (H)								\
-      if (h->dynindx == -1 && !h->forced_local)				\
+      if (H->dynindx == -1 && !H->forced_local)				\
 	if (! bfd_elf_link_record_dynamic_symbol (info, H))		\
 	  return FALSE;							\
      htab->s##SECNAME->size += 4;					\
@@ -284,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **	   list_p,
   BFD_ASSERT (entry);
 
   if (h == NULL
+      || h->forced_local == TRUE
       || (! elf_hash_table (info)->dynamic_sections_created
 	  || (bfd_link_pic (info)
 	      && SYMBOL_REFERENCES_LOCAL (info, h))))
@@ -331,27 +332,31 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **	   list_p,
 		BFD_ASSERT (tls_sec && tls_sec->output_section);
 		bfd_vma sec_vma = tls_sec->output_section->vma;
 
-		bfd_put_32 (output_bfd,
+		if (h == NULL || h->forced_local
+		   || !elf_hash_table (info)->dynamic_sections_created)
+		  {
+		    bfd_put_32 (output_bfd,
 			    sym_value - sec_vma
 			    + (elf_hash_table (info)->dynamic_sections_created
 			       ? 0
-			       : (align_power (TCB_SIZE,
+			       : (align_power (0,
 					       tls_sec->alignment_power))),
 			    htab->sgot->contents + entry->offset
 			    + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
 			       ? 4 : 0));
 
-		ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
-			   "@ %lx, for symbol %s\n",
-			   (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
-			    "GOT_TLS_IE"),
-			   (long) (sym_value - sec_vma),
-			   (long) (htab->sgot->output_section->vma
-			      + htab->sgot->output_offset
-			      + entry->offset
-			      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
-				 ? 4 : 0)),
-			   symbol_name);
+		    ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
+			  "@ %lx, for symbol %s\n",
+			  (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
+			   "GOT_TLS_IE"),
+			  (long) (sym_value - sec_vma),
+			  (long) (htab->sgot->output_section->vma
+			     + htab->sgot->output_offset
+			     + entry->offset
+			     + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
+				? 4 : 0)),
+			  symbol_name);
+		  }
 	      }
 	      break;
 
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index 668642c..e96b3f8 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -1989,36 +1989,35 @@ elf_arc_check_relocs (bfd *			 abfd,
 
       switch (r_type)
 	{
-	  case R_ARC_32:
-	  case R_ARC_32_ME:
-	    /* During shared library creation, these relocs should not
-	       appear in a shared library (as memory will be read only
-	       and the dynamic linker can not resolve these.  However
-	       the error should not occur for e.g. debugging or
-	       non-readonly sections.  */
-	    if (h != NULL
-		&& (bfd_link_dll (info) && !bfd_link_pie (info))
-		&& (sec->flags & SEC_ALLOC) != 0
-		&& (sec->flags & SEC_READONLY) != 0
-		&& ((sec->flags & SEC_CODE) != 0
-		    || (sec->flags & SEC_DEBUGGING) != 0))
-	      {
-		const char *name;
-		if (h)
-		  name = h->root.root.string;
-		else
-		  /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
-		  name = "UNKNOWN";
-		_bfd_error_handler
-		  /* xgettext:c-format */
-		  (_("%pB: relocation %s against `%s' can not be used"
-		     " when making a shared object; recompile with -fPIC"),
-		   abfd,
-		   arc_elf_howto (r_type)->name,
-		   name);
-		bfd_set_error (bfd_error_bad_value);
-		return FALSE;
-	      }
+	case R_ARC_32:
+	case R_ARC_32_ME:
+	  /* During shared library creation, these relocs should not
+	     appear in a shared library (as memory will be read only
+	     and the dynamic linker can not resolve these.  However
+	     the error should not occur for e.g. debugging or
+	     non-readonly sections.  */
+	  if (h != NULL
+	      && (bfd_link_dll (info) && !bfd_link_pie (info))
+	      && (sec->flags & SEC_ALLOC) != 0
+	      && (sec->flags & SEC_READONLY) != 0
+	      && ((sec->flags & SEC_CODE) != 0
+		  || (sec->flags & SEC_DEBUGGING) != 0))
+	    {
+	      const char *name;
+	      if (h)
+		name = h->root.root.string;
+	      else
+		name = "UNKNOWN";
+	      _bfd_error_handler
+	      /* xgettext:c-format */
+	      (_("%pB: relocation %s against `%s' can not be used"
+		 " when making a shared object; recompile with -fPIC"),
+		 abfd,
+		 arc_elf_howto (r_type)->name,
+		 name);
+	      bfd_set_error (bfd_error_bad_value);
+	      return FALSE;
+	    }
 
 	    /* In some cases we are not setting the 'non_got_ref'
 	       flag, even though the relocations don't require a GOT
@@ -2068,6 +2067,25 @@ elf_arc_check_relocs (bfd *			 abfd,
       if (is_reloc_for_GOT (howto)
 	  || is_reloc_for_TLS (howto))
 	{
+	  if (bfd_link_dll (info) && !bfd_link_pie (info)
+	      && (r_type == R_ARC_TLS_LE_32 || r_type == R_ARC_TLS_LE_S9))
+	    {
+	      const char *name;
+	      if (h)
+		name = h->root.root.string;
+	      else
+		/* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
+		name = "UNKNOWN";
+	      _bfd_error_handler
+		/* xgettext:c-format */
+		(_("%pB: relocation %s against `%s' can not be used"
+		   " when making a shared object; recompile with -fPIC"),
+		   abfd,
+		   arc_elf_howto (r_type)->name,
+		   name);
+	      bfd_set_error (bfd_error_bad_value);
+	      return FALSE;
+	    }
 	  if (! _bfd_elf_create_got_section (dynobj, info))
 	    return FALSE;
 
@@ -2490,6 +2508,38 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd,
     s = bfd_get_linker_section (dynobj, SECTION);		\
   break;
 
+
+struct obfd_info_group {
+  bfd *output_bfd;
+  struct bfd_link_info *info;
+};
+
+static bfd_boolean
+arc_create_forced_local_got_entries_for_tls (struct bfd_hash_entry *bh,
+					     void *data)
+{
+  struct elf_arc_link_hash_entry * h =
+    (struct elf_arc_link_hash_entry *) bh;
+  struct obfd_info_group *tmp = (struct obfd_info_group *) data;
+
+  if (h->got_ents != NULL)
+    {
+      BFD_ASSERT (h);
+
+      struct got_entry *list = h->got_ents;
+
+      while (list != NULL)
+	{
+	  create_got_dynrelocs_for_single_entry (list, tmp->output_bfd,
+						 tmp->info, h);
+	  list = list->next;
+	}
+    }
+
+  return TRUE;
+}
+
+
 /* Function :  elf_arc_finish_dynamic_sections
    Brief    :  Finish up the dynamic sections handling.
    Args     :  output_bfd :
@@ -2623,6 +2673,12 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
 	}
     }
 
+  struct obfd_info_group group;
+  group.output_bfd = output_bfd;
+  group.info = info;
+  bfd_hash_traverse (&info->hash->table,
+		     arc_create_forced_local_got_entries_for_tls, &group);
+
   return TRUE;
 }


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