This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Fix edge cases in orphan section placement.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d81222d3863037a90e0402cf438f7e45600feea2

commit d81222d3863037a90e0402cf438f7e45600feea2
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Mon Dec 12 17:52:09 2016 -0800

    Fix edge cases in orphan section placement.
    
    There were still some cases I found where orphan section placement
    was screwy -- where the script has no output section description for
    either .data or .bss, a .bss orphan section ends up getting placed
    before the .data section. In addition, if there is an output section
    description for a data section not named .data (e.g., .rela.dyn),
    the orphan .bss gets placed before it. This patch cleans that up,
    by tracking the last allocated section even as we're adding orphans.
    
    I've also improved segment layout in the absence of a PHDRS clause.
    A zero-length NOBITS section will no longer force a new segment
    when followed by a PROGBITS section.
    
    2016-12-12  Cary Coutant  <ccoutant@gmail.com>
    
    gold/
    	* script-sections.cc (Orphan_section_placement::update_last_alloc):
    	New method.
    	(Orphan_section_placement::find_place): Place orphan .data section
    	after either RODATA or TEXT.
    	(Script_sections::place_orphan): Call update_last_alloc for allocated
    	sections.
    	(Script_sections::create_segments): Improve handling of BSS.

Diff:
---
 gold/ChangeLog          | 10 ++++++++++
 gold/script-sections.cc | 35 ++++++++++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index ef0dc13..aeec389 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,13 @@
+2016-12-12  Cary Coutant  <ccoutant@gmail.com>
+
+	* script-sections.cc (Orphan_section_placement::update_last_alloc):
+	New method.
+	(Orphan_section_placement::find_place): Place orphan .data section
+	after either RODATA or TEXT.
+	(Script_sections::place_orphan): Call update_last_alloc for allocated
+	sections.
+	(Script_sections::create_segments): Improve handling of BSS.
+
 2016-12-13  Alan Modra  <amodra@gmail.com>
 
 	PR gold/16711
diff --git a/gold/script-sections.cc b/gold/script-sections.cc
index ae81f89..d970e57 100644
--- a/gold/script-sections.cc
+++ b/gold/script-sections.cc
@@ -313,6 +313,10 @@ class Orphan_section_placement
   bool
   find_place(Output_section*, Elements_iterator** pwhere);
 
+  // Update PLACE_LAST_ALLOC.
+  void
+  update_last_alloc(Elements_iterator where);
+
   // Return the iterator being used for sections at the very end of
   // the linker script.
   Elements_iterator
@@ -519,6 +523,11 @@ Orphan_section_placement::find_place(Output_section* os,
 	case PLACE_RODATA:
 	  follow = PLACE_TEXT;
 	  break;
+	case PLACE_DATA:
+	  follow = PLACE_RODATA;
+	  if (!this->places_[PLACE_RODATA].have_location)
+	    follow = PLACE_TEXT;
+	  break;
 	case PLACE_BSS:
 	  follow = PLACE_LAST_ALLOC;
 	  break;
@@ -557,6 +566,20 @@ Orphan_section_placement::find_place(Output_section* os,
   return ret;
 }
 
+// Update PLACE_LAST_ALLOC.
+void
+Orphan_section_placement::update_last_alloc(Elements_iterator elem)
+{
+  Elements_iterator prev = elem;
+  --prev;
+  if (this->places_[PLACE_LAST_ALLOC].have_location
+      && this->places_[PLACE_LAST_ALLOC].location == prev)
+    {
+      this->places_[PLACE_LAST_ALLOC].have_location = true;
+      this->places_[PLACE_LAST_ALLOC].location = elem;
+    }
+}
+
 // Return the iterator being used for sections at the very end of the
 // linker script.
 
@@ -3617,6 +3640,9 @@ Script_sections::place_orphan(Output_section* os)
       Sections_elements::iterator last = osp->last_place();
       *where = this->sections_elements_->insert(last, orphan);
     }
+
+  if ((os->flags() & elfcpp::SHF_ALLOC) != 0)
+    osp->update_last_alloc(*where);
 }
 
 // Set the addresses of all the output sections.  Walk through all the
@@ -3926,10 +3952,10 @@ Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
   Output_segment* first_seg = NULL;
   Output_segment* current_seg = NULL;
   bool is_current_seg_readonly = true;
-  Layout::Section_list::iterator plast = sections.end();
   uint64_t last_vma = 0;
   uint64_t last_lma = 0;
   uint64_t last_size = 0;
+  bool in_bss = false;
   for (Layout::Section_list::iterator p = sections.begin();
        p != sections.end();
        ++p)
@@ -3956,7 +3982,7 @@ Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
 	  // skipping a page.
 	  need_new_segment = true;
 	}
-      else if (is_bss_section(*plast) && !is_bss_section(*p))
+      else if (in_bss && !is_bss_section(*p))
 	{
 	  // A non-BSS section can not follow a BSS section in the
 	  // same segment.
@@ -3988,6 +4014,7 @@ Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
 	  if (first_seg == NULL)
 	    first_seg = current_seg;
 	  is_current_seg_readonly = true;
+	  in_bss = false;
 	}
 
       current_seg->add_output_section_to_load(layout, *p, seg_flags);
@@ -3995,7 +4022,9 @@ Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
       if (((*p)->flags() & elfcpp::SHF_WRITE) != 0)
 	is_current_seg_readonly = false;
 
-      plast = p;
+      if (is_bss_section(*p) && size > 0)
+        in_bss = true;
+
       last_vma = vma;
       last_lma = lma;
       last_size = size;


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