* nto-procfs.c (get_regset): Pass correct pointer.
[deliverable/binutils-gdb.git] / gold / layout.cc
index b59caea6166d48e91709741e2adb88abf5de27bc..a651d0650d9cc96a066bad2ee80f3fb6bdfa7fd1 100644 (file)
@@ -46,8 +46,9 @@
 #include "reduced_debug_output.h"
 #include "reloc.h"
 #include "descriptors.h"
-#include "layout.h"
 #include "plugin.h"
+#include "incremental.h"
+#include "layout.h"
 
 namespace gold
 {
@@ -86,8 +87,8 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task)
 
 // Layout methods.
 
-Layout::Layout(const General_options& options, Script_options* script_options)
-  : options_(options),
+Layout::Layout(int number_of_input_files, Script_options* script_options)
+  : number_of_input_files_(number_of_input_files),
     script_options_(script_options),
     namepool_(),
     sympool_(),
@@ -97,7 +98,6 @@ Layout::Layout(const General_options& options, Script_options* script_options)
     segment_list_(),
     section_list_(),
     unattached_section_list_(),
-    sections_are_attached_(false),
     special_output_list_(),
     section_headers_(NULL),
     tls_segment_(NULL),
@@ -117,11 +117,14 @@ Layout::Layout(const General_options& options, Script_options* script_options)
     debug_info_(NULL),
     group_signatures_(),
     output_file_size_(-1),
+    sections_are_attached_(false),
     input_requires_executable_stack_(false),
     input_with_gnu_stack_note_(false),
     input_without_gnu_stack_note_(false),
     has_static_tls_(false),
-    any_postprocessing_sections_(false)
+    any_postprocessing_sections_(false),
+    resized_signatures_(false),
+    incremental_inputs_(NULL)
 {
   // Make space for more than enough segments for a typical file.
   // This is just for efficiency--it's OK if we wind up needing more.
@@ -130,6 +133,10 @@ Layout::Layout(const General_options& options, Script_options* script_options)
   // We expect two unattached Output_data objects: the file header and
   // the segment headers.
   this->special_output_list_.reserve(2);
+
+  // Initialize structure needed for an incremental build.
+  if (parameters->options().incremental())
+    this->incremental_inputs_ = new Incremental_inputs;
 }
 
 // Hash a key we use to look up an output section mapping.
