PR gold/12279
authorIan Lance Taylor <ian@airs.com>
Fri, 8 Jul 2011 23:49:11 +0000 (23:49 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 8 Jul 2011 23:49:11 +0000 (23:49 +0000)
* 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.

gold/ChangeLog
gold/i386.cc
gold/resolve.cc
gold/symtab.cc
gold/symtab.h
gold/x86_64.cc

index 028919856a1263c2da92ca14ff0d13dc7307f9e1..81e9e4316555c38ea84afec37890a9f6fa7d6421 100644 (file)
@@ -1,3 +1,15 @@
+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.
+
 2011-07-08  Ian Lance Taylor  <iant@google.com>
 
        PR gold/12372
index 6c6c4b414894811d3542c3d3de33754fd888dc65..21d008c34e27fdbb4d0ac1c26056dad8c7db3825 100644 (file)
@@ -2638,7 +2638,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
     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(const Relocate_info<32, false>* relinfo,
             }
           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(const Relocate_info<32, false>* relinfo,
       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(const Relocate_info<32, false>* relinfo,
             }
           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(const Relocate_info<32, false>* relinfo,
       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(const Relocate_info<32, false>* relinfo,
          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(const Relocate_info<32, false>* relinfo,
     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(const Relocate_info<32, false>* relinfo,
       // 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(const Relocate_info<32, false>* relinfo,
       // 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 720b350b327da25a672d162fd98bca55af7e1177..03288eccf19ff20bc7aa1388cf533b796484819c 100644 (file)
@@ -351,8 +351,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
   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>* to,
 
 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 Symbol* to, unsigned int frombits,
                              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(bool is_error, const char* msg,
 // 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 7e5b66c83dd8ed6c4dd309b1b42cd8744300cd13..26d803262d57ba9c51ce7fcd51e967b7e03aa5ae 100644 (file)
@@ -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_segment(
       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 9ba9c08fc3887ee21e78e5ecf3e5e8d94ea9c505..e2aa6a7f536e7f380e9b0d95dbc9153712e3833d 100644 (file)
@@ -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 da4efeda2a387a19cd6591752e7413f4b06d4b56..182429e325ab49e7ff999d4480ee8f23a6496fce 100644 (file)
@@ -3110,7 +3110,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
        }
       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(const Relocate_info<64, false>* relinfo,
             }
           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(const Relocate_info<64, false>* relinfo,
        }
       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(const Relocate_info<64, false>* relinfo,
             }
           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(const Relocate_info<64, false>* relinfo,
        }
       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(const Relocate_info<64, false>* relinfo,
       // 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(const Relocate_info<64, false>* relinfo,
       // 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(const Relocate_info<64, false>* relinfo,
     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(const Relocate_info<64, false>* relinfo,
       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;