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]

gold patch committed: Error when mixing TLS and non-TLS symbols


PR 12279 points out that gold silently permits linking together TLS and
non-TLS symbols.  This patch adds an error for that case, and avoids
crashing later.  Committed to mainline.

Ian


2011-07-08  Ian Lance Taylor  <iant@google.com>

	PR gold/12279
	* resolve.cc (Symbol_table::should_override): Add fromtype
	parameter.  Change all callers.  Give error when linking together
	TLS and non-TLS symbol.
	(Symbol_table::should_override_with_special): Add fromtype
	parameter.  Change all callers.
	* i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if
	there is no TLS segment if we have reported some errors.
	* x86_64.cc (Target_x86_64::relocate_tls): Likewise.


Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.136
diff -u -p -r1.136 i386.cc
--- i386.cc	8 Jul 2011 22:48:08 -0000	1.136
+++ i386.cc	8 Jul 2011 23:45:32 -0000
@@ -2638,7 +2638,11 @@ Target_i386::Relocate::relocate_tls(cons
     case elfcpp::R_386_TLS_GD:           // Global-dynamic
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_gd_to_le(relinfo, relnum, tls_segment,
 			     rel, r_type, value, view,
 			     view_size);
@@ -2664,7 +2668,11 @@ Target_i386::Relocate::relocate_tls(cons
             }
           if (optimized_type == tls::TLSOPT_TO_IE)
 	    {
-              gold_assert(tls_segment != NULL);
+	      if (tls_segment == NULL)
+		{
+		  gold_assert(parameters->errors()->error_count() > 0);
+		  return;
+		}
 	      this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
                                  got_offset, view, view_size);
               break;
@@ -2687,7 +2695,11 @@ Target_i386::Relocate::relocate_tls(cons
       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
       if (optimized_type == tls::TLSOPT_TO_LE)
         {
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
 			          rel, r_type, value, view,
 			          view_size);
@@ -2722,7 +2734,11 @@ Target_i386::Relocate::relocate_tls(cons
             }
           if (optimized_type == tls::TLSOPT_TO_IE)
 	    {
-              gold_assert(tls_segment != NULL);
+	      if (tls_segment == NULL)
+		{
+		  gold_assert(parameters->errors()->error_count() > 0);
+		  return;
+		}
 	      this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
                                       got_offset, view, view_size);
               break;
@@ -2754,7 +2770,11 @@ Target_i386::Relocate::relocate_tls(cons
       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type,
 			     value, view, view_size);
 	  break;
@@ -2785,7 +2805,11 @@ Target_i386::Relocate::relocate_tls(cons
 	  elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
 	  if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
 	    {
-	      gold_assert(tls_segment != NULL);
+	      if (tls_segment == NULL)
+		{
+		  gold_assert(parameters->errors()->error_count() > 0);
+		  return;
+		}
 	      value -= tls_segment->memsz();
 	    }
 	}
@@ -2797,7 +2821,11 @@ Target_i386::Relocate::relocate_tls(cons
     case elfcpp::R_386_TLS_IE_32:
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
 					      rel, r_type, value, view,
 					      view_size);
@@ -2841,7 +2869,11 @@ Target_i386::Relocate::relocate_tls(cons
       // have been created for this location, so do not apply it now.
       if (!parameters->options().shared())
         {
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
           value -= tls_segment->memsz();
           Relocate_functions<32, false>::rel32(view, value);
         }
@@ -2852,7 +2884,11 @@ Target_i386::Relocate::relocate_tls(cons
       // have been created for this location, so do not apply it now.
       if (!parameters->options().shared())
         {
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
           value = tls_segment->memsz() - value;
           Relocate_functions<32, false>::rel32(view, value);
         }
Index: resolve.cc
===================================================================
RCS file: /cvs/src/src/gold/resolve.cc,v
retrieving revision 1.62
diff -u -p -r1.62 resolve.cc
--- resolve.cc	6 Jul 2011 04:43:39 -0000	1.62
+++ resolve.cc	8 Jul 2011 23:45:32 -0000
@@ -351,8 +351,8 @@ Symbol_table::resolve(Sized_symbol<size>
   bool adjust_common_sizes;
   bool adjust_dyndef;
   typename Sized_symbol<size>::Size_type tosize = to->symsize();
-  if (Symbol_table::should_override(to, frombits, OBJECT, object,
-				    &adjust_common_sizes,
+  if (Symbol_table::should_override(to, frombits, sym.get_st_type(), OBJECT,
+				    object, &adjust_common_sizes,
 				    &adjust_dyndef))
     {
       elfcpp::STB tobinding = to->binding();
@@ -409,8 +409,8 @@ Symbol_table::resolve(Sized_symbol<size>
 
 bool
 Symbol_table::should_override(const Symbol* to, unsigned int frombits,
-                              Defined defined, Object* object,
-			      bool* adjust_common_sizes,
+			      elfcpp::STT fromtype, Defined defined,
+			      Object* object, bool* adjust_common_sizes,
 			      bool* adjust_dyndef)
 {
   *adjust_common_sizes = false;
@@ -434,7 +434,13 @@ Symbol_table::should_override(const Symb
 			      to->type());
     }
 
-  // FIXME: Warn if either but not both of TO and SYM are STT_TLS.
+  if (to->type() == elfcpp::STT_TLS
+      ? fromtype != elfcpp::STT_TLS
+      : fromtype == elfcpp::STT_TLS)
+    Symbol_table::report_resolve_problem(true,
+					 _("symbol '%s' used as both __thread "
+					   "and non-__thread"),
+					 to, defined, object);
 
   // We use a giant switch table for symbol resolution.  This code is
   // unwieldy, but: 1) it is efficient; 2) we definitely handle all
@@ -870,13 +876,15 @@ Symbol_table::report_resolve_problem(boo
 // defining special symbols.
 
 bool
-Symbol_table::should_override_with_special(const Symbol* to, Defined defined)
+Symbol_table::should_override_with_special(const Symbol* to,
+					   elfcpp::STT fromtype,
+					   Defined defined)
 {
   bool adjust_common_sizes;
   bool adjust_dyn_def;
   unsigned int frombits = global_flag | regular_flag | def_flag;
-  bool ret = Symbol_table::should_override(to, frombits, defined, NULL,
-					   &adjust_common_sizes,
+  bool ret = Symbol_table::should_override(to, frombits, fromtype, defined,
+					   NULL, &adjust_common_sizes,
 					   &adjust_dyn_def);
   gold_assert(!adjust_common_sizes && !adjust_dyn_def);
   return ret;
Index: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.156
diff -u -p -r1.156 symtab.cc
--- symtab.cc	29 Jun 2011 14:43:08 -0000	1.156
+++ symtab.cc	8 Jul 2011 23:45:33 -0000
@@ -1883,7 +1883,7 @@ Symbol_table::do_define_in_output_data(
       return sym;
     }
 
-  if (Symbol_table::should_override_with_special(oldsym, defined))
+  if (Symbol_table::should_override_with_special(oldsym, type, defined))
     this->override_with_special(oldsym, sym);
 
   if (resolve_oldsym)
@@ -1997,7 +1997,7 @@ Symbol_table::do_define_in_output_segmen
       return sym;
     }
 
-  if (Symbol_table::should_override_with_special(oldsym, defined))
+  if (Symbol_table::should_override_with_special(oldsym, type, defined))
     this->override_with_special(oldsym, sym);
 
   if (resolve_oldsym)
@@ -2116,7 +2116,7 @@ Symbol_table::do_define_as_constant(
     }
 
   if (force_override
-      || Symbol_table::should_override_with_special(oldsym, defined))
+      || Symbol_table::should_override_with_special(oldsym, type, defined))
     this->override_with_special(oldsym, sym);
 
   if (resolve_oldsym)
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gold/symtab.h,v
retrieving revision 1.123
diff -u -p -r1.123 symtab.h
--- symtab.h	28 Jun 2011 05:39:45 -0000	1.123
+++ symtab.h	8 Jul 2011 23:45:34 -0000
@@ -1661,7 +1661,8 @@ class Symbol_table
   // Whether we should override a symbol, based on flags in
   // resolve.cc.
   static bool
-  should_override(const Symbol*, unsigned int, Defined, Object*, bool*, bool*);
+  should_override(const Symbol*, unsigned int, elfcpp::STT, Defined,
+		  Object*, bool*, bool*);
 
   // Report a problem in symbol resolution.
   static void
@@ -1679,7 +1680,7 @@ class Symbol_table
   // Whether we should override a symbol with a special symbol which
   // is automatically defined by the linker.
   static bool
-  should_override_with_special(const Symbol*, Defined);
+  should_override_with_special(const Symbol*, elfcpp::STT, Defined);
 
   // Override a symbol with a special symbol.
   template<int size>
Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.134
diff -u -p -r1.134 x86_64.cc
--- x86_64.cc	8 Jul 2011 22:48:08 -0000	1.134
+++ x86_64.cc	8 Jul 2011 23:45:35 -0000
@@ -3110,7 +3110,11 @@ Target_x86_64::Relocate::relocate_tls(co
 	}
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_gd_to_le(relinfo, relnum, tls_segment,
 			     rela, r_type, value, view,
 			     view_size);
@@ -3136,7 +3140,11 @@ Target_x86_64::Relocate::relocate_tls(co
             }
           if (optimized_type == tls::TLSOPT_TO_IE)
             {
-              gold_assert(tls_segment != NULL);
+	      if (tls_segment == NULL)
+		{
+		  gold_assert(parameters->errors()->error_count() > 0);
+		  return;
+		}
               value = target->got_plt_section()->address() + got_offset;
               this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
                                  value, view, address, view_size);
@@ -3165,7 +3173,11 @@ Target_x86_64::Relocate::relocate_tls(co
 	}
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
 			          rela, r_type, value, view,
 			          view_size);
@@ -3200,7 +3212,11 @@ Target_x86_64::Relocate::relocate_tls(co
             }
           if (optimized_type == tls::TLSOPT_TO_IE)
             {
-              gold_assert(tls_segment != NULL);
+	      if (tls_segment == NULL)
+		{
+		  gold_assert(parameters->errors()->error_count() > 0);
+		  return;
+		}
               value = target->got_plt_section()->address() + got_offset;
               this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment,
                                       rela, r_type, value, view, address,
@@ -3232,7 +3248,11 @@ Target_x86_64::Relocate::relocate_tls(co
 	}
       if (optimized_type == tls::TLSOPT_TO_LE)
         {
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  this->tls_ld_to_le(relinfo, relnum, tls_segment, rela, r_type,
 			     value, view, view_size);
 	  break;
@@ -3262,7 +3282,11 @@ Target_x86_64::Relocate::relocate_tls(co
       // R_X86_64_TLSLD.
       if (optimized_type == tls::TLSOPT_TO_LE && is_executable)
 	{
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  value -= tls_segment->memsz();
 	}
       Relocate_functions<64, false>::rela32(view, value, addend);
@@ -3272,7 +3296,11 @@ Target_x86_64::Relocate::relocate_tls(co
       // See R_X86_64_DTPOFF32, just above, for why we check for is_executable.
       if (optimized_type == tls::TLSOPT_TO_LE && is_executable)
 	{
-	  gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  value -= tls_segment->memsz();
 	}
       Relocate_functions<64, false>::rela64(view, value, addend);
@@ -3281,7 +3309,11 @@ Target_x86_64::Relocate::relocate_tls(co
     case elfcpp::R_X86_64_GOTTPOFF:         // Initial-exec
       if (optimized_type == tls::TLSOPT_TO_LE)
 	{
-          gold_assert(tls_segment != NULL);
+	  if (tls_segment == NULL)
+	    {
+	      gold_assert(parameters->errors()->error_count() > 0);
+	      return;
+	    }
 	  Target_x86_64::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
                                                 rela, r_type, value, view,
                                                 view_size);
@@ -3316,6 +3348,11 @@ Target_x86_64::Relocate::relocate_tls(co
       break;
 
     case elfcpp::R_X86_64_TPOFF32:          // Local-exec
+      if (tls_segment == NULL)
+	{
+	  gold_assert(parameters->errors()->error_count() > 0);
+	  return;
+	}
       value -= tls_segment->memsz();
       Relocate_functions<64, false>::rela32(view, value, addend);
       break;

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