* gas/mips/jal.d: Remove duplicate pattern.
[deliverable/binutils-gdb.git] / gold / layout.cc
index eb1322ae6affdfd82cb38ecdcdf6349ad9436ce0..b5490d665c06a9a697be18dd22529ce7392da158 100644 (file)
@@ -503,10 +503,15 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
       const char* file_name = relobj == NULL ? NULL : relobj->name().c_str();
       Output_section** output_section_slot;
       Script_sections::Section_type script_section_type;
+      const char* orig_name = name;
       name = ss->output_section_name(file_name, name, &output_section_slot,
                                     &script_section_type);
       if (name == NULL)
        {
+         gold_debug(DEBUG_SCRIPT, _("Unable to create output section '%s' "
+                                    "because it is not allowed by the "
+                                    "SECTIONS clause of the linker script"),
+                    orig_name);
          // The SECTIONS clause says to discard this input section.
          return NULL;
        }
@@ -1166,10 +1171,11 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
   bool is_address_set = parameters->options().section_start(os->name(), &addr);
 
   // In general the only thing we really care about for PT_LOAD
-  // segments is whether or not they are writable, so that is how we
-  // search for them.  Large data sections also go into their own
-  // PT_LOAD segment.  People who need segments sorted on some other
-  // basis will have to use a linker script.
+  // segments is whether or not they are writable or executable,
+  // so that is how we search for them.
+  // Large data sections also go into their own PT_LOAD segment.
+  // People who need segments sorted on some other basis will
+  // have to use a linker script.
 
   Segment_list::const_iterator p;
   for (p = this->segment_list_.begin();
@@ -1181,6 +1187,9 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
       if (!parameters->options().omagic()
          && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
        continue;
+      if (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())
@@ -1449,6 +1458,7 @@ Layout::define_group_signatures(Symbol_table* symtab)
 Output_segment*
 Layout::find_first_load_seg()
 {
+  Output_segment* best = NULL;
   for (Segment_list::const_iterator p = this->segment_list_.begin();
        p != this->segment_list_.end();
        ++p)
@@ -1457,8 +1467,13 @@ Layout::find_first_load_seg()
          && ((*p)->flags() & elfcpp::PF_R) != 0
          && (parameters->options().omagic()
              || ((*p)->flags() & elfcpp::PF_W) == 0))
-       return *p;
+        {
+          if (best == NULL || this->segment_precedes(*p, best))
+            best = *p;
+        }
     }
+  if (best != NULL)
+    return best;
 
   gold_assert(!this->script_options_->saw_phdrs_clause());
 
@@ -2099,7 +2114,7 @@ Layout::create_gold_note()
   std::string desc = std::string("gold ") + gold::get_version_string();
 
   size_t trailing_padding;
-  Output_section *os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
+  Output_sectionos = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
                                         ".note.gnu.gold-version", desc.size(),
                                         false, &trailing_padding);
   if (os == NULL)
@@ -2314,7 +2329,7 @@ Layout::create_incremental_info_sections(Symbol_table* symtab)
   incr->create_data_sections(symtab);
 
   // Add the .gnu_incremental_inputs section.
