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] ld: Add fold_segment_align/fold_segment_relro_end/fold_segment_end


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

commit d7475e036f69ff7ac78252db74a65fe4d617c4ee
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Nov 12 17:20:09 2017 -0800

    ld: Add fold_segment_align/fold_segment_relro_end/fold_segment_end
    
    Extract DATA_SEGMENT_END/DATA_SEGMENT_ALIGN/DATA_SEGMENT_RELRO_END cases
    for GNU_RELRO segment into separate functions so that they can also be
    used for text-only LOAD segment.
    
    	* ldexp.c (fold_unary): Extract the DATA_SEGMENT_END case to ...
    	(fold_segment_end): New function.
    	(fold_binary): Extract the DATA_SEGMENT_ALIGN case to ...
    	(fold_segment_align): New function.
    	(fold_binary): Extract the DATA_SEGMENT_RELRO_END case to ...
    	(fold_segment_relro_end): New function.

Diff:
---
 ld/ChangeLog |   9 +++
 ld/ldexp.c   | 194 ++++++++++++++++++++++++++++++++---------------------------
 2 files changed, 114 insertions(+), 89 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0a39d74..bee75c1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,14 @@
 2017-11-12  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* ldexp.c (fold_unary): Extract the DATA_SEGMENT_END case to ...
+	(fold_segment_end): New function.
+	(fold_binary): Extract the DATA_SEGMENT_ALIGN case to ...
+	(fold_segment_align): New function.
+	(fold_binary): Extract the DATA_SEGMENT_RELRO_END case to ...
+	(fold_segment_relro_end): New function.
+
+2017-11-12  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* ldexp.h (phase_enum): Rename exp_dataseg_none,
 	exp_dataseg_align_seen, exp_dataseg_relro_seen,
 	exp_dataseg_end_seen, exp_dataseg_relro_adjust,
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 5633e50..83d9f8f 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -343,6 +343,30 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h)
 }
 
 static void
+fold_segment_end (seg_align_type *seg)
+{
+  if (expld.phase == lang_first_phase_enum
+      || expld.section != bfd_abs_section_ptr)
+    {
+      expld.result.valid_p = FALSE;
+    }
+  else if (seg->phase == exp_seg_align_seen
+	   || seg->phase == exp_seg_relro_seen)
+    {
+      seg->phase = exp_seg_end_seen;
+      seg->end = expld.result.value;
+    }
+  else if (seg->phase == exp_seg_done
+	   || seg->phase == exp_seg_adjust
+	   || seg->phase == exp_seg_relro_adjust)
+    {
+      /* OK.  */
+    }
+  else
+    expld.result.valid_p = FALSE;
+}
+
+static void
 fold_unary (etree_type *tree)
 {
   exp_fold_tree_1 (tree->unary.child);
@@ -389,25 +413,7 @@ fold_unary (etree_type *tree)
 	  break;
 
 	case DATA_SEGMENT_END:
-	  if (expld.phase == lang_first_phase_enum
-	      || expld.section != bfd_abs_section_ptr)
-	    {
-	      expld.result.valid_p = FALSE;
-	    }
-	  else if (expld.dataseg.phase == exp_seg_align_seen
-		   || expld.dataseg.phase == exp_seg_relro_seen)
-	    {
-	      expld.dataseg.phase = exp_seg_end_seen;
-	      expld.dataseg.end = expld.result.value;
-	    }
-	  else if (expld.dataseg.phase == exp_seg_done
-		   || expld.dataseg.phase == exp_seg_adjust
-		   || expld.dataseg.phase == exp_seg_relro_adjust)
-	    {
-	      /* OK.  */
-	    }
-	  else
-	    expld.result.valid_p = FALSE;
+	  fold_segment_end (&expld.dataseg);
 	  break;
 
 	default:
@@ -444,6 +450,84 @@ arith_result_section (const etree_value_type *lhs)
 }
 
 static void
+fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
+{
+  seg->relro = exp_seg_relro_start;
+  if (expld.phase == lang_first_phase_enum
+      || expld.section != bfd_abs_section_ptr)
+    expld.result.valid_p = FALSE;
+  else
+    {
+      bfd_vma maxpage = lhs->value;
+      bfd_vma commonpage = expld.result.value;
+
+      expld.result.value = align_n (expld.dot, maxpage);
+      if (seg->phase == exp_seg_relro_adjust)
+	expld.result.value = seg->base;
+      else if (seg->phase == exp_seg_adjust)
+	{
+	  if (commonpage < maxpage)
+	    expld.result.value += ((expld.dot + commonpage - 1)
+				   & (maxpage - commonpage));
+	}
+      else
+	{
+	  expld.result.value += expld.dot & (maxpage - 1);
+	  if (seg->phase == exp_seg_done)
+	    {
+	      /* OK.  */
+	    }
+	  else if (seg->phase == exp_seg_none)
+	    {
+	      seg->phase = exp_seg_align_seen;
+	      seg->base = expld.result.value;
+	      seg->pagesize = commonpage;
+	      seg->maxpagesize = maxpage;
+	      seg->relro_end = 0;
+	    }
+	  else
+	    expld.result.valid_p = FALSE;
+	}
+    }
+}
+
+static void
+fold_segment_relro_end (seg_align_type *seg, etree_value_type *lhs)
+{
+  /* Operands swapped!  XXX_SEGMENT_RELRO_END(offset,exp) has offset
+     in expld.result and exp in lhs.  */
+  seg->relro = exp_seg_relro_end;
+  seg->relro_offset = expld.result.value;
+  if (expld.phase == lang_first_phase_enum
+      || expld.section != bfd_abs_section_ptr)
+    expld.result.valid_p = FALSE;
+  else if (seg->phase == exp_seg_align_seen
+	   || seg->phase == exp_seg_adjust
+	   || seg->phase == exp_seg_relro_adjust
+	   || seg->phase == exp_seg_done)
+    {
+      if (seg->phase == exp_seg_align_seen
+	  || seg->phase == exp_seg_relro_adjust)
+	seg->relro_end = lhs->value + expld.result.value;
+
+      if (seg->phase == exp_seg_relro_adjust
+	  && (seg->relro_end & (seg->pagesize - 1)))
+	{
+	  seg->relro_end += seg->pagesize - 1;
+	  seg->relro_end &= ~(seg->pagesize - 1);
+	  expld.result.value = seg->relro_end - expld.result.value;
+	}
+      else
+	expld.result.value = lhs->value;
+
+      if (seg->phase == exp_seg_align_seen)
+	seg->phase = exp_seg_relro_seen;
+    }
+  else
+    expld.result.valid_p = FALSE;
+}
+
+static void
 fold_binary (etree_type *tree)
 {
   etree_value_type lhs;
@@ -573,79 +657,11 @@ fold_binary (etree_type *tree)
 	  break;
 
 	case DATA_SEGMENT_ALIGN:
-	  expld.dataseg.relro = exp_seg_relro_start;
-	  if (expld.phase == lang_first_phase_enum
-	      || expld.section != bfd_abs_section_ptr)
-	    expld.result.valid_p = FALSE;
-	  else
-	    {
-	      bfd_vma maxpage = lhs.value;
-	      bfd_vma commonpage = expld.result.value;
-
-	      expld.result.value = align_n (expld.dot, maxpage);
-	      if (expld.dataseg.phase == exp_seg_relro_adjust)
-		expld.result.value = expld.dataseg.base;
-	      else if (expld.dataseg.phase == exp_seg_adjust)
-		{
-		  if (commonpage < maxpage)
-		    expld.result.value += ((expld.dot + commonpage - 1)
-					   & (maxpage - commonpage));
-		}
-	      else
-		{
-		  expld.result.value += expld.dot & (maxpage - 1);
-		  if (expld.dataseg.phase == exp_seg_done)
-		    {
-		      /* OK.  */
-		    }
-		  else if (expld.dataseg.phase == exp_seg_none)
-		    {
-		      expld.dataseg.phase = exp_seg_align_seen;
-		      expld.dataseg.base = expld.result.value;
-		      expld.dataseg.pagesize = commonpage;
-		      expld.dataseg.maxpagesize = maxpage;
-		      expld.dataseg.relro_end = 0;
-		    }
-		  else
-		    expld.result.valid_p = FALSE;
-		}
-	    }
+	  fold_segment_align (&expld.dataseg, &lhs);
 	  break;
 
 	case DATA_SEGMENT_RELRO_END:
-	  /* Operands swapped!  DATA_SEGMENT_RELRO_END(offset,exp)
-	     has offset in expld.result and exp in lhs.  */
-	  expld.dataseg.relro = exp_seg_relro_end;
-	  expld.dataseg.relro_offset = expld.result.value;
-	  if (expld.phase == lang_first_phase_enum
-	      || expld.section != bfd_abs_section_ptr)
-	    expld.result.valid_p = FALSE;
-	  else if (expld.dataseg.phase == exp_seg_align_seen
-		   || expld.dataseg.phase == exp_seg_adjust
-		   || expld.dataseg.phase == exp_seg_relro_adjust
-		   || expld.dataseg.phase == exp_seg_done)
-	    {
-	      if (expld.dataseg.phase == exp_seg_align_seen
-		  || expld.dataseg.phase == exp_seg_relro_adjust)
-		expld.dataseg.relro_end = lhs.value + expld.result.value;
-
-	      if (expld.dataseg.phase == exp_seg_relro_adjust
-		  && (expld.dataseg.relro_end
-		      & (expld.dataseg.pagesize - 1)))
-		{
-		  expld.dataseg.relro_end += expld.dataseg.pagesize - 1;
-		  expld.dataseg.relro_end &= ~(expld.dataseg.pagesize - 1);
-		  expld.result.value = (expld.dataseg.relro_end
-					- expld.result.value);
-		}
-	      else
-		expld.result.value = lhs.value;
-
-	      if (expld.dataseg.phase == exp_seg_align_seen)
-		expld.dataseg.phase = exp_seg_relro_seen;
-	    }
-	  else
-	    expld.result.valid_p = FALSE;
+	  fold_segment_relro_end (&expld.dataseg, &lhs);
 	  break;
 
 	default:


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