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]

Re: Relative expressions and ASSERT


Committed.

	* ldexp.c (fold_binary): Set result section for arithmetic and
	logical operations to NULL when both operands are in same section.
	* ld.texinfo (Expression Section): Describe this.

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.271
diff -u -p -r1.271 ld.texinfo
--- ld/ld.texinfo	13 Jan 2011 13:34:53 -0000	1.271
+++ ld/ld.texinfo	20 Jan 2011 03:42:31 -0000
@@ -5567,8 +5567,13 @@ An operation involving only numbers resu
 @item
 The result of comparisons, @samp{&&} and @samp{||} is also a number.
 @item
-The result of other operations on relative addresses (after above
-conversions) is a relative address in the same section as the operand(s).
+The result of other binary arithmetic and logical operations on two
+relative addresses in the same section or two absolute addresess
+(after above conversions) is also a number.
+@item
+The result of other operations on relative addresses or one
+relative address and a number, is a relative address in the same
+section as the relative operand(s).
 @item
 The result of other operations on absolute addresses (after above
 conversions) is an absolute address.
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.92
diff -u -p -r1.92 ldexp.c
--- ld/ldexp.c	13 Jan 2011 13:29:55 -0000	1.92
+++ ld/ldexp.c	21 Jan 2011 13:14:09 -0000
@@ -335,36 +335,47 @@ fold_binary (etree_type *tree)
 	    {
 	      make_abs ();
 	      lhs.value += lhs.section->vma;
+	      lhs.section = bfd_abs_section_ptr;
 	    }
 
 	  /* If the rhs is just a number, keep the lhs section.  */
 	  else if (expld.result.section == NULL)
-	    expld.result.section = lhs.section;
+	    {
+	      expld.result.section = lhs.section;
+	      /* Make this NULL so that we know one of the operands
+		 was just a number, for later tests.  */
+	      lhs.section = NULL;
+	    }
 	}
+      /* At this point we know that both operands have the same
+	 section, or at least one of them is a plain number.  */
 
       switch (tree->type.node_code)
 	{
-	case '%':
-	  if (expld.result.value != 0)
-	    expld.result.value = ((bfd_signed_vma) lhs.value
-				  % (bfd_signed_vma) expld.result.value);
-	  else if (expld.phase != lang_mark_phase_enum)
-	    einfo (_("%F%S %% by zero\n"));
-	  break;
-
-	case '/':
-	  if (expld.result.value != 0)
-	    expld.result.value = ((bfd_signed_vma) lhs.value
-				  / (bfd_signed_vma) expld.result.value);
-	  else if (expld.phase != lang_mark_phase_enum)
-	    einfo (_("%F%S / by zero\n"));
-	  break;
-
+	  /* Arithmetic operators, bitwise AND, bitwise OR and XOR
+	     keep the section of one of their operands only when the
+	     other operand is a plain number.  Losing the section when
+	     operating on two symbols, ie. a result of a plain number,
+	     is required for subtraction and XOR.  It's justifiable
+	     for the other operations on the grounds that adding,
+	     multiplying etc. two section relative values does not
+	     really make sense unless they are just treated as
+	     numbers.
+	     The same argument could be made for many expressions
+	     involving one symbol and a number.  For example,
+	     "1 << x" and "100 / x" probably should not be given the
+	     section of x.  The trouble is that if we fuss about such
+	     things the rules become complex and it is onerous to
+	     document ld expression evaluation.  */
 #define BOP(x, y) \
 	case x:							\
 	  expld.result.value = lhs.value y expld.result.value;	\
+	  if (expld.result.section == lhs.section)		\
+	    expld.result.section = NULL;			\
 	  break;
 
+	  /* Comparison operators, logical AND, and logical OR always
+	     return a plain number.  */
 #define BOPN(x, y) \
 	case x:							\
 	  expld.result.value = lhs.value y expld.result.value;	\
@@ -388,6 +399,26 @@ fold_binary (etree_type *tree)
 	  BOPN (ANDAND, &&);
 	  BOPN (OROR, ||);
 
+	case '%':
+	  if (expld.result.value != 0)
+	    expld.result.value = ((bfd_signed_vma) lhs.value
+				  % (bfd_signed_vma) expld.result.value);
+	  else if (expld.phase != lang_mark_phase_enum)
+	    einfo (_("%F%S %% by zero\n"));
+	  if (expld.result.section == lhs.section)
+	    expld.result.section = NULL;
+	  break;
+
+	case '/':
+	  if (expld.result.value != 0)
+	    expld.result.value = ((bfd_signed_vma) lhs.value
+				  / (bfd_signed_vma) expld.result.value);
+	  else if (expld.phase != lang_mark_phase_enum)
+	    einfo (_("%F%S / by zero\n"));
+	  if (expld.result.section == lhs.section)
+	    expld.result.section = NULL;
+	  break;
+
 	case MAX_K:
 	  if (lhs.value > expld.result.value)
 	    expld.result.value = lhs.value;

-- 
Alan Modra
Australia Development Lab, IBM


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