ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / gold / layout.cc
index f2dc6da1913e6901e2bfb87286516995743c2bc5..acc03b21e19bf09cbb035709abdfb79945e56e7b 100644 (file)
@@ -1,7 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -236,6 +235,54 @@ Free_list::print_stats()
          program_name, Free_list::num_allocate_visits);
 }
 
+// A Hash_task computes the MD5 checksum of an array of char.
+// It has a blocker on either side (i.e., the task cannot run until
+// the first is unblocked, and it unblocks the second after running).
+
+class Hash_task : public Task
+{
+ public:
+  Hash_task(const unsigned char* src,
+           size_t size,
+           unsigned char* dst,
+           Task_token* build_id_blocker,
+           Task_token* final_blocker)
+    : src_(src), size_(size), dst_(dst), build_id_blocker_(build_id_blocker),
+      final_blocker_(final_blocker)
+  { }
+
+  void
+  run(Workqueue*)
+  { md5_buffer(reinterpret_cast<const char*>(src_), size_, dst_); }
+
+  Task_token*
+  is_runnable();
+
+  // Unblock FINAL_BLOCKER_ when done.
+  void
+  locks(Task_locker* tl)
+  { tl->add(this, this->final_blocker_); }
+
+  std::string
+  get_name() const
+  { return "Hash_task"; }
+
+ private:
+  const unsigned char* const src_;
+  const size_t size_;
+  unsigned char* const dst_;
+  Task_token* const build_id_blocker_;
+  Task_token* const final_blocker_;
+};
+
+Task_token*
+Hash_task::is_runnable()
+{
+  if (this->build_id_blocker_->is_blocked())
+    return this->build_id_blocker_;
+  return NULL;
+}
+
 // Layout::Relaxation_debug_check methods.
 
 // Check that sections and special data are in reset states.
@@ -245,7 +292,8 @@ Free_list::print_stats()
 void
 Layout::Relaxation_debug_check::check_output_data_for_reset_values(
     const Layout::Section_list& sections,
-    const Layout::Data_list& special_outputs)
+    const Layout::Data_list& special_outputs,
+    const Layout::Data_list& relax_outputs)
 {
   for(Layout::Section_list::const_iterator p = sections.begin();
       p != sections.end();
@@ -256,6 +304,8 @@ Layout::Relaxation_debug_check::check_output_data_for_reset_values(
       p != special_outputs.end();
       ++p)
     gold_assert((*p)->address_and_file_offset_have_reset_values());
+
+  gold_assert(relax_outputs.empty());
 }
 
 // Save information of SECTIONS for checking later.
@@ -380,6 +430,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
     section_list_(),
     unattached_section_list_(),
     special_output_list_(),
+    relax_output_list_(),
     section_headers_(NULL),
     tls_segment_(NULL),
     relro_segment_(NULL),
@@ -398,6 +449,9 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
     eh_frame_hdr_section_(NULL),
     gdb_index_data_(NULL),
     build_id_note_(NULL),
+    array_of_hashes_(NULL),
+    size_of_array_of_hashes_(0),
+    input_view_(NULL),
     debug_abbrev_(NULL),
     debug_info_(NULL),
     group_signatures_(),
@@ -470,6 +524,7 @@ static const char* gdb_sections[] =
   "addr",         // Fission extension
   // "aranges",   // not used by gdb as of 7.4
   "frame",
+  "gdb_scripts",
   "info",
   "types",
   "line",
@@ -478,8 +533,11 @@ static const char* gdb_sections[] =
   "macro",
   // "pubnames",  // not used by gdb as of 7.4
   // "pubtypes",  // not used by gdb as of 7.4
+  // "gnu_pubnames",  // Fission extension
+  // "gnu_pubtypes",  // Fission extension
   "ranges",
   "str",
+  "str_offsets",
 };
 
 // This is the minimum set of sections needed for line numbers.
@@ -490,6 +548,7 @@ static const char* lines_only_debug_sections[] =
   // "addr",      // Fission extension
   // "aranges",   // not used by gdb as of 7.4
   // "frame",
