OSDN Git Service

PR 10156
authorIan Lance Taylor <ian@airs.com>
Wed, 24 Jun 2009 19:48:51 +0000 (19:48 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 24 Jun 2009 19:48:51 +0000 (19:48 +0000)
* layout.cc (Layout::choose_output_section): If we find an
existing section, update the flags.
(Layout::create_notes): New function, broken out of
Layout::finalize.
(Layout::finalize): Don't create note sections.
(Layout::create_note): Don't crash if linker script discards
section.
(Layout::create_gold_note): Likewise.
(Layout::create_build_id): Likewise.  Don't set
after_input_sections on the section.
(Layout::create_executable_stack_info): Remove target parameter.
Change caller.
* layout.h (class Layout): Declare create_notes.  Update
declaration of create_executable_stack_info.
* gold.cc (queue_middle_tasks): Call create_notes.
* output.cc (Output_section::update_flags_for_input_section): Move
here from output.h.  If SHF_ALLOC flag is newly set, mark address
invalid.
* output.h (Output_data::mark_address_invalid): New function.
(class Output_section): Only declare, not define,
update_flags_for_input_section.  Remove set_flags.

gold/ChangeLog
gold/gold.cc
gold/layout.cc
gold/layout.h
gold/output.cc
gold/output.h

index 85326d1..efa806f 100644 (file)
@@ -1,5 +1,30 @@
 2009-06-24  Ian Lance Taylor  <iant@google.com>
 
+       PR 10156
+       * layout.cc (Layout::choose_output_section): If we find an
+       existing section, update the flags.
+       (Layout::create_notes): New function, broken out of
+       Layout::finalize.
+       (Layout::finalize): Don't create note sections.
+       (Layout::create_note): Don't crash if linker script discards
+       section.
+       (Layout::create_gold_note): Likewise.
+       (Layout::create_build_id): Likewise.  Don't set
+       after_input_sections on the section.
+       (Layout::create_executable_stack_info): Remove target parameter.
+       Change caller.
+       * layout.h (class Layout): Declare create_notes.  Update
+       declaration of create_executable_stack_info.
+       * gold.cc (queue_middle_tasks): Call create_notes.
+       * output.cc (Output_section::update_flags_for_input_section): Move
+       here from output.h.  If SHF_ALLOC flag is newly set, mark address
+       invalid.
+       * output.h (Output_data::mark_address_invalid): New function.
+       (class Output_section): Only declare, not define,
+       update_flags_for_input_section.  Remove set_flags.
+
+2009-06-24  Ian Lance Taylor  <iant@google.com>
+
        * script-sections.cc (Output_section_definition::
        set_section_addresses): Rename shadowing local load_address to
        laddr.
index ae4b8b8..c65ba29 100644 (file)
@@ -386,6 +386,9 @@ queue_middle_tasks(const General_options& options,
   // TODO: if this is too slow, do this as a task, rather than inline.
   symtab->detect_odr_violations(task, options.output_file_name());
 
+  // Create any automatic note sections.
+  layout->create_notes();
+
   // Create any output sections required by any linker script.
   layout->create_script_sections();
 
index 4014ec0..e8625d2 100644 (file)
@@ -416,7 +416,10 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
       if (output_section_slot != NULL)
        {
          if (*output_section_slot != NULL)
-           return *output_section_slot;
+           {
+             (*output_section_slot)->update_flags_for_input_section(flags);
+             return *output_section_slot;
+           }
 
          // We don't put sections found in the linker script into
          // SECTION_NAME_MAP_.  That keeps us from getting confused
@@ -1028,6 +1031,16 @@ Layout::layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags)
     }
 }
 
+// Create automatic note sections.
+
+void
+Layout::create_notes()
+{
+  this->create_gold_note();
+  this->create_executable_stack_info();
+  this->create_build_id();
+}
+
 // Create the dynamic sections which are needed before we read the
 // relocs.
 
@@ -1198,9 +1211,6 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
 
   this->count_local_symbols(task, input_objects);
 
-  this->create_gold_note();
-  this->create_executable_stack_info(target);
-  this->create_build_id();
   this->link_stabs_sections();
 
   Output_segment* phdr_seg = NULL;
@@ -1442,6 +1452,9 @@ Layout::create_note(const char* name, int note_type,
   Output_section* os = this->choose_output_section(NULL, section_name,
                                                   elfcpp::SHT_NOTE,
                                                   flags, false);
+  if (os == NULL)
+    return NULL;
+
   Output_section_data* posd = new Output_data_const_buffer(buffer, notehdrsz,
                                                           size / 8,
                                                           "** note header");
@@ -1467,6 +1480,8 @@ Layout::create_gold_note()
   Output_section *os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
                                         ".note.gnu.gold-version", desc.size(),
                                         false, &trailing_padding);
