PR ld/10515
[binutils-gdb.git] / gold / dynobj.cc
index a95787d9f5bdfbf7154b108d0e7a566638090573..df2afeb319701794092d9f7bd5ae13b179045dbe 100644 (file)
@@ -73,7 +73,9 @@ Sized_dynobj<size, big_endian>::Sized_dynobj(
     const elfcpp::Ehdr<size, big_endian>& ehdr)
   : Dynobj(name, input_file, offset),
     elf_file_(this, ehdr),
-    dynsym_shndx_(-1U)
+    dynsym_shndx_(-1U),
+    symbols_(NULL),
+    defined_count_(0)
 {
 }
 
@@ -81,13 +83,9 @@ Sized_dynobj<size, big_endian>::Sized_dynobj(
 
 template<int size, bool big_endian>
 void
-Sized_dynobj<size, big_endian>::setup(
-    const elfcpp::Ehdr<size, big_endian>& ehdr)
+Sized_dynobj<size, big_endian>::setup(Target *target)
 {
-  this->set_target(ehdr.get_e_machine(), size, big_endian,
-                  ehdr.get_e_ident()[elfcpp::EI_OSABI],
-                  ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
-
+  this->set_target(target);
   const unsigned int shnum = this->elf_file_.shnum();
   this->set_shnum(shnum);
 }
@@ -653,7 +651,8 @@ Sized_dynobj<size, big_endian>::make_version_map(
 template<int size, bool big_endian>
 void
 Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
-                                              Read_symbols_data* sd)
+                                              Read_symbols_data* sd,
+                                              Layout*)
 {
   if (sd->symbols == NULL)
     {
@@ -675,6 +674,14 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
   Version_map version_map;
   this->make_version_map(sd, &version_map);
 
+  // If printing symbol counts, we want to track symbols.
+  
+  if (parameters->options().user_set_print_symbol_counts())
+    {
+      this->symbols_ = new Symbols();
+      this->symbols_->resize(symcount);
+    }
+
   const char* sym_names =
     reinterpret_cast<const char*>(sd->symbol_names->data());
   symtab->add_from_dynobj(this, sd->symbols->data(), symcount,
@@ -683,7 +690,9 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
                           ? NULL
                           : sd->versym->data()),
                          sd->versym_size,
-                         &version_map);
+                         &version_map,
+                         this->symbols_,
+                         &this->defined_count_);
 
   delete sd->symbols;
   sd->symbols = NULL;
@@ -710,6 +719,29 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
   this->clear_view_cache_marks();
 }
 
+// Get symbol counts.
+
+template<int size, bool big_endian>
+void
+Sized_dynobj<size, big_endian>::do_get_global_symbol_counts(
+    const Symbol_table*,
+    size_t* defined,
+    size_t* used) const
+{
+  *defined = this->defined_count_;
+  size_t count = 0;
+  for (typename Symbols::const_iterator p = this->symbols_->begin();
+       p != this->symbols_->end();
+       ++p)
+    if (*p != NULL
+       && (*p)->source() == Symbol::FROM_OBJECT
+       && (*p)->object() == this
+       && (*p)->is_defined()
+       && (*p)->dynsym_index() != -1U)
+      ++count;
+  *used = count;
+}
+
 // Given a vector of hash codes, compute the number of hash buckets to
 // use.
 
@@ -1270,16 +1302,15 @@ Versions::Versions(const Version_script_info& version_script,
   : defs_(), needs_(), version_table_(),
     is_finalized_(false), version_script_(version_script)
 {
-  // We always need a base version, so define that first. Nothing
+  // We always need a base version, so define that first.  Nothing
   // explicitly declares itself as part of base, so it doesn't need to
   // be in version_table_.
-  // FIXME: Should use soname here when creating a shared object. Is
-  // this fixme still valid? It looks like it's doing the right thing
-  // to me.
   if (parameters->options().shared())
     {
-      const char* name = dynpool->add(parameters->options().output_file_name(),
-                                      false, NULL);
+      const char* name = parameters->options().soname();
+      if (name == NULL)
+       name = parameters->options().output_file_name();
+      name = dynpool->add(name, false, NULL);
       Verdef* vdbase = new Verdef(name, std::vector<std::string>(),
                                   true, false, true);
       this->defs_.push_back(vdbase);