+  // "gdb_scripts",
   "info",
   // "types",
   "line",
@@ -498,8 +557,11 @@ static const char* lines_only_debug_sections[] =
   // "macro",
   // "pubnames",  // not used by gdb as of 7.4
   // "pubtypes",  // not used by gdb as of 7.4
+  // "gnu_pubnames",  // Fission extension
+  // "gnu_pubtypes",  // Fission extension
   // "ranges",
   "str",
+  "str_offsets",  // Fission extension
 };
 
 // These sections are the DWARF fast-lookup tables, and are not needed
@@ -509,7 +571,9 @@ static const char* gdb_fast_lookup_sections[] =
 {
   "aranges",
   "pubnames",
+  "gnu_pubnames",
   "pubtypes",
+  "gnu_pubtypes",
 };
 
 // Returns whether the given debug section is in the list of
@@ -590,7 +654,13 @@ Layout::include_section(Sized_relobj_file<size, big_endian>*, const char* name,
       && (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE))
     return false;
 
-  switch (shdr.get_sh_type())
+  elfcpp::Elf_Word sh_type = shdr.get_sh_type();
+
+  if ((sh_type >= elfcpp::SHT_LOOS && sh_type <= elfcpp::SHT_HIOS)
+      || (sh_type >= elfcpp::SHT_LOPROC && sh_type <= elfcpp::SHT_HIPROC))
+    return parameters->target().should_include_section(sh_type);
+
+  switch (sh_type)
     {
     case elfcpp::SHT_NULL:
     case elfcpp::SHT_SYMTAB:
@@ -1047,7 +1117,7 @@ Layout::special_ordering_of_input_section(const char* name)
   // wind up in the .text section.  Sections that start with these
   // prefixes must appear first, and must appear in the order listed
   // here.
-  static const char* const text_section_sort[] = 
+  static const char* const text_section_sort[] =
   {
     ".text.unlikely",
     ".text.exit",
@@ -1107,7 +1177,7 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
          = this->section_segment_map_.find(Const_section_id(object, shndx));
       if (it == this->section_segment_map_.end())
        {
-          os = this->choose_output_section(object, name, sh_type,
+         os = this->choose_output_section(object, name, sh_type,
                                           shdr.get_sh_flags(), true,
                                           ORDER_INVALID, false);
        }
@@ -1203,7 +1273,7 @@ void
 Layout::insert_section_segment_map(Const_section_id secn,
                                   Unique_segment_info *s)
 {
-  gold_assert(this->unique_segment_for_sections_specified_); 
+  gold_assert(this->unique_segment_for_sections_specified_);
   this->section_segment_map_[secn] = s;
 }
 
@@ -1658,6 +1728,10 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
       && strcmp(name, ".text") == 0)
     os->set_may_sort_attached_input_sections();
 
+  // GNU linker sorts section by name with --sort-section=name.
+  if (strcmp(parameters->options().sort_section(), "name") == 0)
+      os->set_must_sort_attached_input_sections();
+
   // Check for .stab*str sections, as .stab* sections need to link to
   // them.
   if (type == elfcpp::SHT_STRTAB
@@ -1839,44 +1913,44 @@ Layout::attach_allocated_section_to_segment(const Target* target,
   if (!os->is_unique_segment())
     {
       for (p = this->segment_list_.begin();
-          p != this->segment_list_.end();
+          p != this->segment_list_.end();
           ++p)
        {
-         if ((*p)->type() != elfcpp::PT_LOAD)                        
-           continue;                        
-         if ((*p)->is_unique_segment())                        
-           continue;                        
-         if (!parameters->options().omagic()                        
-             && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))                        
-           continue;                        
-         if ((target->isolate_execinstr() || parameters->options().rosegment())                        
-             && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))                        
-           continue;                        
-         // If -Tbss was specified, we need to separate the data and BSS                        
-         // segments.                        
-         if (parameters->options().user_set_Tbss())                        
-           {                        
-             if ((os->type() == elfcpp::SHT_NOBITS)                        
-                 == (*p)->has_any_data_sections())                        
-               continue;                        
-           }                        
-         if (os->is_large_data_section() && !(*p)->is_large_data_segment())                        
-           continue;                        
-                           
-         if (is_address_set)                        
-           {                        
-             if ((*p)->are_addresses_set())                        
-               continue;                        
-                           
-             (*p)->add_initial_output_data(os);                        
-             (*p)->update_flags_for_output_section(seg_flags);                        
-             (*p)->set_addresses(addr, addr);                        
-             break;                        
-           }                        
-                           
-         (*p)->add_output_section_to_load(this, os, seg_flags);                        
-         break;                        
-       }                        
+         if ((*p)->type() != elfcpp::PT_LOAD)
+           continue;
+         if ((*p)->is_unique_segment())
+           continue;
+         if (!parameters->options().omagic()
+             && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
+           continue;
+         if ((target->isolate_execinstr() || parameters->options().rosegment())
+             && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))
+           continue;
+         // If -Tbss was specified, we need to separate the data and BSS
+         // segments.
+         if (parameters->options().user_set_Tbss())
+           {
+             if ((os->type() == elfcpp::SHT_NOBITS)
+                 == (*p)->has_any_data_sections())
+               continue;
+           }
+         if (os->is_large_data_section() && !(*p)->is_large_data_segment())
+           continue;
+
+         if (is_address_set)
+           {
+             if ((*p)->are_addresses_set())
+               continue;
+
+             (*p)->add_initial_output_data(os);
+             (*p)->update_flags_for_output_section(seg_flags);
+             (*p)->set_addresses(addr, addr);
+             break;
+           }
+
+         (*p)->add_output_section_to_load(this, os, seg_flags);
+         break;
+       }
     }
 
   if (p == this->segment_list_.end()
@@ -2027,8 +2101,7 @@ Layout::layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags,
       if ((gnu_stack_flags & elfcpp::SHF_EXECINSTR) != 0)
        {
          this->input_requires_executable_stack_ = true;
-         if (parameters->options().warn_execstack()
-             || parameters->options().is_stack_executable())
+         if (parameters->options().warn_execstack())
            gold_warning(_("%s: requires executable stack"),
                         obj->name().c_str());
        }
@@ -2286,6 +2359,20 @@ Layout::clean_up_after_relaxation()
        ++p)
     delete *p;
   this->script_output_section_data_list_.clear();
+
+  // Special-case fill output objects are recreated each time through
+  // the relaxation loop.
+  this->reset_relax_output();
+}
+
+void
+Layout::reset_relax_output()
+{
+  for (Data_list::const_iterator p = this->relax_output_list_.begin();
+       p != this->relax_output_list_.end();
+       ++p)
+    delete *p;
+  this->relax_output_list_.clear();
 }
 
 // Prepare for relaxation.
