Generate a complete exception frame header. Discard duplicate
[binutils-gdb.git] / gold / symtab.cc
index 7e0af342a88c6388d671aec88b53f29f16e3b30c..3c2a9761a09a42fd266745a49cf2972468c4c4f3 100644 (file)
@@ -66,6 +66,7 @@ Symbol::init_fields(const char* name, const char* version,
   this->has_got_offset_ = false;
   this->has_plt_offset_ = false;
   this->has_warning_ = false;
+  this->is_copied_from_dynobj_ = false;
 }
 
 // Initialize the fields in the base class Symbol for SYM in OBJECT.
@@ -188,6 +189,27 @@ Sized_symbol<size>::init(const char* name, Value_type value, Size_type symsize,
   this->symsize_ = symsize;
 }
 
+// Return true if this symbol should be added to the dynamic symbol
+// table.
+
+inline bool
+Symbol::should_add_dynsym_entry() const
+{
+  // If the symbol is used by a dynamic relocation, we need to add it.
+  if (this->needs_dynsym_entry())
+    return true;
+
+  // If exporting all symbols or building a shared library,
+  // and the symbol is defined in a regular object and is
+  // externally visible, we need to add it.
+  if ((parameters->export_dynamic() || parameters->output_is_shared())
+      && !this->is_from_dynobj()
+      && this->is_externally_visible())
+    return true;
+
+  return false;
+}
+
 // Return true if the final value of this symbol is known at link
 // time.
 
@@ -499,7 +521,7 @@ Symbol_table::add_from_relobj(
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
-    Symbol** sympointers)
+    typename Sized_relobj<size, big_endian>::Symbols* sympointers)
 {
   gold_assert(size == relobj->target()->get_size());
   gold_assert(size == parameters->get_size());
@@ -570,7 +592,7 @@ Symbol_table::add_from_relobj(
                                      def, *psym);
        }
 
-      *sympointers++ = res;
+      (*sympointers)[i] = res;
     }
 }
 
@@ -1202,14 +1224,77 @@ Symbol_table::define_symbols(const Layout* layout, const Target* target,
     }
 }
 
+// Define CSYM using a COPY reloc.  POSD is the Output_data where the
+// symbol should be defined--typically a .dyn.bss section.  VALUE is
+// the offset within POSD.
+
+template<int size>
+void
+Symbol_table::define_with_copy_reloc(const Target* target,
+                                    Sized_symbol<size>* csym,
+                                    Output_data* posd, uint64_t value)
+{
+  gold_assert(csym->is_from_dynobj());
+  gold_assert(!csym->is_copied_from_dynobj());
+  Object* object = csym->object();
+  gold_assert(object->is_dynamic());
+  Dynobj* dynobj = static_cast<Dynobj*>(object);
+
+  // Our copied variable has to override any variable in a shared
+  // library.
+  elfcpp::STB binding = csym->binding();
+  if (binding == elfcpp::STB_WEAK)
+    binding = elfcpp::STB_GLOBAL;
+
+  this->define_in_output_data(target, csym->name(), csym->version(),
+                             posd, value, csym->symsize(),
+                             csym->type(), binding,
+                             csym->visibility(), csym->nonvis(),
+                             false, false);
+
+  csym->set_is_copied_from_dynobj();
+  csym->set_needs_dynsym_entry();
+
+  this->copied_symbol_dynobjs_[csym] = dynobj;
+
+  // We have now defined all aliases, but we have not entered them all
+  // in the copied_symbol_dynobjs_ map.
+  if (csym->has_alias())
+    {
+      Symbol* sym = csym;
+      while (true)
+       {
+         sym = this->weak_aliases_[sym];
+         if (sym == csym)
+           break;
+         gold_assert(sym->output_data() == posd);
+
+         sym->set_is_copied_from_dynobj();
+         this->copied_symbol_dynobjs_[sym] = dynobj;
+       }
+    }
+}
+
+// SYM is defined using a COPY reloc.  Return the dynamic object where
+// the original definition was found.
+
+Dynobj*
+Symbol_table::get_copy_source(const Symbol* sym) const
+{
+  gold_assert(sym->is_copied_from_dynobj());
+  Copied_symbol_dynobjs::const_iterator p =
+    this->copied_symbol_dynobjs_.find(sym);
+  gold_assert(p != this->copied_symbol_dynobjs_.end());
+  return p->second;
+}
+
 // Set the dynamic symbol indexes.  INDEX is the index of the first
 // global dynamic symbol.  Pointers to the symbols are stored into the
 // vector SYMS.  The names are added to DYNPOOL.  This returns an
 // updated dynamic symbol index.
 
 unsigned int
-Symbol_table::set_dynsym_indexes(const General_options* options,
-                                const Target* target,
+Symbol_table::set_dynsym_indexes(const Target* target,
                                 unsigned int index,
                                 std::vector<Symbol*>* syms,
                                 Stringpool* dynpool,
@@ -1225,10 +1310,7 @@ Symbol_table::set_dynsym_indexes(const General_options* options,
       // some symbols appear more than once in the symbol table, with
       // and without a version.
 
-      if (!sym->needs_dynsym_entry()
-          && (!options->export_dynamic()
-              || !sym->in_reg()
-              || !sym->is_externally_visible()))
+      if (!sym->should_add_dynsym_entry())
        sym->set_dynsym_index(-1U);
       else if (!sym->has_dynsym_index())
        {
@@ -1239,7 +1321,7 @@ Symbol_table::set_dynsym_indexes(const General_options* options,
 
          // Record any version information.
          if (sym->version() != NULL)
-           versions->record_version(options, dynpool, sym);
+           versions->record_version(this, dynpool, sym);
        }
     }
 
@@ -1788,7 +1870,7 @@ Symbol_table::add_from_relobj<32, false>(
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
-    Symbol** sympointers);
+    Sized_relobj<32, true>::Symbols* sympointers);
 #endif
 
 #ifdef HAVE_TARGET_32_BIG
@@ -1800,7 +1882,7 @@ Symbol_table::add_from_relobj<32, true>(
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
-    Symbol** sympointers);
+    Sized_relobj<32, false>::Symbols* sympointers);
 #endif
 
 #ifdef HAVE_TARGET_64_LITTLE
@@ -1812,7 +1894,7 @@ Symbol_table::add_from_relobj<64, false>(
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
-    Symbol** sympointers);
+    Sized_relobj<64, true>::Symbols* sympointers);
 #endif
 
 #ifdef HAVE_TARGET_64_BIG
@@ -1824,7 +1906,7 @@ Symbol_table::add_from_relobj<64, true>(
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
-    Symbol** sympointers);
+    Sized_relobj<64, false>::Symbols* sympointers);
 #endif
 
 #ifdef HAVE_TARGET_32_LITTLE
@@ -1883,6 +1965,22 @@ Symbol_table::add_from_dynobj<64, true>(
     const std::vector<const char*>* version_map);
 #endif
 
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
+template
+void
+Symbol_table::define_with_copy_reloc<32>(const Target* target,
+                                        Sized_symbol<32>* sym,
+                                        Output_data* posd, uint64_t value);
+#endif
+
+#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
+template
+void
+Symbol_table::define_with_copy_reloc<64>(const Target* target,
+                                        Sized_symbol<64>* sym,
+                                        Output_data* posd, uint64_t value);
+#endif
+
 #ifdef HAVE_TARGET_32_LITTLE
 template
 void
@@ -1915,5 +2013,4 @@ Warnings::issue_warning<64, true>(const Symbol* sym,
                                  size_t relnum, off_t reloffset) const;
 #endif
 
-
 } // End namespace gold.