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] Fold arithmetic integer expressions


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

commit 9ad39107ca6e4efcda0f48a6abf528844a2f11aa
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Oct 4 10:41:26 2016 +1030

    Fold arithmetic integer expressions
    
    Commit b751e639 regressed arm linux kernel builds, that have an
    ASSERT (((__hyp_idmap_text_end - (__hyp_idmap_text_start
           			          & ~ (((0x1 << 0xc) - 0x1))))
             <= (0x1 << 0xc)), HYP init code too big or misaligned)
    
    Due to some insanity in ld expression evaluation, the integer values
    0x1 and 0xc above are treated as absolute addresses (ie. they have an
    associated section, *ABS*, see exp_fold_tree_1 case etree_value) while
    the expression (0x1 << 0xc) has a plain number result.  The left hand
    side of the inequality happens to evaluate to a "negative" .text
    section relative value.  Comparing a section relative value against an
    absolute value works since the section relative value is first
    converted to absolute.  Comparing a section relative value against a
    number just compares the offsets, which fails since the "negative"
    offset is really a very large positive number.
    
    This patch works around the problem by folding integer expressions, so
    the assert again becomes
    ASSERT (((__hyp_idmap_text_end - (__hyp_idmap_text_start
           			          & 0xfffffffffffff000))
             <= 0x1000), HYP init code too big or misaligned)
    
    	* ldexp.c (exp_value_fold): New function.
    	(exp_unop, exp_binop, exp_trinop): Use it.

Diff:
---
 ld/ChangeLog |  5 +++++
 ld/ldexp.c   | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 3ad2a7a..8b22c50 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-04  Alan Modra  <amodra@gmail.com>
+
+	* ldexp.c (exp_value_fold): New function.
+	(exp_unop, exp_binop, exp_trinop): Use it.
+
 2016-09-30  Alan Modra  <amodra@gmail.com>
 
 	* scripttempl/v850.sc: Don't reference __ctbp, __ep, __gp when
diff --git a/ld/ldexp.c b/ld/ldexp.c
index a560643..9f88144 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1252,6 +1252,19 @@ exp_fold_tree_no_dot (etree_type *tree)
   exp_fold_tree_1 (tree);
 }
 
+static void
+exp_value_fold (etree_type *tree)
+{
+  exp_fold_tree_no_dot (tree);
+  if (expld.result.valid_p)
+    {
+      tree->type.node_code = INT;
+      tree->value.value = expld.result.value;
+      tree->value.str = NULL;
+      tree->type.node_class = etree_value;
+    }
+}
+
 etree_type *
 exp_binop (int code, etree_type *lhs, etree_type *rhs)
 {
@@ -1263,6 +1276,12 @@ exp_binop (int code, etree_type *lhs, etree_type *rhs)
   new_e->binary.lhs = lhs;
   new_e->binary.rhs = rhs;
   new_e->type.node_class = etree_binary;
+  if (lhs->type.node_class == etree_value
+      && rhs->type.node_class == etree_value
+      && code != ALIGN_K
+      && code != DATA_SEGMENT_ALIGN
+      && code != DATA_SEGMENT_RELRO_END)
+    exp_value_fold (new_e);
   return new_e;
 }
 
@@ -1278,6 +1297,10 @@ exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
   new_e->trinary.cond = cond;
   new_e->trinary.rhs = rhs;
   new_e->type.node_class = etree_trinary;
+  if (cond->type.node_class == etree_value
+      && lhs->type.node_class == etree_value
+      && rhs->type.node_class == etree_value)
+    exp_value_fold (new_e);
   return new_e;
 }
 
@@ -1291,6 +1314,12 @@ exp_unop (int code, etree_type *child)
   new_e->unary.type.lineno = child->type.lineno;
   new_e->unary.child = child;
   new_e->unary.type.node_class = etree_unary;
+  if (child->type.node_class == etree_value
+      && code != ALIGN_K
+      && code != ABSOLUTE
+      && code != NEXT
+      && code != DATA_SEGMENT_END)
+    exp_value_fold (new_e);
   return new_e;
 }


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