@@ -2308,12 +2395,29 @@ Layout::prepare_for_relaxation()
 
   if (is_debugging_enabled(DEBUG_RELAXATION))
     this->relaxation_debug_check_->check_output_data_for_reset_values(
-       this->section_list_, this->special_output_list_);
+       this->section_list_, this->special_output_list_,
+       this->relax_output_list_);
 
   // Also enable recording of output section data from scripts.
   this->record_output_section_data_from_script_ = true;
 }
 
+// If the user set the address of the text segment, that may not be
+// compatible with putting the segment headers and file headers into
+// that segment.  For isolate_execinstr() targets, it's the rodata
+// segment rather than text where we might put the headers.
+static inline bool
+load_seg_unusable_for_headers(const Target* target)
+{
+  const General_options& options = parameters->options();
+  if (target->isolate_execinstr())
+    return (options.user_set_Trodata_segment()
+           && options.Trodata_segment() % target->abi_pagesize() != 0);
+  else
+    return (options.user_set_Ttext()
+           && options.Ttext() % target->abi_pagesize() != 0);
+}
+
 // Relaxation loop body:  If target has no relaxation, this runs only once
 // Otherwise, the target relaxation hook is called at the end of
 // each iteration.  If the hook returns true, it means re-layout of
@@ -2366,11 +2470,7 @@ Layout::relaxation_loop_body(
       != General_options::OBJECT_FORMAT_ELF)
     load_seg = NULL;
 