+  if (os == NULL)
+    return;
 
   Output_section_data* posd = new Output_data_const(desc, 4);
   os->add_output_section_data(posd);
@@ -1491,7 +1506,7 @@ Layout::create_gold_note()
 // library, we create a PT_GNU_STACK segment.
 
 void
-Layout::create_executable_stack_info(const Target* target)
+Layout::create_executable_stack_info()
 {
   bool is_stack_executable;
   if (parameters->options().is_execstack_set())
@@ -1503,7 +1518,8 @@ Layout::create_executable_stack_info(const Target* target)
       if (this->input_requires_executable_stack_)
        is_stack_executable = true;
       else if (this->input_without_gnu_stack_note_)
-       is_stack_executable = target->is_default_stack_executable();
+       is_stack_executable =
+         parameters->target().is_default_stack_executable();
       else
        is_stack_executable = false;
     }
@@ -1600,6 +1616,8 @@ Layout::create_build_id()
   Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_BUILD_ID,
                                         ".note.gnu.build-id", descsz, true,
                                         &trailing_padding);
+  if (os == NULL)
+    return;
 
   if (!desc.empty())
     {
@@ -1622,7 +1640,6 @@ Layout::create_build_id()
       gold_assert(trailing_padding == 0);
       this->build_id_note_ = new Output_data_zero_fill(descsz, 4);
       os->add_output_section_data(this->build_id_note_);
-      os->set_after_input_sections();
     }
 }
 
index f538b64..86234a1 100644 (file)
@@ -208,6 +208,10 @@ class Layout
   void
   define_section_symbols(Symbol_table*);
 
+  // Create automatic note sections.
+  void
+  create_notes();
+
   // Create sections for linker scripts.
   void
   create_script_sections()
@@ -474,7 +478,7 @@ class Layout
 
   // Record whether the stack must be executable.
   void
-  create_executable_stack_info(const Target*);
+  create_executable_stack_info();
 
   // Create a build ID note if needed.
   void
index 911a49a..64fcb37 100644 (file)
@@ -1995,6 +1995,24 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
   return true;
 }
 
+// Update the output section flags based on input section flags.
+
+void
+Output_section::update_flags_for_input_section(elfcpp::Elf_Xword flags)
+{
+  // If we created the section with SHF_ALLOC clear, we set the
+  // address.  If we are now setting the SHF_ALLOC flag, we need to
+  // undo that.
+  if ((this->flags_ & elfcpp::SHF_ALLOC) == 0
+      && (flags & elfcpp::SHF_ALLOC) != 0)
+    this->mark_address_invalid();
+
+  this->flags_ |= (flags
+                  & (elfcpp::SHF_WRITE
+                     | elfcpp::SHF_ALLOC
+                     | elfcpp::SHF_EXECINSTR));
+}
+
 // Given an address OFFSET relative to the start of input section
 // SHNDX in OBJECT, return whether this address is being included in
 // the final link.  This should only be called if SHNDX in OBJECT has
index 3e46ad8..f9cbfa6 100644 (file)
@@ -330,6 +330,13 @@ class Output_data
 
   // Functions that child classes may call.
 
+  // Reset the address.  The Output_section class needs this when an
+  // SHF_ALLOC input section is added to an output section which was
+  // formerly not SHF_ALLOC.
+  void
+  mark_address_invalid()
+  { this->is_address_valid_ = false; }
+
   // Set the size of the data.
   void
   set_data_size(off_t data_size)
@@ -1948,22 +1955,9 @@ class Output_section : public Output_data
   flags() const
   { return this->flags_; }
 
-  // Set the section flags.  This may only be used with the Layout
-  // code when it is prepared to move the section to a different
-  // segment.
-  void
-  set_flags(elfcpp::Elf_Xword flags)
-  { this->flags_ = flags; }
-
   // Update the output section flags based on input section flags.
   void
-  update_flags_for_input_section(elfcpp::Elf_Xword flags)
-  {
-    this->flags_ |= (flags
-                    & (elfcpp::SHF_WRITE
-                       | elfcpp::SHF_ALLOC
-                       | elfcpp::SHF_EXECINSTR));
-  }
+  update_flags_for_input_section(elfcpp::Elf_Xword flags);
 
   // Return the entsize field.
   uint64_t