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: Obey linker script when sorting sections


This patch changes gold to obey the linker script when sorting sections
if the linker script specifies how the sections should be sorted.  It's
better to obey the script, even if the script is not laying out sections
as gold would prefer.  This avoids an error which can occur with an
empty .tbss section when the linker script sorts it differently.
Committed to mainline and 2.21 branch.

Ian


2011-03-14  Ian Lance Taylor  <iant@google.com>

	* script-sections.cc (Sort_output_sections::script_compare):
	Rename from is_before, change return type.
	(Sort_output_sections::operator()): Adjust accordingly.


Index: script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.48
diff -u -p -u -r1.48 script-sections.cc
--- script-sections.cc	4 Jan 2011 21:46:06 -0000	1.48
+++ script-sections.cc	14 Mar 2011 01:35:20 -0000
@@ -3561,8 +3561,8 @@ class Sort_output_sections
   operator()(const Output_section* os1, const Output_section* os2) const;
 
  private:
-  bool
-  is_before(const Output_section* os1, const Output_section* os2) const;
+  int
+  script_compare(const Output_section* os1, const Output_section* os2) const;
 
  private:
   const Script_sections::Sections_elements* elements_;
@@ -3586,6 +3586,12 @@ Sort_output_sections::operator()(const O
   if (os1->address() != os2->address())
     return os1->address() < os2->address();
 
+  // If the linker script says which of these sections is first, go
+  // with what it says.
+  int i = this->script_compare(os1, os2);
+  if (i != 0)
+    return i < 0;
+
   // Sort PROGBITS before NOBITS.
   bool nobits1 = os1->type() == elfcpp::SHT_NOBITS;
   bool nobits2 = os2->type() == elfcpp::SHT_NOBITS;
@@ -3604,38 +3610,46 @@ Sort_output_sections::operator()(const O
     return true;
   if (!os1->is_noload() && os2->is_noload())
     return true;
-  
-  // The sections have the same address. Check the section positions 
-  // in accordance with the linker script.
-  return this->is_before(os1, os2);
-}
 
-// Return true if OS1 comes before OS2 in ELEMENTS_.  This ensures
-// that we keep empty sections in the order in which they appear in a
-// linker script.
+  // The sections seem practically identical.  Sort by name to get a
+  // stable sort.
+  return os1->name() < os2->name();
+}
 
-bool
-Sort_output_sections::is_before(const Output_section* os1,
-				const Output_section* os2) const
+// Return -1 if OS1 comes before OS2 in ELEMENTS_, 1 if comes after, 0
+// if either OS1 or OS2 is not mentioned.  This ensures that we keep
+// empty sections in the order in which they appear in a linker
+// script.
+
+int
+Sort_output_sections::script_compare(const Output_section* os1,
+				     const Output_section* os2) const
 {
   if (this->elements_ == NULL)
-    return false;
+    return 0;
 
+  bool found_os1 = false;
+  bool found_os2 = false;
   for (Script_sections::Sections_elements::const_iterator
 	 p = this->elements_->begin();
        p != this->elements_->end();
        ++p)
     {
-      if (os1 == (*p)->get_output_section())
+      if (os2 == (*p)->get_output_section())
+	{
+	  if (found_os1)
+	    return -1;
+	  found_os2 = true;
+	}
+      else if (os1 == (*p)->get_output_section())
 	{
-	  for (++p; p != this->elements_->end(); ++p)
-	    if (os2 == (*p)->get_output_section())
-	      return true;
-	  break;
+	  if (found_os2)
+	    return 1;
+	  found_os1 = true;
 	}
     }
 
-  return false;
+  return 0;
 }
 
 // Return whether OS is a BSS section.  This is a SHT_NOBITS section.

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