-  // If the user set the address of the text segment, that may not be
-  // compatible with putting the segment headers and file headers into
-  // that segment.
-  if (parameters->options().user_set_Ttext()
-      && parameters->options().Ttext() % target->abi_pagesize() != 0)
+  if (load_seg_unusable_for_headers(target))
     {
       load_seg = NULL;
       phdr_seg = NULL;
@@ -2658,12 +2758,14 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   // If there is a load segment that contains the file and program headers,
   // provide a symbol __ehdr_start pointing there.
   // A program can use this to examine itself robustly.
-  if (load_seg != NULL)
-    symtab->define_in_output_segment("__ehdr_start", NULL,
-                                    Symbol_table::PREDEFINED, load_seg, 0, 0,
-                                    elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
-                                    elfcpp::STV_DEFAULT, 0,
-                                    Symbol::SEGMENT_START, true);
+  Symbol *ehdr_start = symtab->lookup("__ehdr_start");
+  if (ehdr_start != NULL && ehdr_start->is_predefined())
+    {
+      if (load_seg != NULL)
+       ehdr_start->set_output_segment(load_seg, Symbol::SEGMENT_START);
+      else
+        ehdr_start->set_undefined();
+    }
 
   // Set the file offsets of all the non-data sections we've seen so
   // far which don't have to wait for the input sections.  We need
@@ -2872,7 +2974,14 @@ Layout::create_executable_stack_info()
 {
   bool is_stack_executable;
   if (parameters->options().is_execstack_set())
-    is_stack_executable = parameters->options().is_stack_executable();
+    {
+      is_stack_executable = parameters->options().is_stack_executable();
+      if (!is_stack_executable
+          && this->input_requires_executable_stack_
+          && parameters->options().warn_execstack())
+       gold_warning(_("one or more inputs require executable stack, "
+                      "but -z noexecstack was given"));
+    }
   else if (!this->input_with_gnu_stack_note_)
     return;
   else
@@ -2924,7 +3033,7 @@ Layout::create_build_id()
   std::string desc;
   if (strcmp(style, "md5") == 0)
     descsz = 128 / 8;
-  else if (strcmp(style, "sha1") == 0)
+  else if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
     descsz = 160 / 8;
   else if (strcmp(style, "uuid") == 0)
     {
@@ -3175,12 +3284,14 @@ Layout::segment_precedes(const Output_segment* seg1,
 
   // The order of non-PT_LOAD segments is unimportant.  We simply sort
   // by the numeric segment type and flags values.  There should not
-  // be more than one segment with the same type and flags.
+  // be more than one segment with the same type and flags, except
+  // when a linker script specifies such.
   if (type1 != elfcpp::PT_LOAD)
     {
       if (type1 != type2)
        return type1 < type2;
-      gold_assert(flags1 != flags2);
+      gold_assert(flags1 != flags2
+                 || this->script_options_->saw_phdrs_clause());
       return flags1 < flags2;
     }
 
@@ -3262,6 +3373,20 @@ align_file_offset(off_t off, uint64_t addr, uint64_t abi_pagesize)
   return aligned_off;
 }
 
+// On targets where the text segment contains only executable code,
+// a non-executable segment is never the text segment.
+
+static inline bool
+is_text_segment(const Target* target, const Output_segment* seg)
+{
+  elfcpp::Elf_Xword flags = seg->flags();
+  if ((flags & elfcpp::PF_W) != 0)
+    return false;
+  if ((flags & elfcpp::PF_X) == 0)
+    return !target->isolate_execinstr();
+  return true;
+}
+
 // Set the file offsets of all the segments, and all the sections they
 // contain.  They have all been created.  LOAD_SEG must be be laid out
 // first.  Return the offset of the data to follow.
@@ -3354,8 +3479,14 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
            }
          else if (parameters->options().user_set_Ttext()
                   && (parameters->options().omagic()
-                      || ((*p)->flags() & elfcpp::PF_W) == 0))
+                      || is_text_segment(target, *p)))
+           {
+             are_addresses_set = true;
+           }
+         else if (parameters->options().user_set_Trodata_segment()
+                  && ((*p)->flags() & (elfcpp::PF_W | elfcpp::PF_X)) == 0)
            {
+             addr = parameters->options().Trodata_segment();
              are_addresses_set = true;
            }
          else if (parameters->options().user_set_Tdata()
@@ -3404,7 +3535,10 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
                  // If the target wants a fixed minimum distance from the
                  // text segment to the read-only segment, move up now.
-                 uint64_t min_addr = start_addr + target->rosegment_gap();
+                 uint64_t min_addr =
+                   start_addr + (parameters->options().user_set_rosegment_gap()
+                                 ? parameters->options().rosegment_gap()
+                                 : target->rosegment_gap());
                  if (addr < min_addr)
                    addr = min_addr;
 
@@ -3425,7 +3559,13 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          if (!parameters->options().nmagic()
              && !parameters->options().omagic())
-           off = align_file_offset(off, addr, abi_pagesize);
+           {
+             // Here we are also taking care of the case when
+             // the maximum segment alignment is larger than the page size.
+             off = align_file_offset(off, addr,
+                                     std::max(abi_pagesize,
+                                              (*p)->maximum_alignment()));
+           }
          else
            {
              // This is -N or -n with a section script which prevents
@@ -3442,7 +3582,8 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          unsigned int shndx_hold = *pshndx;
          bool has_relro = false;
-         uint64_t new_addr = (*p)->set_section_addresses(this, false, addr,
+         uint64_t new_addr = (*p)->set_section_addresses(target, this,
+                                                         false, addr,
                                                          &increase_relro,
                                                          &has_relro,
                                                          &off, pshndx);
@@ -3483,7 +3624,8 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
                    increase_relro = 0;
                  has_relro = false;
 
-                 new_addr = (*p)->set_section_addresses(this, true, addr,
+                 new_addr = (*p)->set_section_addresses(target, this,
+                                                        true, addr,
                                                         &increase_relro,
                                                         &has_relro,
                                                         &off, pshndx);
@@ -3519,6 +3661,8 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
       // so they land after the segments starting at LOAD_SEG.
       off = align_file_offset(off, 0, target->abi_pagesize());
 
+      this->reset_relax_output();
+
       for (Segment_list::iterator p = this->segment_list_.begin();
           *p != load_seg;
           ++p)
@@ -3532,8 +3676,8 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
              bool has_relro = false;
              const uint64_t old_addr = (*p)->vaddr();
              const uint64_t old_end = old_addr + (*p)->memsz();
-             uint64_t new_addr = (*p)->set_section_addresses(this, true,
-                                                             old_addr,
+             uint64_t new_addr = (*p)->set_section_addresses(target, this,
+                                                             true, old_addr,
                                                              &increase_relro,
                                                              &has_relro,
                                                              &off,
@@ -4178,18 +4322,20 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        }
     }
 
-  // Create the hash tables.
+  // Create the hash tables.  The Gnu-style hash table must be
+  // built first, because it changes the order of the symbols
+  // in the dynamic symbol table.
 
-  if (strcmp(parameters->options().hash_style(), "sysv") == 0
+  if (strcmp(parameters->options().hash_style(), "gnu") == 0
       || strcmp(parameters->options().hash_style(), "both") == 0)
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
-       this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
+       this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
                                    elfcpp::SHF_ALLOC, false,
                                    ORDER_DYNAMIC_LINKER, false);
 
@@ -4204,23 +4350,28 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        {
          if (dynsym != NULL)
            hashsec->set_link_section(dynsym);
-         hashsec->set_entsize(4);
-       }
 
-      if (odyn != NULL)
-       odyn->add_section_address(elfcpp::DT_HASH, hashsec);
+         // For a 64-bit target, the entries in .gnu.hash do not have
+         // a uniform size, so we only set the entry size for a
+         // 32-bit target.
+         if (parameters->target().get_size() == 32)
+           hashsec->set_entsize(4);
+
+         if (odyn != NULL)
+           odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+       }
     }
 
-  if (strcmp(parameters->options().hash_style(), "gnu") == 0
+  if (strcmp(parameters->options().hash_style(), "sysv") == 0
       || strcmp(parameters->options().hash_style(), "both") == 0)
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
-       this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
+       this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
                                    elfcpp::SHF_ALLOC, false,
                                    ORDER_DYNAMIC_LINKER, false);
 
@@ -4235,16 +4386,11 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        {
          if (dynsym != NULL)
            hashsec->set_link_section(dynsym);
-
-         // For a 64-bit target, the entries in .gnu.hash do not have
-         // a uniform size, so we only set the entry size for a
-         // 32-bit target.
-         if (parameters->target().get_size() == 32)
-           hashsec->set_entsize(4);
-
-         if (odyn != NULL)
-           odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+         hashsec->set_entsize(4);
        }
+
+      if (odyn != NULL)
+       odyn->add_section_address(elfcpp::DT_HASH, hashsec);
     }
 }
 
