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 commit] PR gold/17432: Fix allocation of TLS common during LTO


The plugin API doesn't provide a way for the claimed file handler to
identify a TLS symbol, so when adding a common TLS symbol, gold
mistakenly places the symbol in the non-TLS commons list, and does
not override it when we see the replacement symbol that is marked
as TLS. Consequently, we allocate the TLS common symbol as a regular
common, and, if it's the only TLS in the program, we'll give an
internal error because we haven't allocated a TLS segment.

This patch fixes the problem by removing an exclusion where common
symbols would not override the placeholder symbols, but checking to
see if the size needs adjusting (the original reason for the exclusion).
Furthermore, we need to avoid putting placeholder symbols in the common
list, and wait until we see a real common symbol with a type we can
trust.

-cary


2014-09-25  Cary Coutant  <ccoutant@google.com>

gold/
	PR gold/17432
	* resolve.cc (Symbol_table::resolve): Override common placeholder
	symbols, but adjust sizes.
	* symtab.cc (Symbol_table::add_from_object): Don't add placeholder
	symbols to common lists.


diff --git a/gold/resolve.cc b/gold/resolve.cc
index abb5d90..52dae8b 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -309,11 +309,26 @@ Symbol_table::resolve(Sized_symbol<size>* to,
     {
       Pluginobj* obj = to->object()->pluginobj();
       if (obj != NULL
-          && parameters->options().plugins()->in_replacement_phase()
-          && !to->is_common())
+          && parameters->options().plugins()->in_replacement_phase())
         {
-          this->override(to, sym, st_shndx, is_ordinary, object, version);
-          return;
+	  bool adjust_common = false;
+	  typename Sized_symbol<size>::Size_type tosize = 0;
+	  typename Sized_symbol<size>::Value_type tovalue = 0;
+	  if (to->is_common() && !is_ordinary && st_shndx == elfcpp::SHN_COMMON)
+	    {
+	      adjust_common = true;
+	      typename Sized_symbol<size>::Size_type tosize = to->symsize();
+	      typename Sized_symbol<size>::Value_type tovalue = to->value();
+	    }
+	  this->override(to, sym, st_shndx, is_ordinary, object, version);
+	  if (adjust_common)
+	    {
+	      if (tosize > to->symsize())
+		to->set_symsize(tosize);
+	      if (tovalue > to->value())
+		to->set_value(tovalue);
+	    }
+	  return;
         }
     }
 
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 210ab25..70fb3f0 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -980,7 +980,8 @@ Symbol_table::add_from_object(Object* object,
       gold_assert(ret != NULL);
 
       was_undefined = ret->is_undefined();
-      was_common = ret->is_common();
+      // Commons from plugins are just placeholders.
+      was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
 
       this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx, object,
 		    version);
@@ -1003,7 +1004,8 @@ Symbol_table::add_from_object(Object* object,
 	  ret = this->get_sized_symbol<size>(insdefault.first->second);
 
 	  was_undefined = ret->is_undefined();
-	  was_common = ret->is_common();
+	  // Commons from plugins are just placeholders.
+	  was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
 
 	  this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx, object,
 			version);
@@ -1066,8 +1068,10 @@ Symbol_table::add_from_object(Object* object,
     }
 
   // Keep track of common symbols, to speed up common symbol
-  // allocation.
-  if (!was_common && ret->is_common())
+  // allocation.  Don't record commons from plugin objects;
+  // we need to wait until we see the real symbol in the
+  // replacement file.
+  if (!was_common && ret->is_common() && ret->object()->pluginobj() == NULL)
     {
       if (ret->type() == elfcpp::STT_TLS)
 	this->tls_commons_.push_back(ret);


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