H8/300: Fix pseudo registers reads/writes.
[deliverable/binutils-gdb.git] / gold / resolve.cc
index 720b350b327da25a672d162fd98bca55af7e1177..3b6e7069d02a9b428c7ad1cc66ebf0392b3060d1 100644 (file)
@@ -96,7 +96,9 @@ Symbol::override_base(const elfcpp::Sym<size, big_endian>& sym,
   this->override_version(version);
   this->u_.from_object.shndx = st_shndx;
   this->is_ordinary_shndx_ = is_ordinary;
-  this->type_ = sym.get_st_type();
+  // Don't override st_type from plugin placeholder symbols.
+  if (object->pluginobj() == NULL)
+    this->type_ = sym.get_st_type();
   this->binding_ = sym.get_st_bind();
   this->override_visibility(sym.get_st_visibility());
   this->nonvis_ = sym.get_st_nonvis();
@@ -296,7 +298,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
 
   // Record if we've seen this symbol in a real ELF object (i.e., the
   // symbol is referenced from outside the world known to the plugin).
-  if (object->pluginobj() == NULL)
+  if (object->pluginobj() == NULL && !object->is_dynamic())
     to->set_in_real_elf();
 
   // If we're processing replacement files, allow new symbols to override
@@ -336,29 +338,40 @@ Symbol_table::resolve(Sized_symbol<size>* to,
       && to->name()[0] == '_' && to->name()[1] == 'Z')
     {
       Symbol_location fromloc
-          = { object, orig_st_shndx, sym.get_st_value() };
+          = { object, orig_st_shndx, static_cast<off_t>(sym.get_st_value()) };
       Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary),
-                               to->value() };
+                               static_cast<off_t>(to->value()) };
       this->candidate_odr_violations_[to->name()].insert(fromloc);
       this->candidate_odr_violations_[to->name()].insert(toloc);
     }
 
+  // Plugins don't provide a symbol type, so adopt the existing type
+  // if the FROM symbol is from a plugin.
+  elfcpp::STT fromtype = (object->pluginobj() != NULL
+                         ? to->type()
+                         : sym.get_st_type());
   unsigned int frombits = symbol_to_bits(sym.get_st_bind(),
                                          object->is_dynamic(),
                                         st_shndx, is_ordinary,
-                                         sym.get_st_type());
+                                         fromtype);
 
   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, fromtype, OBJECT,
+                                   object, &adjust_common_sizes,
                                    &adjust_dyndef))
     {
       elfcpp::STB tobinding = to->binding();
+      typename Sized_symbol<size>::Value_type tovalue = to->value();
       this->override(to, sym, st_shndx, is_ordinary, object, version);
-      if (adjust_common_sizes && tosize > to->symsize())
-        to->set_symsize(tosize);
+      if (adjust_common_sizes)
+       {
+         if (tosize > to->symsize())
+           to->set_symsize(tosize);
+         if (tovalue > to->value())
+           to->set_value(tovalue);
+       }
       if (adjust_dyndef)
        {
          // We are overriding an UNDEF or WEAK UNDEF with a DYN DEF.
@@ -368,8 +381,13 @@ Symbol_table::resolve(Sized_symbol<size>* to,
     }
   else
     {
-      if (adjust_common_sizes && sym.get_st_size() > tosize)
-        to->set_symsize(sym.get_st_size());
+      if (adjust_common_sizes)
+       {
+         if (sym.get_st_size() > tosize)
+           to->set_symsize(sym.get_st_size());
+         if (sym.get_st_value() > to->value())
+           to->set_value(sym.get_st_value());
+       }
       if (adjust_dyndef)
        {
          // We are keeping a DYN DEF after seeing an UNDEF or WEAK UNDEF.
@@ -409,8 +427,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 +452,12 @@ 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)
+      && !to->is_placeholder())
+    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 +893,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;
This page took 0.032006 seconds and 4 git commands to generate.