@@ -4737,6 +4883,8 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
     odyn->add_constant(elfcpp::DT_FLAGS, flags);
 
   flags = 0;
+  if (parameters->options().global())
+    flags |= elfcpp::DF_1_GLOBAL;
   if (parameters->options().initfirst())
     flags |= elfcpp::DF_1_INITFIRST;
   if (parameters->options().interpose())
@@ -5170,6 +5318,13 @@ Layout::write_data(const Symbol_table* symtab, Output_file* of) const
        p != this->special_output_list_.end();
        ++p)
     (*p)->write(of);
+
+  // Write out the Output_data which are not in an Output_section
+  // and are regenerated in each iteration of relaxation.
+  for (Data_list::const_iterator p = this->relax_output_list_.begin();
+       p != this->relax_output_list_.end();
+       ++p)
+    (*p)->write(of);
 }
 
 // Write out the Output_sections which can only be written after the
@@ -5210,9 +5365,53 @@ Layout::write_sections_after_input_sections(Output_file* of)
   this->section_headers_->write(of);
 }
 
-// If the build ID requires computing a checksum, do so here, and
-// write it out.  We compute a checksum over the entire file because
-// that is simplest.
+// Build IDs can be computed as a "flat" sha1 or md5 of a string of bytes,
+// or as a "tree" where each chunk of the string is hashed and then those
+// hashes are put into a (much smaller) string which is hashed with sha1.
+// We compute a checksum over the entire file because that is simplest.
+
+Task_token*
+Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
+                            Output_file* of)
+{
+  const size_t filesize = (this->output_file_size() <= 0 ? 0
+                          : static_cast<size_t>(this->output_file_size()));
+  if (this->build_id_note_ != NULL
+      && strcmp(parameters->options().build_id(), "tree") == 0
+      && parameters->options().build_id_chunk_size_for_treehash() > 0
+      && filesize > 0
+      && (filesize >=
+         parameters->options().build_id_min_file_size_for_treehash()))
+    {
+      static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
+      const size_t chunk_size =
+         parameters->options().build_id_chunk_size_for_treehash();
+      const size_t num_hashes = ((filesize - 1) / chunk_size) + 1;
+      Task_token* post_hash_tasks_blocker = new Task_token(true);
+      post_hash_tasks_blocker->add_blockers(num_hashes);
+      this->size_of_array_of_hashes_ = num_hashes * MD5_OUTPUT_SIZE_IN_BYTES;
+      const unsigned char* src = of->get_input_view(0, filesize);
+      this->input_view_ = src;
+      unsigned char *dst = new unsigned char[this->size_of_array_of_hashes_];
+      this->array_of_hashes_ = dst;
+      for (size_t i = 0, src_offset = 0; i < num_hashes;
+          i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
+       {
+         size_t size = std::min(chunk_size, filesize - src_offset);
+         workqueue->queue(new Hash_task(src + src_offset,
+                                        size,
+                                        dst,
+                                        build_id_blocker,
+                                        post_hash_tasks_blocker));
+       }
+      return post_hash_tasks_blocker;
+    }
+  return build_id_blocker;
+}
+
+// If a tree-style build ID was requested, the parallel part of that computation
+// is already done, and the final hash-of-hashes is computed here.  For other
+// types of build IDs, all the work is done here.
 
 void
 Layout::write_build_id(Output_file* of) const
@@ -5220,34 +5419,39 @@ Layout::write_build_id(Output_file* of) const
   if (this->build_id_note_ == NULL)
     return;
 
-  const unsigned char* iv = of->get_input_view(0, this->output_file_size_);
-
   unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
                                          this->build_id_note_->data_size());
 
