This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gold patch committed: Fix x86_64 Linux kernel build


I committed this patch to gold to fix the x86_64 Linux kernel build.
The main issue was handling the case of adding an SHF_ALLOC section to a
section which was originally created without SHF_ALLOC.  This can only
happen when using a linker script, and it happens with some Linux kernel
scripts that load the .note sections.  I also had to fix the case of a
linker script discarding the .note sections.  I moved the creation of
the automatic .note sections (.note.gnu.build-id, etc.) to happen before
sections are attached to segments, so that I didn't have to reattach the
section when it changed from non-ALLOC to ALLOC.

Ian


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.


Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.64
diff -p -u -r1.64 gold.cc
--- gold.cc	24 Jun 2009 05:01:16 -0000	1.64
+++ gold.cc	24 Jun 2009 19:47:07 -0000
@@ -386,6 +386,9 @@ queue_middle_tasks(const General_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: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.130
diff -p -u -r1.130 layout.cc
--- layout.cc	24 Jun 2009 05:09:11 -0000	1.130
+++ layout.cc	24 Jun 2009 19:47:07 -0000
@@ -416,7 +416,10 @@ Layout::choose_output_section(const Relo
       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_s
     }
 }
 
+// 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* in
 
   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, in
   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(con
       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: layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.66
diff -p -u -r1.66 layout.h
--- layout.h	24 Jun 2009 00:38:00 -0000	1.66
+++ layout.h	24 Jun 2009 19:47:07 -0000
@@ -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: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.91
diff -p -u -r1.91 output.cc
--- output.cc	22 Jun 2009 06:51:53 -0000	1.91
+++ output.cc	24 Jun 2009 19:47:08 -0000
@@ -1995,6 +1995,24 @@ Output_section::add_merge_input_section(
   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: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.79
diff -p -u -r1.79 output.h
--- output.h	22 Jun 2009 06:51:53 -0000	1.79
+++ output.h	24 Jun 2009 19:47:08 -0000
@@ -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_dat
   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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]