-  const char *incremental_inputs_name =
+  const charincremental_inputs_name =
     this->namepool_.add(".gnu_incremental_inputs", false, NULL);
   Output_section* incremental_inputs_os =
     this->make_output_section(incremental_inputs_name,
@@ -2323,7 +2338,7 @@ Layout::create_incremental_info_sections(Symbol_table* symtab)
   incremental_inputs_os->add_output_section_data(incr->inputs_section());
 
   // Add the .gnu_incremental_symtab section.
-  const char *incremental_symtab_name =
+  const charincremental_symtab_name =
     this->namepool_.add(".gnu_incremental_symtab", false, NULL);
   Output_section* incremental_symtab_os =
     this->make_output_section(incremental_symtab_name,
@@ -2333,7 +2348,7 @@ Layout::create_incremental_info_sections(Symbol_table* symtab)
   incremental_symtab_os->set_entsize(4);
 
   // Add the .gnu_incremental_relocs section.
-  const char *incremental_relocs_name =
+  const charincremental_relocs_name =
     this->namepool_.add(".gnu_incremental_relocs", false, NULL);
   Output_section* incremental_relocs_os =
     this->make_output_section(incremental_relocs_name,
@@ -2342,8 +2357,17 @@ Layout::create_incremental_info_sections(Symbol_table* symtab)
   incremental_relocs_os->add_output_section_data(incr->relocs_section());
   incremental_relocs_os->set_entsize(incr->relocs_entsize());
 
+  // Add the .gnu_incremental_got_plt section.
+  const char* incremental_got_plt_name =
+    this->namepool_.add(".gnu_incremental_got_plt", false, NULL);
+  Output_section* incremental_got_plt_os =
+    this->make_output_section(incremental_got_plt_name,
+                             elfcpp::SHT_GNU_INCREMENTAL_GOT_PLT, 0,
+                             ORDER_INVALID, false);
+  incremental_got_plt_os->add_output_section_data(incr->got_plt_section());
+
   // Add the .gnu_incremental_strtab section.
-  const char *incremental_strtab_name =
+  const charincremental_strtab_name =
     this->namepool_.add(".gnu_incremental_strtab", false, NULL);
   Output_section* incremental_strtab_os = this->make_output_section(incremental_strtab_name,
                                                         elfcpp::SHT_STRTAB, 0,
@@ -2355,10 +2379,12 @@ Layout::create_incremental_info_sections(Symbol_table* symtab)
   incremental_inputs_os->set_after_input_sections();
   incremental_symtab_os->set_after_input_sections();
   incremental_relocs_os->set_after_input_sections();
+  incremental_got_plt_os->set_after_input_sections();
 
   incremental_inputs_os->set_link_section(incremental_strtab_os);
   incremental_symtab_os->set_link_section(incremental_inputs_os);
   incremental_relocs_os->set_link_section(incremental_inputs_os);
+  incremental_got_plt_os->set_link_section(incremental_inputs_os);
 }
 
 // Return whether SEG1 should be before SEG2 in the output file.  This
@@ -2446,8 +2472,13 @@ Layout::segment_precedes(const Output_segment* seg1,
       if (section_count1 > 0 && section_count2 == 0)
        return false;
 
-      uint64_t paddr1 = seg1->first_section_load_address();
-      uint64_t paddr2 = seg2->first_section_load_address();
+      uint64_t paddr1 =        (seg1->are_addresses_set()
+                        ? seg1->paddr()
+                        : seg1->first_section_load_address());
+      uint64_t paddr2 =        (seg2->are_addresses_set()
+                        ? seg2->paddr()
+                        : seg2->first_section_load_address());
+
       if (paddr1 != paddr2)
        return paddr1 < paddr2;
     }
@@ -2507,7 +2538,7 @@ align_file_offset(off_t off, uint64_t addr, uint64_t abi_pagesize)
 
 off_t
 Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
-                           unsigned int *pshndx)
+                           unsigned intpshndx)
 {
   // Sort them into the final order.
   std::sort(this->segment_list_.begin(), this->segment_list_.end(),
@@ -2546,7 +2577,6 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
   const bool check_sections = parameters->options().check_sections();
   Output_segment* last_load_segment = NULL;
 
-  bool was_readonly = false;
   for (Segment_list::iterator p = this->segment_list_.begin();
        p != this->segment_list_.end();
        ++p)
@@ -2593,21 +2623,17 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          if (!are_addresses_set)
            {
-             // If the last segment was readonly, and this one is
-             // not, then skip the address forward one page,
-             // maintaining the same position within the page.  This
-             // lets us store both segments overlapping on a single
-             // page in the file, but the loader will put them on
-             // different pages in memory.
+             // Skip the address forward one page, maintaining the same
+             // position within the page.  This lets us store both segments
+             // overlapping on a single page in the file, but the loader will
+             // put them on different pages in memory. We will revisit this
+             // decision once we know the size of the segment.
 
              addr = align_address(addr, (*p)->maximum_alignment());
              aligned_addr = addr;
 
-             if (was_readonly && ((*p)->flags() & elfcpp::PF_W) != 0)
-               {
-                 if ((addr & (abi_pagesize - 1)) != 0)
-                   addr = addr + abi_pagesize;
-               }
+             if ((addr & (abi_pagesize - 1)) != 0)
+                addr = addr + abi_pagesize;
 
              off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
            }
@@ -2665,9 +2691,6 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
          addr = new_addr;
 
-         if (((*p)->flags() & elfcpp::PF_W) == 0)
-           was_readonly = true;
-
          // Implement --check-sections.  We know that the segments
          // are sorted by LMA.
          if (check_sections && last_load_segment != NULL)
@@ -2714,7 +2737,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
 
 off_t
 Layout::set_relocatable_section_offsets(Output_data* file_header,
-                                       unsigned int *pshndx)
+                                       unsigned intpshndx)
 {
   off_t off = 0;
 
@@ -3102,7 +3125,7 @@ Layout::allocated_output_section_count() const
 void
 Layout::create_dynamic_symtab(const Input_objects* input_objects,
                               Symbol_table* symtab,
-                             Output_section **pdynstr,
+                             Output_section** pdynstr,
                              unsigned int* plocal_dynamic_count,
                              std::vector<Symbol*>* pdynamic_symbols,
                              Versions* pversions)
@@ -3897,7 +3920,7 @@ Layout::output_section_name(const char* name, size_t* plen)
   if (is_compressed_debug_section(name))
     {
       size_t len = strlen(name);
-      char *uncompressed_name = new char[len];
+      charuncompressed_name = new char[len];
       uncompressed_name[0] = '.';
       gold_assert(name[0] == '.' && name[1] == 'z');
       strncpy(&uncompressed_name[1], &name[2], len - 2);
This page took 0.026175 seconds and 4 git commands to generate.