-  const char* style = parameters->options().build_id();
-  if (strcmp(style, "sha1") == 0)
+  if (this->array_of_hashes_ == NULL)
     {
-      sha1_ctx ctx;
-      sha1_init_ctx(&ctx);
-      sha1_process_bytes(iv, this->output_file_size_, &ctx);
-      sha1_finish_ctx(&ctx, ov);
+      const size_t output_file_size = this->output_file_size();
+      const unsigned char* iv = of->get_input_view(0, output_file_size);
+      const char* style = parameters->options().build_id();
+
+      // If we get here with style == "tree" then the output must be
+      // too small for chunking, and we use SHA-1 in that case.
+      if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
+       sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+      else if (strcmp(style, "md5") == 0)
+       md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+      else
+       gold_unreachable();
+
+      of->free_input_view(0, output_file_size, iv);
     }
-  else if (strcmp(style, "md5") == 0)
+  else
     {
-      md5_ctx ctx;
-      md5_init_ctx(&ctx);
-      md5_process_bytes(iv, this->output_file_size_, &ctx);
-      md5_finish_ctx(&ctx, ov);
+      // Non-overlapping substrings of the output file have been hashed.
+      // Compute SHA-1 hash of the hashes.
+      sha1_buffer(reinterpret_cast<const char*>(this->array_of_hashes_),
+                 this->size_of_array_of_hashes_, ov);
+      delete[] this->array_of_hashes_;
+      of->free_input_view(0, this->output_file_size(), this->input_view_);
     }
