Fix PR PR16445 - gdbserver build failure on x86.
[deliverable/binutils-gdb.git] / gold / layout.cc
index b593acdb0b2ce989be51567a3bf817141eabff10..38fd272b7050cde510de86d3ad82291422f377de 100644 (file)
@@ -1,6 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 // Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
@@ -244,10 +244,10 @@ 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)
+           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)
   { }
@@ -293,7 +293,8 @@ Hash_task::is_runnable()
 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();
@@ -304,6 +305,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.
@@ -428,6 +431,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),
@@ -1098,7 +1102,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",
@@ -1158,7 +1162,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);
        }
@@ -1254,7 +1258,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;
 }
 
@@ -1709,6 +1713,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
@@ -1890,44 +1898,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()
@@ -2337,6 +2345,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.
@@ -2359,12 +2381,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
@@ -2417,11 +2456,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;
@@ -2713,7 +2748,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
     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,
+                                    elfcpp::STV_HIDDEN, 0,
                                     Symbol::SEGMENT_START, true);
 
   // Set the file offsets of all the non-data sections we've seen so
@@ -3315,6 +3350,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.
@@ -3407,10 +3456,16 @@ 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()
                   && ((*p)->flags() & elfcpp::PF_W) != 0
                   && (!parameters->options().user_set_Tbss()
@@ -3457,7 +3512,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;
 
@@ -3478,7 +3536,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
@@ -3495,7 +3559,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);
@@ -3536,7 +3601,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);
@@ -3572,6 +3638,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)
@@ -3585,8 +3653,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,
@@ -5223,6 +5291,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
@@ -5270,20 +5345,20 @@ Layout::write_sections_after_input_sections(Output_file* of)
 
 Task_token*
 Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
-                             Output_file* of)
+                            Output_file* of)
 {
   const size_t filesize = (this->output_file_size() <= 0 ? 0
-                           : static_cast<size_t>(this->output_file_size()));
+                          : 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()))
+         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();
+         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);
@@ -5293,15 +5368,15 @@ Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
       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));
-        }
+          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;
@@ -5318,7 +5393,7 @@ Layout::write_build_id(Output_file* of) const
     return;
 
   unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
-                                          this->build_id_note_->data_size());
+                                         this->build_id_note_->data_size());
 
   if (this->array_of_hashes_ == NULL)
     {
@@ -5329,11 +5404,11 @@ Layout::write_build_id(Output_file* of) const
       // 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);
+       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);
+       md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
       else
-        gold_unreachable();
+       gold_unreachable();
 
       of->free_input_view(0, output_file_size, iv);
     }
@@ -5342,7 +5417,7 @@ Layout::write_build_id(Output_file* of) const
       // 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);
+                 this->size_of_array_of_hashes_, ov);
       delete[] this->array_of_hashes_;
       of->free_input_view(0, this->output_file_size(), this->input_view_);
     }
This page took 0.032376 seconds and 4 git commands to generate.