@@ -581,6 +588,10 @@ Layout::layout_group(Symbol_table* symtab,
     os->set_info_symndx(sym);
   else
     {
+      // Reserve some space to minimize reallocations.
+      if (this->group_signatures_.empty())
+       this->group_signatures_.reserve(this->number_of_input_files_ * 16);
+
       // We will wind up using a symbol whose name is the signature.
       // So just put the signature in the symbol name pool to save it.
       signature = symtab->canonicalize_name(signature);
@@ -631,7 +642,7 @@ Layout::layout_eh_frame(Sized_relobj<size, big_endian>* object,
       this->eh_frame_section_ = os;
       this->eh_frame_data_ = new Eh_frame();
 
-      if (this->options_.eh_frame_hdr())
+      if (parameters->options().eh_frame_hdr())
        {
          Output_section* hdr_os =
            this->choose_output_section(NULL,
@@ -751,12 +762,13 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
 {
   Output_section* os;
   if ((flags & elfcpp::SHF_ALLOC) == 0
-      && strcmp(this->options_.compress_debug_sections(), "none") != 0
+      && strcmp(parameters->options().compress_debug_sections(), "none") != 0
       && is_compressible_debug_section(name))
-    os = new Output_compressed_section(&this->options_, name, type, flags);
+    os = new Output_compressed_section(&parameters->options(), name, type,
+                                      flags);
 
   else if ((flags & elfcpp::SHF_ALLOC) == 0
-           && this->options_.strip_debug_non_line()
+           && parameters->options().strip_debug_non_line()
            && strcmp(".debug_abbrev", name) == 0)
     {
       os = this->debug_abbrev_ = new Output_reduced_debug_abbrev_section(
@@ -765,7 +777,7 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
         this->debug_info_->set_abbreviations(this->debug_abbrev_);
     }
   else if ((flags & elfcpp::SHF_ALLOC) == 0
-           && this->options_.strip_debug_non_line()
+           && parameters->options().strip_debug_non_line()
            && strcmp(".debug_info", name) == 0)
     {
       os = this->debug_info_ = new Output_reduced_debug_info_section(
@@ -877,7 +889,7 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
         {
           // If -Tbss was specified, we need to separate the data
           // and BSS segments.
-          if (this->options_.user_set_Tbss())
+          if (parameters->options().user_set_Tbss())
             {
               if ((os->type() == elfcpp::SHT_NOBITS)
                   == (*p)->has_any_data_sections())
@@ -1209,6 +1221,12 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
       this->create_version_sections(&versions, symtab, local_dynamic_count,
                                    dynamic_symbols, dynstr);
     }
+  
+  if (this->incremental_inputs_)
+    {
+      this->incremental_inputs_->finalize();
+      this->create_incremental_info_sections();
+    }
 
   // If there is a SECTIONS clause, put all the input sections into
   // the required order.
@@ -1220,7 +1238,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   else
     load_seg = this->find_first_load_seg();
 
-  if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
+  if (parameters->options().oformat_enum()
+      != General_options::OBJECT_FORMAT_ELF)
     load_seg = NULL;
 
   gold_assert(phdr_seg == NULL || load_seg != NULL);
@@ -1241,7 +1260,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   // Lay out the file header.
   Output_file_header* file_header;
   file_header = new Output_file_header(target, symtab, segment_headers,
-                                      this->options_.entry());
+                                      parameters->options().entry());
   if (load_seg != NULL)
     load_seg->add_initial_output_data(file_header);
 
@@ -1454,8 +1473,8 @@ void
 Layout::create_executable_stack_info(const Target* target)
 {
   bool is_stack_executable;
-  if (this->options_.is_execstack_set())
-    is_stack_executable = this->options_.is_stack_executable();
+  if (parameters->options().is_execstack_set())
+    is_stack_executable = parameters->options().is_stack_executable();
   else if (!this->input_with_gnu_stack_note_)
     return;
   else
@@ -1586,6 +1605,37 @@ Layout::create_build_id()
     }
 }
 
+// Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed
+// for the next run of incremental linking to check what has changed.
+
+void
+Layout::create_incremental_info_sections()
+{
+  gold_assert(this->incremental_inputs_ != NULL);
+
+  // Add the .gnu_incremental_inputs section.
+  const char *incremental_inputs_name =
+    this->namepool_.add(".gnu_incremental_inputs", false, NULL);
+  Output_section* inputs_os =
+    this->make_output_section(incremental_inputs_name,
+                             elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0);
+  Output_section_data* posd =
+      this->incremental_inputs_->create_incremental_inputs_section_data();
+  inputs_os->add_output_section_data(posd);
+  
+  // Add the .gnu_incremental_strtab section.
+  const char *incremental_strtab_name =
+    this->namepool_.add(".gnu_incremental_strtab", false, NULL);
+  Output_section* strtab_os = this->make_output_section(incremental_strtab_name,
+                                                        elfcpp::SHT_STRTAB,
+                                                        0);
+  Output_data_strtab* strtab_data =
+    new Output_data_strtab(this->incremental_inputs_->get_stringpool());
+  strtab_os->add_output_section_data(strtab_data);
+  
+  inputs_os->set_link_section(strtab_data);
+}
+
 // Return whether SEG1 should be before SEG2 in the output file.  This
 // is based entirely on the segment type and flags.  When this is
 // called the segment addresses has normally not yet been set.
@@ -1717,8 +1767,8 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
   // Find the PT_LOAD segments, and set their addresses and offsets
   // and their section's addresses and offsets.
   uint64_t addr;
-  if (this->options_.user_set_Ttext())
-    addr = this->options_.Ttext();
+  if (parameters->options().user_set_Ttext())
+    addr = parameters->options().Ttext();
   else if (parameters->options().shared())
     addr = 0;
   else
@@ -1761,19 +1811,19 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
              // the physical address.
              addr = (*p)->paddr();
            }
-         else if (this->options_.user_set_Tdata()
+         else if (parameters->options().user_set_Tdata()
                   && ((*p)->flags() & elfcpp::PF_W) != 0
-                  && (!this->options_.user_set_Tbss()
+                  && (!parameters->options().user_set_Tbss()
                       || (*p)->has_any_data_sections()))
            {
-             addr = this->options_.Tdata();
+             addr = parameters->options().Tdata();
              are_addresses_set = true;
            }
-         else if (this->options_.user_set_Tbss()
+         else if (parameters->options().user_set_Tbss()
                   && ((*p)->flags() & elfcpp::PF_W) != 0
                   && !(*p)->has_any_data_sections())
            {
-             addr = this->options_.Tbss();
+             addr = parameters->options().Tbss();
              are_addresses_set = true;
            }
 
@@ -2616,7 +2666,7 @@ Layout::sized_create_version_sections(
 void
 Layout::create_interp(const Target* target)
 {
-  const char* interp = this->options_.dynamic_linker();
+  const char* interp = parameters->options().dynamic_linker();
   if (interp == NULL)
     {
       interp = target->dynamic_linker();
@@ -2668,7 +2718,7 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
 
   if (parameters->options().shared())
     {
-      const char* soname = this->options_.soname();
+      const char* soname = parameters->options().soname();
       if (soname != NULL)
        odyn->add_string(elfcpp::DT_SONAME, soname);
     }
@@ -2685,7 +2735,7 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
   // FIXME: Support DT_INIT_ARRAY and DT_FINI_ARRAY.
 
   // Add a DT_RPATH entry if needed.
-  const General_options::Dir_list& rpath(this->options_.rpath());
+  const General_options::Dir_list& rpath(parameters->options().rpath());
   if (!rpath.empty())
     {
       std::string rpath_val;
@@ -2899,6 +2949,9 @@ Layout::output_section_name(const char* name, size_t* plen)
   // initial '.', we use the name unchanged (i.e., "mysection" and
   // ".text" are unchanged).
 
+  // If the name starts with '.note', we keep it unchanged (e.g. to
+  // avoid truncating '.note.ABI-tag' to '.note').
+
   // If the name starts with ".data.rel.ro.local" we use
   // ".data.rel.ro.local".
 
@@ -2914,6 +2967,8 @@ Layout::output_section_name(const char* name, size_t* plen)
   const char* sdot = strchr(s, '.');
   if (sdot == NULL)
     return name;
+  if (strncmp(name, ".note.", 6) == 0)
+    return name;
 
   const char* const data_rel_ro_local = ".data.rel.ro.local";
   if (strncmp(name, data_rel_ro_local, strlen(data_rel_ro_local)) == 0)
@@ -2943,10 +2998,21 @@ Layout::output_section_name(const char* name, size_t* plen)
 // CANDIDATE.
 
 bool
-Layout::find_or_add_kept_section(const std::string name,
+Layout::find_or_add_kept_section(const std::string& name,
                                  Kept_section* candidate,
                                  Kept_section** kept_section)
 {
+  // It's normal to see a couple of entries here, for the x86 thunk
+  // sections.  If we see more than a few, we're linking a C++
+  // program, and we resize to get more space to minimize rehashing.
+  if (this->signatures_.size() > 4
+      && !this->resized_signatures_)
+    {
+      reserve_unordered_map(&this->signatures_,
+                           this->number_of_input_files_ * 64);
+      this->resized_signatures_ = true;
+    }
+
   std::pair<Signatures::iterator, bool> ins(
     this->signatures_.insert(std::make_pair(name, *candidate)));
 
@@ -3183,7 +3249,7 @@ Layout::write_build_id(Output_file* of) const
 void
 Layout::write_binary(Output_file* in) const
 {
-  gold_assert(this->options_.oformat_enum()
+  gold_assert(parameters->options().oformat_enum()
              == General_options::OBJECT_FORMAT_BINARY);
 
   // Get the size of the binary file.
This page took 0.027383 seconds and 4 git commands to generate.