-  else
-    gold_unreachable();
 
   of->write_output_view(this->build_id_note_->offset(),
                        this->build_id_note_->data_size(),
                        ov);
-
-  of->free_input_view(0, this->output_file_size_, iv);
 }
 
 // Write out a binary file.  This is called after the link is
@@ -5308,6 +5512,10 @@ Layout::print_to_mapfile(Mapfile* mapfile) const
        p != this->segment_list_.end();
        ++p)
     (*p)->print_sections_to_mapfile(mapfile);
+  for (Section_list::const_iterator p = this->unattached_section_list_.begin();
+       p != this->unattached_section_list_.end();
+       ++p)
+    (*p)->print_to_mapfile(mapfile);
 }
 
 // Print statistical information to stderr.  This is used for --stats.
@@ -5342,6 +5550,8 @@ void
 Write_sections_task::locks(Task_locker* tl)
 {
   tl->add(this, this->output_sections_blocker_);
+  if (this->input_sections_blocker_ != NULL)
+    tl->add(this, this->input_sections_blocker_);
   tl->add(this, this->final_blocker_);
 }
 
@@ -5437,12 +5647,14 @@ Write_after_input_sections_task::run(Workqueue*)
 
 // Close_task_runner methods.
 
-// Run the task--close the file.
+// Finish up the build ID computation, if necessary, and write a binary file,
+// if necessary.  Then close the output file.
 
 void
 Close_task_runner::run(Workqueue*, const Task*)
 {
-  // If we need to compute a checksum for the BUILD if, we do so here.
+  // At this point the multi-threaded part of the build ID computation,
+  // if any, is done.  See queue_build_id_tasks().
   this->layout_->write_build_id(this->of_);
 
   // If we've been asked to create a binary file, we do so here.
This page took 0.03319 seconds and 4 git commands to generate.