2008-12-15 Paul Pluzhnikov <ppluzhnikov@google.com>
[deliverable/binutils-gdb.git] / gold / object.cc
index 2ecb8a9e915e93062fe01f944be5b34851df9ce4..f7dcda89ceb201f204dc6874a1be3aabe26ac891 100644 (file)
@@ -33,6 +33,7 @@
 #include "layout.h"
 #include "output.h"
 #include "symtab.h"
+#include "cref.h"
 #include "reloc.h"
 #include "object.h"
 #include "dynobj.h"
@@ -245,6 +246,7 @@ Sized_relobj<size, big_endian>::Sized_relobj(
     output_local_symbol_count_(0),
     output_local_dynsym_count_(0),
     symbols_(),
+    defined_count_(0),
     local_symbol_offset_(0),
     local_dynsym_offset_(0),
     local_values_(),
@@ -924,7 +926,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
        {
          // Do not include this section in the link.
          out_sections[i] = NULL;
-          out_section_offsets[i] = -1U;
+          out_section_offsets[i] = invalid_address;
          continue;
        }
 
@@ -965,7 +967,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
 
       out_sections[i] = os;
       if (offset == -1)
-        out_section_offsets[i] = -1U;
+        out_section_offsets[i] = invalid_address;
       else
         out_section_offsets[i] = convert_types<Address, off_t>(offset);
 
@@ -1002,7 +1004,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
       if (data_section == NULL)
        {
          out_sections[i] = NULL;
-          out_section_offsets[i] = -1U;
+          out_section_offsets[i] = invalid_address;
          continue;
        }
 
@@ -1012,7 +1014,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
       Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
                                                rr);
       out_sections[i] = os;
-      out_section_offsets[i] = -1U;
+      out_section_offsets[i] = invalid_address;
     }
 
   // Handle the .eh_frame sections at the end.
@@ -1040,7 +1042,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
                                                   &offset);
       out_sections[i] = os;
       if (offset == -1)
-        out_section_offsets[i] = -1U;
+        out_section_offsets[i] = invalid_address;
       else
         out_section_offsets[i] = convert_types<Address, off_t>(offset);
 
@@ -1087,7 +1089,8 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
                          sd->symbols->data() + sd->external_symbols_offset,
                          symcount, this->local_symbol_count_,
                          sym_names, sd->symbol_names_size,
-                         &this->symbols_);
+                         &this->symbols_,
+                         &this->defined_count_);
 
   delete sd->symbols;
   sd->symbols = NULL;
@@ -1263,7 +1266,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
               // so we leave the input value unchanged here.
              continue;
            }
-         else if (out_offsets[shndx] == -1U)
+         else if (out_offsets[shndx] == invalid_address)
            {
              // This is a SHF_MERGE section or one which otherwise
              // requires special handling.  We get the output address
@@ -1570,13 +1573,35 @@ Sized_relobj<size, big_endian>::map_to_kept_section(
       *found = true;
       Output_section* os = kept->object_->output_section(kept->shndx_);
       Address offset = kept->object_->get_output_section_offset(kept->shndx_);
-      gold_assert(os != NULL && offset != -1U);
+      gold_assert(os != NULL && offset != invalid_address);
       return os->address() + offset;
     }
   *found = false;
   return 0;
 }
 
+// Get symbol counts.
+
+template<int size, bool big_endian>
+void
+Sized_relobj<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 (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())
+      ++count;
+  *used = count;
+}
+
 // Input_objects methods.
 
 // Add a regular relocatable object to the list.  Return false if this
@@ -1631,6 +1656,14 @@ Input_objects::add_object(Object* obj)
        }
     }
 
+  // Add this object to the cross-referencer if requested.
+  if (parameters->options().user_set_print_symbol_counts())
+    {
+      if (this->cref_ == NULL)
+       this->cref_ = new Cref();
+      this->cref_->add_object(obj);
+    }
+
   return true;
 }
 
@@ -1671,6 +1704,38 @@ Input_objects::check_dynamic_dependencies() const
     }
 }
 
+// Start processing an archive.
+
+void
+Input_objects::archive_start(Archive* archive)
+{
+  if (parameters->options().user_set_print_symbol_counts())
+    {
+      if (this->cref_ == NULL)
+       this->cref_ = new Cref();
+      this->cref_->add_archive_start(archive);
+    }
+}
+
+// Stop processing an archive.
+
+void
+Input_objects::archive_stop(Archive* archive)
+{
+  if (parameters->options().user_set_print_symbol_counts())
+    this->cref_->add_archive_stop(archive);
+}
+
+// Print symbol counts
+
+void
+Input_objects::print_symbol_counts(const Symbol_table* symtab) const
+{
+  if (parameters->options().user_set_print_symbol_counts()
+      && this->cref_ != NULL)
+    this->cref_->print_symbol_counts(symtab);
+}
+
 // Relocate_info methods.
 
 // Return a string describing the location of a relocation.  This is
This page took 0.025355 seconds and 4 git commands to generate.