public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Relative expressions and ASSERT
@ 2010-08-10 22:20 Daniel Jacobowitz
  2010-08-11  6:31 ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-08-10 22:20 UTC (permalink / raw)
  To: binutils; +Cc: Kazu Hirata

Kazu has discovered a really perverse behavior of linker script
processing.  Consider this script:

SECTIONS
{
	.section : {
	  ASSERT ((main & 1) == 0, "In-section 0");
	  ASSERT ((main & 1) == 1, "In-section 1");
	}
	ASSERT ((main & 1) == 0, "Out-section 0")
	ASSERT ((main & 1) == 1, "Out-section 1")
}

It seems like two of those asserts must trigger on any program - but
it's not so.  In fact, neither of the In-section messages is printed
for my test (anything with 'main' will do).

Why?  Well, because both "1" and "0" are interpreted as relative to
".section".  So it becomes ASSERT ((main & (.section+1)) ==
(.section+0)).

There's a special exception that makes this work for + (and sometimes
-).  The code is in fold_binary.

IMO, it would be plausible to extend this exception to at least
bitwise operators.  But the == case has me stumped.  If "foo = 0" is
going to assign a relative value of 0 to foo, then it's odd for foo == 0
to not use a relative value of 0 too.

Thoughts?  Just Don't Do This inside an output section?

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-10 22:20 Relative expressions and ASSERT Daniel Jacobowitz
@ 2010-08-11  6:31 ` Alan Modra
  2010-08-11 23:11   ` Daniel Jacobowitz
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-08-11  6:31 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: binutils, Kazu Hirata

On Tue, Aug 10, 2010 at 05:16:54PM -0400, Daniel Jacobowitz wrote:
> Kazu has discovered a really perverse behavior of linker script

Yes, current behaviour is horrible.

> IMO, it would be plausible to extend this exception to at least

We're in a hole, let's not dig any deeper..  I think we made a mistake
in treating constants as section relative in output sections.  It
would be better to treat all constants as absolute, and make
exceptions for cases where we want a relative result, probably just
assignment to symbols in an output section.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-11  6:31 ` Alan Modra
@ 2010-08-11 23:11   ` Daniel Jacobowitz
  2010-08-12 13:48     ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-08-11 23:11 UTC (permalink / raw)
  To: binutils, Kazu Hirata

On Wed, Aug 11, 2010 at 11:53:30AM +0930, Alan Modra wrote:
> On Tue, Aug 10, 2010 at 05:16:54PM -0400, Daniel Jacobowitz wrote:
> > Kazu has discovered a really perverse behavior of linker script
> 
> Yes, current behaviour is horrible.
> 
> > IMO, it would be plausible to extend this exception to at least
> 
> We're in a hole, let's not dig any deeper..  I think we made a mistake
> in treating constants as section relative in output sections.  It
> would be better to treat all constants as absolute, and make
> exceptions for cases where we want a relative result, probably just
> assignment to symbols in an output section.

I'm fine with this - although, wondering what linker scripts it
might break.  I took a look, though, and I don't think I can implement
this without breakage everywhere.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-11 23:11   ` Daniel Jacobowitz
@ 2010-08-12 13:48     ` Alan Modra
  2010-08-12 15:47       ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-08-12 13:48 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: binutils, Kazu Hirata

This is mostly just a cleanup I made when looking at overhauling our
expression code.

	* ldexp.c (new_rel): Remove "str".  Update all call sites.
	(exp_fold_tree_1): When assigning to dot, calculate nextdot
	using expld.result.section rather than expld.section.

Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.84
diff -u -p -r1.84 ldexp.c
--- ld/ldexp.c	28 Jul 2010 06:43:32 -0000	1.84
+++ ld/ldexp.c	12 Aug 2010 12:22:34 -0000
@@ -190,11 +190,11 @@ exp_relop (asection *section, bfd_vma va
 }
 
 static void
-new_rel (bfd_vma value, char *str, asection *section)
+new_rel (bfd_vma value, asection *section)
 {
   expld.result.valid_p = TRUE;
   expld.result.value = value;
-  expld.result.str = str;
+  expld.result.str = NULL;
   expld.result.section = section;
 }
 
@@ -561,7 +561,7 @@ fold_name (etree_type *tree)
 		    }
 		  else
 		    new_rel (h->u.def.value + h->u.def.section->output_offset,
-			     NULL, output_section);
+			     output_section);
 		}
 	    }
 	  else if (expld.phase == lang_final_phase_enum
@@ -591,7 +591,7 @@ fold_name (etree_type *tree)
 		       tree->name.name);
 	    }
 	  else if (os->processed_vma)
-	    new_rel (0, NULL, os->bfd_section);
+	    new_rel (0, os->bfd_section);
 	}
       break;
 
@@ -704,7 +704,8 @@ exp_fold_tree_1 (etree_type *tree)
   switch (tree->type.node_class)
     {
     case etree_value:
-      new_rel (tree->value.value, tree->value.str, expld.section);
+      new_rel (tree->value.value, expld.section);
+      expld.result.str = tree->value.str;
       break;
 
     case etree_rel:
@@ -712,7 +713,7 @@ exp_fold_tree_1 (etree_type *tree)
 	{
 	  asection *output_section = tree->rel.section->output_section;
 	  new_rel (tree->rel.value + tree->rel.section->output_offset,
-		   NULL, output_section);
+		   output_section);
 	}
       else
 	memset (&expld.result, 0, sizeof (expld.result));
@@ -766,7 +767,7 @@ exp_fold_tree_1 (etree_type *tree)
 		{
 		  bfd_vma nextdot;
 
-		  nextdot = expld.result.value + expld.section->vma;
+		  nextdot = expld.result.value + expld.result.section->vma;
 		  if (nextdot < expld.dot
 		      && expld.section != bfd_abs_section_ptr)
 		    einfo (_("%F%S cannot move location counter backwards"

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-12 13:48     ` Alan Modra
@ 2010-08-12 15:47       ` Alan Modra
  2010-08-12 16:19         ` H.J. Lu
  2010-08-13 14:51         ` Ian Lance Taylor
  0 siblings, 2 replies; 48+ messages in thread
From: Alan Modra @ 2010-08-12 15:47 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

I started down the path to treating all constants as absolute, and
fairly rapidly found that was unworkable, as we need to distinguish
between a plain numerical value and an absolute address.  So I made
constants have a NULL section.  This allows some nice simplification
when setting up result section in fold_binary;  No special case for
'+' or '-' is needed, I think.

Most of the patch is fairly obvious, but I had to make a few hacks for
ORIGIN, to get ld-scripts/memaddr.t to pass.  ORIGIN was returning an
absolute value (correctly, it really is an address) but this was being
turned into a plain constant by exp_nameop.  exp_nameop can be made to
behave by simply saying the result is invalid during the initial pass
through script expressions.  Then it's possible to return a relative
value for ORIGIN, like the test suite expects.  I originally just
fixed the test suite but I'll leave that to a followup patch.

I don't intend to commit this patch immediately.  I'm sure it will
break some scripts, but if breakage is not too common then this chance
to improve ld sanity may be worthwhile.

	* ldexp.c (make_non_rel, new_number): New functions.
	(make_abs, exp_get_abs_int): Cope with NULL expld.result.section.
	(fold_unary <'~', '!', '-'>): make_non_rel instead of make_abs.
	(fold_binary): Simplify result section logic.  Return NULL section
	for logical ops.
	(fold_name <SIZEOF_HEADERS>): Return new_number, not new_abs.
	(fold_name <DEFINED, SIZEOF, ALIGNOF, LENGTH, CONSTANT>): Likewise.
	(fold_name <ORIGIN>): Don't return valid result when
	lang_first_phase_enum.  Return new_rel, not new_abs.
	(exp_fold_tree_1 <etree_value>): Return new_number, not new_rel.
	(exp_fold_tree_1): Ajust for NULL expld.result.section.  When assigning
	a plain number to dot, assume the value is relative to expld.section.
	Make numbers not in an output section, absolute.
	* ldlang.c (print_assignment): Fix style nit.
	(lang_size_sections_1): Cope with NULL expld.result.section.
	(lang_do_assignments_1): Likewise.

Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.85
diff -u -p -r1.85 ldexp.c
--- ld/ldexp.c	12 Aug 2010 13:36:50 -0000	1.85
+++ ld/ldexp.c	12 Aug 2010 13:45:27 -0000
@@ -138,11 +138,22 @@ exp_print_token (token_code_type code, i
 static void
 make_abs (void)
 {
-  expld.result.value += expld.result.section->vma;
+  if (expld.result.section != NULL)
+    expld.result.value += expld.result.section->vma;
   expld.result.section = bfd_abs_section_ptr;
 }
 
 static void
+make_non_rel (void)
+{
+  if (expld.result.section != NULL)
+    {
+      expld.result.value += expld.result.section->vma;
+      expld.result.section = bfd_abs_section_ptr;
+    }
+}
+
+static void
 new_abs (bfd_vma value)
 {
   expld.result.valid_p = TRUE;
@@ -190,6 +201,15 @@ exp_relop (asection *section, bfd_vma va
 }
 
 static void
+new_number (bfd_vma value)
+{
+  expld.result.valid_p = TRUE;
+  expld.result.value = value;
+  expld.result.str = NULL;
+  expld.result.section = NULL;
+}
+
+static void
 new_rel (bfd_vma value, asection *section)
 {
   expld.result.valid_p = TRUE;
@@ -227,17 +247,17 @@ fold_unary (etree_type *tree)
 	  break;
 
 	case '~':
-	  make_abs ();
+	  make_non_rel ();
 	  expld.result.value = ~expld.result.value;
 	  break;
 
 	case '!':
-	  make_abs ();
+	  make_non_rel ();
 	  expld.result.value = !expld.result.value;
 	  break;
 
 	case '-':
-	  make_abs ();
+	  make_non_rel ();
 	  expld.result.value = -expld.result.value;
 	  break;
 
@@ -319,32 +339,20 @@ fold_binary (etree_type *tree)
 
   if (expld.result.valid_p)
     {
-      /* If the values are from different sections, or this is an
-	 absolute expression, make both the source arguments
-	 absolute.  However, adding or subtracting an absolute
-	 value from a relative value is meaningful, and is an
-	 exception.  */
-      if (expld.section != bfd_abs_section_ptr
-	  && lhs.section == bfd_abs_section_ptr
-	  && tree->type.node_code == '+')
+      if (lhs.section != expld.result.section)
 	{
-	  /* Keep the section of the rhs term.  */
-	  expld.result.value = lhs.value + expld.result.value;
-	  return;
-	}
-      else if (expld.section != bfd_abs_section_ptr
-	       && expld.result.section == bfd_abs_section_ptr
-	       && (tree->type.node_code == '+'
-		   || tree->type.node_code == '-'))
-	{
-	  /* Keep the section of the lhs term.  */
-	  expld.result.section = lhs.section;
-	}
-      else if (expld.result.section != lhs.section
-	       || expld.section == bfd_abs_section_ptr)
-	{
-	  make_abs ();
-	  lhs.value += lhs.section->vma;
+	  /* If the values are from different sections, and neither is
+	     just a number, make both the source arguments absolute.  */
+	  if (expld.result.section != NULL
+	      && lhs.section != NULL)
+	    {
+	      make_abs ();
+	      lhs.value += lhs.section->vma;
+	    }
+
+	  /* If the rhs is just a number, keep the lhs section.  */
+	  else if (expld.result.section == NULL)
+	    expld.result.section = lhs.section;
 	}
 
       switch (tree->type.node_code)
@@ -366,26 +374,32 @@ fold_binary (etree_type *tree)
 	  break;
 
 #define BOP(x, y) \
-	    case x:							\
-	      expld.result.value = lhs.value y expld.result.value;	\
-	      break;
+	case x:							\
+	  expld.result.value = lhs.value y expld.result.value;	\
+	  break;
+
+#define BOPN(x, y) \
+	case x:							\
+	  expld.result.value = lhs.value y expld.result.value;	\
+	  expld.result.section = NULL;				\
+	  break;
 
 	  BOP ('+', +);
 	  BOP ('*', *);
 	  BOP ('-', -);
 	  BOP (LSHIFT, <<);
 	  BOP (RSHIFT, >>);
-	  BOP (EQ, ==);
-	  BOP (NE, !=);
-	  BOP ('<', <);
-	  BOP ('>', >);
-	  BOP (LE, <=);
-	  BOP (GE, >=);
+	  BOPN (EQ, ==);
+	  BOPN (NE, !=);
+	  BOPN ('<', <);
+	  BOPN ('>', >);
+	  BOPN (LE, <=);
+	  BOPN (GE, >=);
 	  BOP ('&', &);
 	  BOP ('^', ^);
 	  BOP ('|', |);
-	  BOP (ANDAND, &&);
-	  BOP (OROR, ||);
+	  BOPN (ANDAND, &&);
+	  BOPN (OROR, ||);
 
 	case MAX_K:
 	  if (lhs.value > expld.result.value)
@@ -499,7 +513,7 @@ fold_name (etree_type *tree)
 	     The bfd function may cache incorrect data.  */
 	  if (expld.phase != lang_mark_phase_enum)
 	    hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
-	  new_abs (hdr_size);
+	  new_number (hdr_size);
 	}
       break;
 
@@ -516,14 +530,12 @@ fold_name (etree_type *tree)
 					    &link_info,
 					    tree->name.name,
 					    FALSE, FALSE, TRUE);
-	  expld.result.value = (h != NULL
-				&& (h->type == bfd_link_hash_defined
-				    || h->type == bfd_link_hash_defweak
-				    || h->type == bfd_link_hash_common)
-				&& (def_iteration == lang_statement_iteration
-				    || def_iteration == -1));
-	  expld.result.section = expld.section;
-	  expld.result.valid_p = TRUE;
+	  new_number (h != NULL
+		      && (h->type == bfd_link_hash_defined
+			  || h->type == bfd_link_hash_defweak
+			  || h->type == bfd_link_hash_common)
+		      && (def_iteration == lang_statement_iteration
+			  || def_iteration == -1));
 	}
       break;
 
@@ -633,7 +645,7 @@ fold_name (etree_type *tree)
 	      if (expld.phase == lang_final_phase_enum)
 		einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
 		       tree->name.name);
-	      new_abs (0);
+	      new_number (0);
 	    }
 	  else if (os->processed_vma)
 	    {
@@ -645,7 +657,7 @@ fold_name (etree_type *tree)
 	      else
 		val = (bfd_vma)1 << os->bfd_section->alignment_power;
 	      
-	      new_abs (val);
+	      new_number (val);
 	    }
 	}
       break;
@@ -656,7 +668,7 @@ fold_name (etree_type *tree)
         
         mem = lang_memory_region_lookup (tree->name.name, FALSE);  
         if (mem != NULL) 
-          new_abs (mem->length);
+          new_number (mem->length);
         else          
           einfo (_("%F%S: undefined MEMORY region `%s'"
 		   " referenced in expression\n"), tree->name.name);
@@ -664,23 +676,24 @@ fold_name (etree_type *tree)
       break;
 
     case ORIGIN:
-      {
-        lang_memory_region_type *mem;
+      if (expld.phase != lang_first_phase_enum)
+	{
+	  lang_memory_region_type *mem;
         
-        mem = lang_memory_region_lookup (tree->name.name, FALSE);  
-        if (mem != NULL) 
-          new_abs (mem->origin);
-        else          
-          einfo (_("%F%S: undefined MEMORY region `%s'"
-		   " referenced in expression\n"), tree->name.name);
-      }
+	  mem = lang_memory_region_lookup (tree->name.name, FALSE);  
+	  if (mem != NULL) 
+	    new_rel (mem->origin, expld.section);
+	  else          
+	    einfo (_("%F%S: undefined MEMORY region `%s'"
+		     " referenced in expression\n"), tree->name.name);
+	}
       break;
 
     case CONSTANT:
       if (strcmp (tree->name.name, "MAXPAGESIZE") == 0)
-	new_abs (config.maxpagesize);
+	new_number (config.maxpagesize);
       else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0)
-	new_abs (config.commonpagesize);
+	new_number (config.commonpagesize);
       else
 	einfo (_("%F%S: unknown constant `%s' referenced in expression\n"),
 	       tree->name.name);
@@ -704,7 +717,7 @@ exp_fold_tree_1 (etree_type *tree)
   switch (tree->type.node_class)
     {
     case etree_value:
-      new_rel (tree->value.value, expld.section);
+      new_number (tree->value.value);
       expld.result.str = tree->value.str;
       break;
 
@@ -767,7 +780,11 @@ exp_fold_tree_1 (etree_type *tree)
 		{
 		  bfd_vma nextdot;
 
-		  nextdot = expld.result.value + expld.result.section->vma;
+		  nextdot = expld.result.value;
+		  if (expld.result.section != NULL)
+		    nextdot += expld.result.section->vma;
+		  else
+		    nextdot += expld.section->vma;
 		  if (nextdot < expld.dot
 		      && expld.section != bfd_abs_section_ptr)
 		    einfo (_("%F%S cannot move location counter backwards"
@@ -818,6 +835,8 @@ exp_fold_tree_1 (etree_type *tree)
 	      lang_update_definedness (tree->assign.dst, h);
 	      h->type = bfd_link_hash_defined;
 	      h->u.def.value = expld.result.value;
+	      if (expld.result.section == NULL)
+		expld.result.section = expld.section;
 	      h->u.def.section = expld.result.section;
 	      if (tree->type.node_class == etree_provide)
 		tree->type.node_class = etree_provided;
@@ -856,6 +875,13 @@ exp_fold_tree_1 (etree_type *tree)
       memset (&expld.result, 0, sizeof (expld.result));
       break;
     }
+
+  /* Any number not inside an output section statement is an
+     absolute value.  */
+  if (expld.result.valid_p
+      && expld.result.section == NULL
+      && expld.section == bfd_abs_section_ptr)
+    expld.result.section = bfd_abs_section_ptr;
 }
 
 void
@@ -1186,7 +1212,8 @@ exp_get_abs_int (etree_type *tree, int d
 
       if (expld.result.valid_p)
 	{
-	  expld.result.value += expld.result.section->vma;
+	  if (expld.result.section != NULL)
+	    expld.result.value += expld.result.section->vma;
 	  return expld.result.value;
 	}
       else if (name != NULL && expld.phase != lang_mark_phase_enum)
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.337
diff -u -p -r1.337 ldlang.c
--- ld/ldlang.c	6 Aug 2010 01:51:17 -0000	1.337
+++ ld/ldlang.c	12 Aug 2010 13:45:30 -0000
@@ -3916,7 +3916,7 @@ print_assignment (lang_assignment_statem
 	{
 	  value = expld.result.value;
 
-	  if (expld.result.section)
+	  if (expld.result.section != NULL)
 	    value += expld.result.section->vma;
 
 	  minfo ("0x%V", value);
@@ -3933,7 +3933,7 @@ print_assignment (lang_assignment_statem
 	    {
 	      value = h->u.def.value;
 
-	      if (expld.result.section)
+	      if (expld.result.section != NULL)
 		value += expld.result.section->vma;
 
 	      minfo ("[0x%V]", value);
@@ -4718,7 +4718,11 @@ lang_size_sections_1
 		exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
 
 		if (expld.result.valid_p)
-		  dot = expld.result.value + expld.result.section->vma;
+		  {
+		    dot = expld.result.value;
+		    if (expld.result.section != NULL)
+		      dot += expld.result.section->vma;
+		  }
 		else if (expld.phase != lang_mark_phase_enum)
 		  einfo (_("%F%S: non constant or forward reference"
 			   " address expression for section %s\n"),
@@ -5397,8 +5401,11 @@ lang_do_assignments_1 (lang_statement_un
 	case lang_data_statement_enum:
 	  exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
 	  if (expld.result.valid_p)
-	    s->data_statement.value = (expld.result.value
-				       + expld.result.section->vma);
+	    {
+	      s->data_statement.value = expld.result.value;
+	      if (expld.result.section != NULL)
+		s->data_statement.value += expld.result.section->vma;
+	    }
 	  else
 	    einfo (_("%F%P: invalid data statement\n"));
 	  {

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-12 15:47       ` Alan Modra
@ 2010-08-12 16:19         ` H.J. Lu
  2010-08-13  0:05           ` Alan Modra
  2010-08-13 14:51         ` Ian Lance Taylor
  1 sibling, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-08-12 16:19 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Aug 12, 2010 at 8:07 AM, Alan Modra <amodra@gmail.com> wrote:
> I started down the path to treating all constants as absolute, and
> fairly rapidly found that was unworkable, as we need to distinguish
> between a plain numerical value and an absolute address.  So I made
> constants have a NULL section.  This allows some nice simplification
> when setting up result section in fold_binary;  No special case for
> '+' or '-' is needed, I think.
>
> Most of the patch is fairly obvious, but I had to make a few hacks for
> ORIGIN, to get ld-scripts/memaddr.t to pass.  ORIGIN was returning an
> absolute value (correctly, it really is an address) but this was being
> turned into a plain constant by exp_nameop.  exp_nameop can be made to
> behave by simply saying the result is invalid during the initial pass
> through script expressions.  Then it's possible to return a relative
> value for ORIGIN, like the test suite expects.  I originally just
> fixed the test suite but I'll leave that to a followup patch.
>
> I don't intend to commit this patch immediately.  I'm sure it will
> break some scripts, but if breakage is not too common then this chance
> to improve ld sanity may be worthwhile.
>
>        * ldexp.c (make_non_rel, new_number): New functions.
>        (make_abs, exp_get_abs_int): Cope with NULL expld.result.section.
>        (fold_unary <'~', '!', '-'>): make_non_rel instead of make_abs.
>        (fold_binary): Simplify result section logic.  Return NULL section
>        for logical ops.
>        (fold_name <SIZEOF_HEADERS>): Return new_number, not new_abs.
>        (fold_name <DEFINED, SIZEOF, ALIGNOF, LENGTH, CONSTANT>): Likewise.
>        (fold_name <ORIGIN>): Don't return valid result when
>        lang_first_phase_enum.  Return new_rel, not new_abs.
>        (exp_fold_tree_1 <etree_value>): Return new_number, not new_rel.
>        (exp_fold_tree_1): Ajust for NULL expld.result.section.  When assigning
>        a plain number to dot, assume the value is relative to expld.section.
>        Make numbers not in an output section, absolute.
>        * ldlang.c (print_assignment): Fix style nit.
>        (lang_size_sections_1): Cope with NULL expld.result.section.
>        (lang_do_assignments_1): Likewise.
>

You can try the new linker on Linux kernel.

-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-12 16:19         ` H.J. Lu
@ 2010-08-13  0:05           ` Alan Modra
  2010-12-16  8:01             ` H.J. Lu
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-08-13  0:05 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
> You can try the new linker on Linux kernel.

An x86 2.6.35 kernel built without any differences.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-12 15:47       ` Alan Modra
  2010-08-12 16:19         ` H.J. Lu
@ 2010-08-13 14:51         ` Ian Lance Taylor
  2010-08-16 15:49           ` Alan Modra
  1 sibling, 1 reply; 48+ messages in thread
From: Ian Lance Taylor @ 2010-08-13 14:51 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: binutils, Kazu Hirata

Alan Modra <amodra@gmail.com> writes:

> I started down the path to treating all constants as absolute, and
> fairly rapidly found that was unworkable, as we need to distinguish
> between a plain numerical value and an absolute address.  So I made
> constants have a NULL section.  This allows some nice simplification
> when setting up result section in fold_binary;  No special case for
> '+' or '-' is needed, I think.
>
> Most of the patch is fairly obvious, but I had to make a few hacks for
> ORIGIN, to get ld-scripts/memaddr.t to pass.  ORIGIN was returning an
> absolute value (correctly, it really is an address) but this was being
> turned into a plain constant by exp_nameop.  exp_nameop can be made to
> behave by simply saying the result is invalid during the initial pass
> through script expressions.  Then it's possible to return a relative
> value for ORIGIN, like the test suite expects.  I originally just
> fixed the test suite but I'll leave that to a followup patch.
>
> I don't intend to commit this patch immediately.  I'm sure it will
> break some scripts, but if breakage is not too common then this chance
> to improve ld sanity may be worthwhile.

gold currently treats all constants used in expressions as absolute.  Of
course it's quite possible that this breaks some scripts.  gold
represents an evaluated expression as a number, a pointer to an output
section, and an alignment (used for the builtin ALIGN function).

For the '+' operator, if only one of the values has a section that
section is retained.  If both values have a section, gold warns on a
relocatable link, and otherwise just does the operation.

Ian

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-13 14:51         ` Ian Lance Taylor
@ 2010-08-16 15:49           ` Alan Modra
  2010-08-19 12:44             ` Alan Modra
  2010-10-01  8:20             ` PR12066 Alan Modra
  0 siblings, 2 replies; 48+ messages in thread
From: Alan Modra @ 2010-08-16 15:49 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

I think this is about the best that can be done for ld script
expressions, if the aim is consistency of evaluation but we value
compatibility with previous versions of ld.  Compatibility dictates we
must have two modes of evaluation.  Expressions inside output sections
definitions are generally relative, while other expressions are always
absolute.  See the ld.texinfo patch below for some details.

Comments?

binutils/
	* NEWS: Mention change in linker script expression evaluation.
ld/
	* ld.texinfo (Expression Section): Detail expression evaluation.
	(Builtin Functions <ADDR>): Correct.
	(Builtin Functions <LOADADDR>): Don't mention LOADADDR normally
	the same as ADDR.
	(Builtin Functions <SEGMENT_START>): Typo fix.
	* ldexp.c (new_number): New function.
	(make_abs, exp_get_abs_int): Cope with NULL expld.result.section.
	(fold_unary <'~', '!', '-'>): Don't make_abs.
	(fold_binary): Simplify result section logic.  Return NULL section
	for logical ops.
	(fold_binary <SEGMENT_START>): Use new_rel_from_abs to set value to
	a consistent result.
	(fold_name <SIZEOF_HEADERS>): Return new_number, not new_abs.
	(fold_name <DEFINED, SIZEOF, ALIGNOF, LENGTH, CONSTANT>): Likewise.
	(fold_name <NAME>): No need to handle absolute symbols differently
	from relative ones.
	(fold_name <ORIGIN>): Don't return valid result when
	lang_first_phase_enum.  Return new_rel_from_abs, not new_abs.
	(exp_fold_tree_1 <etree_value>): Return new_number, not new_rel.
	(exp_fold_tree_1): Ajust for NULL expld.result.section.  When assigning
	a plain number to dot, assume the value is relative to expld.section.
	Make terms not in an output section, absolute.
	* ldlang.c (print_assignment): Fix style nit.
	(lang_size_sections_1): Cope with NULL expld.result.section.
	(lang_do_assignments_1): Likewise.
ld/testsuite/
	* ld-scripts/memory.t: Remove ORIGIN fudge.

Index: binutils/NEWS
===================================================================
RCS file: /cvs/src/src/binutils/NEWS,v
retrieving revision 1.94
diff -u -p -r1.94 NEWS
--- binutils/NEWS	25 Mar 2010 21:12:27 -0000	1.94
+++ binutils/NEWS	16 Aug 2010 06:41:02 -0000
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Linker script expression evaluation is somewhat more sane.  This may
+  break scripts that depend on quirks of the old expression evaluation.
+
 * Add support for the TMS320C6000 (TI C6X) processor family.
 
 * Readelf can now display ARM unwind tables (.ARM.exidx / .ARM.extab) using
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.261
diff -u -p -r1.261 ld.texinfo
--- ld/ld.texinfo	20 Jul 2010 19:25:42 -0000	1.261
+++ ld/ld.texinfo	16 Aug 2010 14:50:23 -0000
@@ -5447,23 +5447,82 @@ address}.
 @cindex absolute and relocatable symbols
 @cindex relocatable and absolute symbols
 @cindex symbols, relocatable and absolute
-When the linker evaluates an expression, the result is either absolute
-or relative to some section.  A relative expression is expressed as a
-fixed offset from the base of a section.
-
-The position of the expression within the linker script determines
-whether it is absolute or relative.  An expression which appears within
-an output section definition is relative to the base of the output
-section.  An expression which appears elsewhere will be absolute.
-
-A symbol set to a relative expression will be relocatable if you request
-relocatable output using the @samp{-r} option.  That means that a
-further link operation may change the value of the symbol.  The symbol's
-section will be the section of the relative expression.
-
-A symbol set to an absolute expression will retain the same value
-through any further link operation.  The symbol will be absolute, and
-will not have any particular associated section.
+Addresses and symbols may be section relative, or absolute.  A section
+relative symbol is relocatable.  If you request relocatable output
+using the @samp{-r} option, a further link operation may change the
+value of a section relative symbol.  On the other hand, an absolute
+symbol will retain the same value throughout any further link
+operations.
+
+Some terms in linker expressions are addresses.  This is true of all
+symbols and for builtin functions that return an address, such as
+@code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and @code{SEGMENT_START}.
+Other terms are simply numbers, or are builtin functions that return a
+non-address value, such as @code{LENGTH}.
+
+When the linker evaluates an expression, the result depends on where
+the expression is located in a linker script.  Expressions appearing
+outside an output section definitions are evaluated with all terms
+first being converted to absolute addresses before applying operators,
+and evaluate to an absolute address result.  Expressions appearing
+inside an output section definition are evaluated with more complex
+rules, but the aim is to treat terms as relative addresses and produce
+a relative address result.  In particular, an assignment of a number
+to a symbol results in a symbol relative to the output section with an
+offset given by the number.  So, in the following simple example,
+
+@smallexample
+@group
+SECTIONS
+  @{
+    . = 0x100;
+    __executable_start = 0x100;
+    .data :
+    @{
+      . = 0x10;
+      __data_start = 0x10;
+      *(.data)
+    @}
+    @dots{}
+  @}
+@end group
+@end smallexample
+
+both @code{.} and @code{__executable_start} are set to the absolute
+address 0x100 in the first two assignments, then both @code{.} and
+@code{__data_start} are set to 0x10 relative to the @code{.data}
+section in the second two assignments.
+
+For expressions appearing inside an output section definition
+involving numbers, relative addresses and absolute addresses, ld
+follows these rules to evaluate terms:
+
+@itemize @bullet
+@item
+Unary operations on a relative address, and binary operations on two
+relative addresses in the same section or between one relative address
+and a number, apply the operator to the offset part of the address(es).
+@item
+Unary operations on an absolute address, and binary operations on one
+or more absolute addresses or on two relative addresses not in the
+same section, first convert any non-absolute term to an absolute
+address before applying the operator.
+@end itemize
+
+The result section of each sub-expression is as follows:
+
+@itemize @bullet
+@item
+An operation involving only numbers results in a number.
+@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).
+@item
+The result of other operations on absolute addresses (after above
+conversions) is an absolute address.
+@end itemize
 
 You can use the builtin function @code{ABSOLUTE} to force an expression
 to be absolute when it would otherwise be relative.  For example, to
@@ -5479,6 +5538,9 @@ SECTIONS
 If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the
 @samp{.data} section.
 
+Using @code{LOADADDR} also forces an expression absolute, since this
+particular builtin function returns an absolute address.
+
 @node Builtin Functions
 @subsection Builtin Functions
 @cindex functions in expressions
@@ -5497,10 +5559,12 @@ normally section relative.  @xref{Expres
 @item ADDR(@var{section})
 @kindex ADDR(@var{section})
 @cindex section address in expression
-Return the absolute address (the VMA) of the named @var{section}.  Your
+Return the address (VMA) of the named @var{section}.  Your
 script must previously have defined the location of that section.  In
-the following example, @code{symbol_1} and @code{symbol_2} are assigned
-identical values:
+the following example, @code{start_of_output_1}, @code{symbol_1} and
+@code{symbol_2} are assigned equivalent values, except that
+@code{symbol_1} will be relative to the @code{.output1} section while
+the other two will be absolute:
 @smallexample
 @group
 SECTIONS @{ @dots{}
@@ -5664,9 +5728,7 @@ Return the length of the memory region n
 @item LOADADDR(@var{section})
 @kindex LOADADDR(@var{section})
 @cindex section load address in expression
-Return the absolute LMA of the named @var{section}.  This is normally
-the same as @code{ADDR}, but it may be different if the @code{AT}
-attribute is used in the output section definition (@pxref{Output
+Return the absolute LMA of the named @var{section}.  (@pxref{Output
 Section LMA}).
 
 @kindex MAX
@@ -5696,7 +5758,7 @@ value has been given for this segment (w
 option) that value will be returned; otherwise the value will be
 @var{default}.  At present, the @samp{-T} command-line option can only
 be used to set the base address for the ``text'', ``data'', and
-``bss'' sections, but you use @code{SEGMENT_START} with any segment
+``bss'' sections, but you can use @code{SEGMENT_START} with any segment
 name.
 
 @item SIZEOF(@var{section})
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.85
diff -u -p -r1.85 ldexp.c
--- ld/ldexp.c	12 Aug 2010 13:36:50 -0000	1.85
+++ ld/ldexp.c	16 Aug 2010 05:22:23 -0000
@@ -138,7 +138,8 @@ exp_print_token (token_code_type code, i
 static void
 make_abs (void)
 {
-  expld.result.value += expld.result.section->vma;
+  if (expld.result.section != NULL)
+    expld.result.value += expld.result.section->vma;
   expld.result.section = bfd_abs_section_ptr;
 }
 
@@ -190,6 +191,15 @@ exp_relop (asection *section, bfd_vma va
 }
 
 static void
+new_number (bfd_vma value)
+{
+  expld.result.valid_p = TRUE;
+  expld.result.value = value;
+  expld.result.str = NULL;
+  expld.result.section = NULL;
+}
+
+static void
 new_rel (bfd_vma value, asection *section)
 {
   expld.result.valid_p = TRUE;
@@ -227,17 +237,14 @@ fold_unary (etree_type *tree)
 	  break;
 
 	case '~':
-	  make_abs ();
 	  expld.result.value = ~expld.result.value;
 	  break;
 
 	case '!':
-	  make_abs ();
 	  expld.result.value = !expld.result.value;
 	  break;
 
 	case '-':
-	  make_abs ();
 	  expld.result.value = -expld.result.value;
 	  break;
 
@@ -293,6 +300,7 @@ fold_binary (etree_type *tree)
     {
       const char *segment_name;
       segment_type *seg;
+
       /* Check to see if the user has overridden the default
 	 value.  */
       segment_name = tree->binary.rhs->name.name;
@@ -305,9 +313,7 @@ fold_binary (etree_type *tree)
 	      einfo (_("%P: warning: address of `%s' isn't multiple of maximum page size\n"),
 		     segment_name);
 	    seg->used = TRUE;
-	    expld.result.value = seg->value;
-	    expld.result.str = NULL;
-	    expld.result.section = expld.section;
+	    new_rel_from_abs (seg->value);
 	    break;
 	  }
       return;
@@ -319,32 +325,20 @@ fold_binary (etree_type *tree)
 
   if (expld.result.valid_p)
     {
-      /* If the values are from different sections, or this is an
-	 absolute expression, make both the source arguments
-	 absolute.  However, adding or subtracting an absolute
-	 value from a relative value is meaningful, and is an
-	 exception.  */
-      if (expld.section != bfd_abs_section_ptr
-	  && lhs.section == bfd_abs_section_ptr
-	  && tree->type.node_code == '+')
+      if (lhs.section != expld.result.section)
 	{
-	  /* Keep the section of the rhs term.  */
-	  expld.result.value = lhs.value + expld.result.value;
-	  return;
-	}
-      else if (expld.section != bfd_abs_section_ptr
-	       && expld.result.section == bfd_abs_section_ptr
-	       && (tree->type.node_code == '+'
-		   || tree->type.node_code == '-'))
-	{
-	  /* Keep the section of the lhs term.  */
-	  expld.result.section = lhs.section;
-	}
-      else if (expld.result.section != lhs.section
-	       || expld.section == bfd_abs_section_ptr)
-	{
-	  make_abs ();
-	  lhs.value += lhs.section->vma;
+	  /* If the values are from different sections, and neither is
+	     just a number, make both the source arguments absolute.  */
+	  if (expld.result.section != NULL
+	      && lhs.section != NULL)
+	    {
+	      make_abs ();
+	      lhs.value += lhs.section->vma;
+	    }
+
+	  /* If the rhs is just a number, keep the lhs section.  */
+	  else if (expld.result.section == NULL)
+	    expld.result.section = lhs.section;
 	}
 
       switch (tree->type.node_code)
@@ -366,26 +360,32 @@ fold_binary (etree_type *tree)
 	  break;
 
 #define BOP(x, y) \
-	    case x:							\
-	      expld.result.value = lhs.value y expld.result.value;	\
-	      break;
+	case x:							\
+	  expld.result.value = lhs.value y expld.result.value;	\
+	  break;
+
+#define BOPN(x, y) \
+	case x:							\
+	  expld.result.value = lhs.value y expld.result.value;	\
+	  expld.result.section = NULL;				\
+	  break;
 
 	  BOP ('+', +);
 	  BOP ('*', *);
 	  BOP ('-', -);
 	  BOP (LSHIFT, <<);
 	  BOP (RSHIFT, >>);
-	  BOP (EQ, ==);
-	  BOP (NE, !=);
-	  BOP ('<', <);
-	  BOP ('>', >);
-	  BOP (LE, <=);
-	  BOP (GE, >=);
 	  BOP ('&', &);
 	  BOP ('^', ^);
 	  BOP ('|', |);
-	  BOP (ANDAND, &&);
-	  BOP (OROR, ||);
+	  BOPN (EQ, ==);
+	  BOPN (NE, !=);
+	  BOPN ('<', <);
+	  BOPN ('>', >);
+	  BOPN (LE, <=);
+	  BOPN (GE, >=);
+	  BOPN (ANDAND, &&);
+	  BOPN (OROR, ||);
 
 	case MAX_K:
 	  if (lhs.value > expld.result.value)
@@ -499,7 +499,7 @@ fold_name (etree_type *tree)
 	     The bfd function may cache incorrect data.  */
 	  if (expld.phase != lang_mark_phase_enum)
 	    hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
-	  new_abs (hdr_size);
+	  new_number (hdr_size);
 	}
       break;
 
@@ -516,14 +516,12 @@ fold_name (etree_type *tree)
 					    &link_info,
 					    tree->name.name,
 					    FALSE, FALSE, TRUE);
-	  expld.result.value = (h != NULL
-				&& (h->type == bfd_link_hash_defined
-				    || h->type == bfd_link_hash_defweak
-				    || h->type == bfd_link_hash_common)
-				&& (def_iteration == lang_statement_iteration
-				    || def_iteration == -1));
-	  expld.result.section = expld.section;
-	  expld.result.valid_p = TRUE;
+	  new_number (h != NULL
+		      && (h->type == bfd_link_hash_defined
+			  || h->type == bfd_link_hash_defweak
+			  || h->type == bfd_link_hash_common)
+		      && (def_iteration == lang_statement_iteration
+			  || def_iteration == -1));
 	}
       break;
 
@@ -545,24 +543,19 @@ fold_name (etree_type *tree)
 	  else if (h->type == bfd_link_hash_defined
 		   || h->type == bfd_link_hash_defweak)
 	    {
-	      if (bfd_is_abs_section (h->u.def.section))
-		new_abs (h->u.def.value);
-	      else
-		{
-		  asection *output_section;
+	      asection *output_section;
 
-		  output_section = h->u.def.section->output_section;
-		  if (output_section == NULL)
-		    {
-		      if (expld.phase != lang_mark_phase_enum)
-			einfo (_("%X%S: unresolvable symbol `%s'"
-				 " referenced in expression\n"),
-			       tree->name.name);
-		    }
-		  else
-		    new_rel (h->u.def.value + h->u.def.section->output_offset,
-			     output_section);
+	      output_section = h->u.def.section->output_section;
+	      if (output_section == NULL)
+		{
+		  if (expld.phase != lang_mark_phase_enum)
+		    einfo (_("%X%S: unresolvable symbol `%s'"
+			     " referenced in expression\n"),
+			   tree->name.name);
 		}
+	      else
+		new_rel (h->u.def.value + h->u.def.section->output_offset,
+			 output_section);
 	    }
 	  else if (expld.phase == lang_final_phase_enum
 		   || expld.assigning_to_dot)
@@ -633,7 +626,7 @@ fold_name (etree_type *tree)
 	      if (expld.phase == lang_final_phase_enum)
 		einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
 		       tree->name.name);
-	      new_abs (0);
+	      new_number (0);
 	    }
 	  else if (os->processed_vma)
 	    {
@@ -645,7 +638,7 @@ fold_name (etree_type *tree)
 	      else
 		val = (bfd_vma)1 << os->bfd_section->alignment_power;
 	      
-	      new_abs (val);
+	      new_number (val);
 	    }
 	}
       break;
@@ -656,7 +649,7 @@ fold_name (etree_type *tree)
         
         mem = lang_memory_region_lookup (tree->name.name, FALSE);  
         if (mem != NULL) 
-          new_abs (mem->length);
+          new_number (mem->length);
         else          
           einfo (_("%F%S: undefined MEMORY region `%s'"
 		   " referenced in expression\n"), tree->name.name);
@@ -664,23 +657,24 @@ fold_name (etree_type *tree)
       break;
 
     case ORIGIN:
-      {
-        lang_memory_region_type *mem;
+      if (expld.phase != lang_first_phase_enum)
+	{
+	  lang_memory_region_type *mem;
         
-        mem = lang_memory_region_lookup (tree->name.name, FALSE);  
-        if (mem != NULL) 
-          new_abs (mem->origin);
-        else          
-          einfo (_("%F%S: undefined MEMORY region `%s'"
-		   " referenced in expression\n"), tree->name.name);
-      }
+	  mem = lang_memory_region_lookup (tree->name.name, FALSE);  
+	  if (mem != NULL) 
+	    new_rel_from_abs (mem->origin);
+	  else          
+	    einfo (_("%F%S: undefined MEMORY region `%s'"
+		     " referenced in expression\n"), tree->name.name);
+	}
       break;
 
     case CONSTANT:
       if (strcmp (tree->name.name, "MAXPAGESIZE") == 0)
-	new_abs (config.maxpagesize);
+	new_number (config.maxpagesize);
       else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0)
-	new_abs (config.commonpagesize);
+	new_number (config.commonpagesize);
       else
 	einfo (_("%F%S: unknown constant `%s' referenced in expression\n"),
 	       tree->name.name);
@@ -704,7 +698,7 @@ exp_fold_tree_1 (etree_type *tree)
   switch (tree->type.node_class)
     {
     case etree_value:
-      new_rel (tree->value.value, expld.section);
+      new_number (tree->value.value);
       expld.result.str = tree->value.str;
       break;
 
@@ -767,7 +761,11 @@ exp_fold_tree_1 (etree_type *tree)
 		{
 		  bfd_vma nextdot;
 
-		  nextdot = expld.result.value + expld.result.section->vma;
+		  nextdot = expld.result.value;
+		  if (expld.result.section != NULL)
+		    nextdot += expld.result.section->vma;
+		  else
+		    nextdot += expld.section->vma;
 		  if (nextdot < expld.dot
 		      && expld.section != bfd_abs_section_ptr)
 		    einfo (_("%F%S cannot move location counter backwards"
@@ -818,6 +816,8 @@ exp_fold_tree_1 (etree_type *tree)
 	      lang_update_definedness (tree->assign.dst, h);
 	      h->type = bfd_link_hash_defined;
 	      h->u.def.value = expld.result.value;
+	      if (expld.result.section == NULL)
+		expld.result.section = expld.section;
 	      h->u.def.section = expld.result.section;
 	      if (tree->type.node_class == etree_provide)
 		tree->type.node_class = etree_provided;
@@ -856,6 +856,12 @@ exp_fold_tree_1 (etree_type *tree)
       memset (&expld.result, 0, sizeof (expld.result));
       break;
     }
+
+  /* Any value not inside an output section statement is an
+     absolute value.  */
+  if (expld.result.valid_p
+      && expld.section == bfd_abs_section_ptr)
+    make_abs ();
 }
 
 void
@@ -1186,7 +1192,8 @@ exp_get_abs_int (etree_type *tree, int d
 
       if (expld.result.valid_p)
 	{
-	  expld.result.value += expld.result.section->vma;
+	  if (expld.result.section != NULL)
+	    expld.result.value += expld.result.section->vma;
 	  return expld.result.value;
 	}
       else if (name != NULL && expld.phase != lang_mark_phase_enum)
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.337
diff -u -p -r1.337 ldlang.c
--- ld/ldlang.c	6 Aug 2010 01:51:17 -0000	1.337
+++ ld/ldlang.c	16 Aug 2010 05:22:26 -0000
@@ -3916,7 +3916,7 @@ print_assignment (lang_assignment_statem
 	{
 	  value = expld.result.value;
 
-	  if (expld.result.section)
+	  if (expld.result.section != NULL)
 	    value += expld.result.section->vma;
 
 	  minfo ("0x%V", value);
@@ -3933,7 +3933,7 @@ print_assignment (lang_assignment_statem
 	    {
 	      value = h->u.def.value;
 
-	      if (expld.result.section)
+	      if (expld.result.section != NULL)
 		value += expld.result.section->vma;
 
 	      minfo ("[0x%V]", value);
@@ -4718,7 +4718,11 @@ lang_size_sections_1
 		exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
 
 		if (expld.result.valid_p)
-		  dot = expld.result.value + expld.result.section->vma;
+		  {
+		    dot = expld.result.value;
+		    if (expld.result.section != NULL)
+		      dot += expld.result.section->vma;
+		  }
 		else if (expld.phase != lang_mark_phase_enum)
 		  einfo (_("%F%S: non constant or forward reference"
 			   " address expression for section %s\n"),
@@ -5397,8 +5401,11 @@ lang_do_assignments_1 (lang_statement_un
 	case lang_data_statement_enum:
 	  exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
 	  if (expld.result.valid_p)
-	    s->data_statement.value = (expld.result.value
-				       + expld.result.section->vma);
+	    {
+	      s->data_statement.value = expld.result.value;
+	      if (expld.result.section != NULL)
+		s->data_statement.value += expld.result.section->vma;
+	    }
 	  else
 	    einfo (_("%F%P: invalid data statement\n"));
 	  {
Index: ld/testsuite/ld-scripts/memory.t
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-scripts/memory.t,v
retrieving revision 1.2
diff -u -p -r1.2 memory.t
--- ld/testsuite/ld-scripts/memory.t	2 Mar 2009 17:27:36 -0000	1.2
+++ ld/testsuite/ld-scripts/memory.t	16 Aug 2010 05:22:28 -0000
@@ -15,19 +15,7 @@ SECTIONS
   . = 0;
   .text :
   {
-    /* The value returned by the ORIGIN operator is a constant.
-       However it is being assigned to a symbol declared within
-       a section.  Therefore the symbol is section-relative and
-       its value will include the offset of that section from
-       the start of memory.  ie the declaration:
-          text_start = ORIGIN (TEXTMEM);
-       here will result in text_start having a value of 0x200.
-       Hence we need to subtract the absolute value of the
-       location counter at this point in order to give text_start
-       a value that is truely absolute, and which coincidentally
-       will allow the tests in script.exp to work.  */
- 	
-    text_start = ORIGIN(TEXTMEM) - ABSOLUTE (.);
+    text_start = ORIGIN (TEXTMEM);
     *(.text)
     *(.pr)
     text_end = .;

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-16 15:49           ` Alan Modra
@ 2010-08-19 12:44             ` Alan Modra
  2010-08-19 20:01               ` Daniel Jacobowitz
  2010-10-01  8:20             ` PR12066 Alan Modra
  1 sibling, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-08-19 12:44 UTC (permalink / raw)
  To: Ian Lance Taylor, Daniel Jacobowitz, binutils, Kazu Hirata

On Tue, Aug 17, 2010 at 12:31:01AM +0930, Alan Modra wrote:
> binutils/
> 	* NEWS: Mention change in linker script expression evaluation.
> ld/
> 	* ld.texinfo (Expression Section): Detail expression evaluation.
[snip]

Committed.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-19 12:44             ` Alan Modra
@ 2010-08-19 20:01               ` Daniel Jacobowitz
  2010-08-31  4:06                 ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-08-19 20:01 UTC (permalink / raw)
  To: Ian Lance Taylor, binutils, Kazu Hirata

On Thu, Aug 19, 2010 at 04:10:47PM +0930, Alan Modra wrote:
> On Tue, Aug 17, 2010 at 12:31:01AM +0930, Alan Modra wrote:
> > binutils/
> > 	* NEWS: Mention change in linker script expression evaluation.
> > ld/
> > 	* ld.texinfo (Expression Section): Detail expression evaluation.
> [snip]
> 
> Committed.

Thank you for working on this!  I think the new version makes a lot
more sense.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-19 20:01               ` Daniel Jacobowitz
@ 2010-08-31  4:06                 ` Alan Modra
  2010-08-31  5:33                   ` Hans-Peter Nilsson
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-08-31  4:06 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: binutils, Alexandre Oliva

> > On Tue, Aug 17, 2010 at 12:31:01AM +0930, Alan Modra wrote:
> > > binutils/
> > > 	* NEWS: Mention change in linker script expression evaluation.
> > > ld/
> > > 	* ld.texinfo (Expression Section): Detail expression evaluation.

Looking at testsuite results, I see this change of mine introduced
some failures.

+FAIL: ld-mmix/bpo-22
regexp_diff match failure
regexp "^0+ g       \.text	0+ Main$"
line   "0000000000000000 g       *ABS*	0000000000000000 Main"

This one is due to
  Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : ADDR (.text));
being evaluated outside of an output section, so giving an absolute
symbol result.  The assignment turns out to be "Main = _start", but
even "Main = Main" would result in Main being converted to an absolute
symbol.

+FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
+FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking
./ld-new: tmpdir/dump0.o(.text+0x34): reloc against `(null)': relocation references a different segment

These are both due to --defsym WD1=D6 now resulting in an absolute WD1
whereas ld used to make WD1 an exact alias for the symbol D6.  The old
behaviour was contrary to the ld docs, which said --defsym created a
symbol at "the absolute address" given by the expression.

I'm not inclined to modify the new rules for expression evaluation.
If we make an exception for sym2=sym1 assignment, then where do we
draw the line?  eg. If sym2=sym1 always gives sym2 the section of
sym1, why should sym2=sym1+1 not do the same?  It would be reasonable
to change ld to evaluate *all* expresions as relative, but I suspect
that would break too many existing ld scripts.

Here's a fix for the mmix failure.

	* scripttempl/mmo.sc: Move assignment to "Main" inside .text
	output section statement.

OK to apply?

Index: ld/scripttempl/mmo.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/mmo.sc,v
retrieving revision 1.7
diff -u -p -r1.7 mmo.sc
--- ld/scripttempl/mmo.sc	29 Jul 2009 00:25:22 -0000	1.7
+++ ld/scripttempl/mmo.sc	31 Aug 2010 03:37:51 -0000
@@ -60,8 +60,8 @@ SECTIONS
     ${RELOCATING+ PROVIDE(etext = .);}
     ${RELOCATING+ PROVIDE(_etext = .);}
     ${RELOCATING+ PROVIDE(__etext = .);}
+    ${RELOCATING+Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : ADDR (.text));}
   }
-  ${RELOCATING+Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : ADDR (.text));}
 
   .stab 0 : { *(.stab) }
   .stabstr 0 : { *(.stabstr) }

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-31  4:06                 ` Alan Modra
@ 2010-08-31  5:33                   ` Hans-Peter Nilsson
  0 siblings, 0 replies; 48+ messages in thread
From: Hans-Peter Nilsson @ 2010-08-31  5:33 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Alexandre Oliva

On Tue, 31 Aug 2010, Alan Modra wrote:
> 	* scripttempl/mmo.sc: Move assignment to "Main" inside .text
> 	output section statement.
>
> OK to apply?

It "naturally" belongs there and the cvs history doesn't show
any uncommented reason why it's currently outside, so yes,
thanks.

brgds, H-P

^ permalink raw reply	[flat|nested] 48+ messages in thread

* PR12066
  2010-08-16 15:49           ` Alan Modra
  2010-08-19 12:44             ` Alan Modra
@ 2010-10-01  8:20             ` Alan Modra
  1 sibling, 0 replies; 48+ messages in thread
From: Alan Modra @ 2010-10-01  8:20 UTC (permalink / raw)
  To: binutils

On Tue, Aug 17, 2010 at 12:31:01AM +0930, Alan Modra wrote:
> 	* NEWS: Mention change in linker script expression evaluation.

The PR 12066 test-cases assign lots of values to symbols, some of
which are addresses and some lengths or just plain numbers, then run
into trouble when they are all interpreted as absolute addresses.  The
new expression evaluation scheme differentiates between numbers,
absolute addresses, and relative addresses.  The trouble is that BFD
doesn't have a way to distinguish an absolute address from a plain
number, so assigning to a symbol then using it loses the difference
between a plain number and an address.  I first developed a patch to
allow ld to do that (attached) then decided that a simpler approach
would work, and in fact is closer to the old ld expression evaluation.

Besides, the other patch caused a segfault in the xtensa relax_section
due to introducing an alias for bfd_abs_section, and I didn't want to
chase down all other potential problems.

	PR ld/12066
	* ldexp.c (fold_name): Treat absolute symbols as plain numbers.
	* ld.texinfo (Expression Section): Don't say absolute symbols
	are addresses.

Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.86
diff -u -p -r1.86 ldexp.c
--- ld/ldexp.c	19 Aug 2010 05:51:49 -0000	1.86
+++ ld/ldexp.c	1 Oct 2010 02:34:55 -0000
@@ -553,6 +553,8 @@ fold_name (etree_type *tree)
 			     " referenced in expression\n"),
 			   tree->name.name);
 		}
+	      else if (output_section == bfd_abs_section_ptr)
+		new_number (h->u.def.value + h->u.def.section->output_offset);
 	      else
 		new_rel (h->u.def.value + h->u.def.section->output_offset,
 			 output_section);
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.264
diff -u -p -r1.264 ld.texinfo
--- ld/ld.texinfo	16 Sep 2010 00:06:12 -0000	1.264
+++ ld/ld.texinfo	1 Oct 2010 02:56:29 -0000
@@ -5453,11 +5453,11 @@ value of a section relative symbol.  On 
 symbol will retain the same value throughout any further link
 operations.
 
-Some terms in linker expressions are addresses.  This is true of all
-symbols and for builtin functions that return an address, such as
-@code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and @code{SEGMENT_START}.
-Other terms are simply numbers, or are builtin functions that return a
-non-address value, such as @code{LENGTH}.
+Some terms in linker expressions are addresses.  This is true of
+section relative symbols and for builtin functions that return an
+address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and
+@code{SEGMENT_START}.  Other terms are simply numbers, or are builtin
+functions that return a non-address value, such as @code{LENGTH}.
 
 When the linker evaluates an expression, the result depends on where
 the expression is located in a linker script.  Expressions appearing

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-08-13  0:05           ` Alan Modra
@ 2010-12-16  8:01             ` H.J. Lu
  2010-12-16 11:16               ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-16  8:01 UTC (permalink / raw)
  To: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
>> You can try the new linker on Linux kernel.
>
> An x86 2.6.35 kernel built without any differences.
>

It caused:

http://sourceware.org/bugzilla/show_bug.cgi?id=12327


-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16  8:01             ` H.J. Lu
@ 2010-12-16 11:16               ` Alan Modra
  2010-12-16 13:21                 ` H.J. Lu
                                   ` (2 more replies)
  0 siblings, 3 replies; 48+ messages in thread
From: Alan Modra @ 2010-12-16 11:16 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Wed, Dec 15, 2010 at 08:25:17PM -0800, H.J. Lu wrote:
> On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
> > On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
> >> You can try the new linker on Linux kernel.
> >
> > An x86 2.6.35 kernel built without any differences.
> >
> 
> It caused:
> 
> http://sourceware.org/bugzilla/show_bug.cgi?id=12327

I was expecting this to cause some trouble.  You can't avoid breaking
some linker scripts when you change the linker expression evaluation
rules (really, give it some rules rather than the adhoc mess that was
there before).  I wonder if I should have gone a little further, and
removed the special case for expressions outside of an output section
definition.  It's what I really wanted to do, but ran into a number of
testsuite failures in our own testsuite when I originally tried that.
Now that we differentiate between plain numbers and absolute symbols,
only one testcase needs adjusting.

So, if I commit this, scripts like the testcase below will need some
asjustment.  On the other hand, sym1 = sym2 assignments should work
like they used to outside of an output section statement, fixing the
kernel problem and
frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking

How to people feel about this for 2.21.1?

ld/
	* ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
	when outside of an output section statement.
	* ld.texinfo (Expression Section): Update description.
ld/testsuite/
	* ld-scripts/align.t: Make ADDR absolute.

Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.87
diff -u -p -r1.87 ldexp.c
--- ld/ldexp.c	1 Oct 2010 08:15:41 -0000	1.87
+++ ld/ldexp.c	16 Dec 2010 08:52:09 -0000
@@ -858,12 +858,6 @@ exp_fold_tree_1 (etree_type *tree)
       memset (&expld.result, 0, sizeof (expld.result));
       break;
     }
-
-  /* Any value not inside an output section statement is an
-     absolute value.  */
-  if (expld.result.valid_p
-      && expld.section == bfd_abs_section_ptr)
-    make_abs ();
 }
 
 void
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.268
diff -u -p -r1.268 ld.texinfo
--- ld/ld.texinfo	15 Dec 2010 14:56:37 -0000	1.268
+++ ld/ld.texinfo	16 Dec 2010 08:52:59 -0000
@@ -5505,15 +5505,13 @@ address, such as @code{ADDR}, @code{LOAD
 functions that return a non-address value, such as @code{LENGTH}.
 
 When the linker evaluates an expression, the result depends on where
-the expression is located in a linker script.  Expressions appearing
-outside an output section definitions are evaluated with all terms
-first being converted to absolute addresses before applying operators,
-and evaluate to an absolute address result.  Expressions appearing
-inside an output section definition are evaluated with more complex
-rules, but the aim is to treat terms as relative addresses and produce
-a relative address result.  In particular, an assignment of a number
-to a symbol results in a symbol relative to the output section with an
-offset given by the number.  So, in the following simple example,
+the expression is located in a linker script.  Outside of an output
+section definition, a result that is a number is treated as an
+absolute address.  Inside an output section definition, a result that
+is a number is treated as a relative address.  In particular, an
+assignment of a number to a symbol results in a symbol relative to the
+output section with an offset given by the number.  So, in the
+following simple example,
 
 @smallexample
 @group
@@ -5537,9 +5535,8 @@ address 0x100 in the first two assignmen
 @code{__data_start} are set to 0x10 relative to the @code{.data}
 section in the second two assignments.
 
-For expressions appearing inside an output section definition
-involving numbers, relative addresses and absolute addresses, ld
-follows these rules to evaluate terms:
+For expressions involving numbers, relative addresses and absolute
+addresses, ld follows these rules to evaluate terms:
 
 @itemize @bullet
 @item
Index: ld/testsuite/ld-scripts/align.t
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-scripts/align.t,v
retrieving revision 1.1
diff -u -p -r1.1 align.t
--- ld/testsuite/ld-scripts/align.t	20 Feb 2004 15:31:10 -0000	1.1
+++ ld/testsuite/ld-scripts/align.t	16 Dec 2010 08:52:10 -0000
@@ -4,5 +4,5 @@ SECTIONS
   .data ALIGN(0x40) : AT (ALIGN (LOADADDR (.text) + SIZEOF (.text), 0x80))
     {}
   ASSERT (LOADADDR(.data) == 0x80, "dyadic ALIGN broken")
-  ASSERT (ADDR(.data) == 0x40, "monadic ALIGN broken")
+  ASSERT (ABSOLUTE(ADDR(.data)) == 0x40, "monadic ALIGN broken")
 }

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 11:16               ` Alan Modra
@ 2010-12-16 13:21                 ` H.J. Lu
  2010-12-16 15:49                   ` H.J. Lu
  2010-12-16 16:51                 ` Daniel Jacobowitz
  2010-12-16 22:43                 ` H.J. Lu
  2 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 13:21 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 3:02 AM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Dec 15, 2010 at 08:25:17PM -0800, H.J. Lu wrote:
>> On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
>> > On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
>> >> You can try the new linker on Linux kernel.
>> >
>> > An x86 2.6.35 kernel built without any differences.
>> >
>>
>> It caused:
>>
>> http://sourceware.org/bugzilla/show_bug.cgi?id=12327
>
> I was expecting this to cause some trouble.  You can't avoid breaking
> some linker scripts when you change the linker expression evaluation
> rules (really, give it some rules rather than the adhoc mess that was
> there before).  I wonder if I should have gone a little further, and
> removed the special case for expressions outside of an output section
> definition.  It's what I really wanted to do, but ran into a number of
> testsuite failures in our own testsuite when I originally tried that.
> Now that we differentiate between plain numbers and absolute symbols,
> only one testcase needs adjusting.
>
> So, if I commit this, scripts like the testcase below will need some
> asjustment.  On the other hand, sym1 = sym2 assignments should work
> like they used to outside of an output section statement, fixing the
> kernel problem and
> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking
>
> How to people feel about this for 2.21.1?
>
> ld/
>        * ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
>        when outside of an output section statement.
>        * ld.texinfo (Expression Section): Update description.
> ld/testsuite/
>        * ld-scripts/align.t: Make ADDR absolute.
>
> Index: ld/ldexp.c
> ===================================================================
> RCS file: /cvs/src/src/ld/ldexp.c,v
> retrieving revision 1.87
> diff -u -p -r1.87 ldexp.c
> --- ld/ldexp.c  1 Oct 2010 08:15:41 -0000       1.87
> +++ ld/ldexp.c  16 Dec 2010 08:52:09 -0000
> @@ -858,12 +858,6 @@ exp_fold_tree_1 (etree_type *tree)
>       memset (&expld.result, 0, sizeof (expld.result));
>       break;
>     }
> -
> -  /* Any value not inside an output section statement is an
> -     absolute value.  */
> -  if (expld.result.valid_p
> -      && expld.section == bfd_abs_section_ptr)
> -    make_abs ();
>  }
>
>  void
> Index: ld/ld.texinfo
> ===================================================================
> RCS file: /cvs/src/src/ld/ld.texinfo,v
> retrieving revision 1.268
> diff -u -p -r1.268 ld.texinfo
> --- ld/ld.texinfo       15 Dec 2010 14:56:37 -0000      1.268
> +++ ld/ld.texinfo       16 Dec 2010 08:52:59 -0000
> @@ -5505,15 +5505,13 @@ address, such as @code{ADDR}, @code{LOAD
>  functions that return a non-address value, such as @code{LENGTH}.
>
>  When the linker evaluates an expression, the result depends on where
> -the expression is located in a linker script.  Expressions appearing
> -outside an output section definitions are evaluated with all terms
> -first being converted to absolute addresses before applying operators,
> -and evaluate to an absolute address result.  Expressions appearing
> -inside an output section definition are evaluated with more complex
> -rules, but the aim is to treat terms as relative addresses and produce
> -a relative address result.  In particular, an assignment of a number
> -to a symbol results in a symbol relative to the output section with an
> -offset given by the number.  So, in the following simple example,
> +the expression is located in a linker script.  Outside of an output
> +section definition, a result that is a number is treated as an
> +absolute address.  Inside an output section definition, a result that
> +is a number is treated as a relative address.  In particular, an
> +assignment of a number to a symbol results in a symbol relative to the
> +output section with an offset given by the number.  So, in the
> +following simple example,
>
>  @smallexample
>  @group
> @@ -5537,9 +5535,8 @@ address 0x100 in the first two assignmen
>  @code{__data_start} are set to 0x10 relative to the @code{.data}
>  section in the second two assignments.
>
> -For expressions appearing inside an output section definition
> -involving numbers, relative addresses and absolute addresses, ld
> -follows these rules to evaluate terms:
> +For expressions involving numbers, relative addresses and absolute
> +addresses, ld follows these rules to evaluate terms:
>
>  @itemize @bullet
>  @item
> Index: ld/testsuite/ld-scripts/align.t
> ===================================================================
> RCS file: /cvs/src/src/ld/testsuite/ld-scripts/align.t,v
> retrieving revision 1.1
> diff -u -p -r1.1 align.t
> --- ld/testsuite/ld-scripts/align.t     20 Feb 2004 15:31:10 -0000      1.1
> +++ ld/testsuite/ld-scripts/align.t     16 Dec 2010 08:52:10 -0000
> @@ -4,5 +4,5 @@ SECTIONS
>   .data ALIGN(0x40) : AT (ALIGN (LOADADDR (.text) + SIZEOF (.text), 0x80))
>     {}
>   ASSERT (LOADADDR(.data) == 0x80, "dyadic ALIGN broken")
> -  ASSERT (ADDR(.data) == 0x40, "monadic ALIGN broken")
> +  ASSERT (ABSOLUTE(ADDR(.data)) == 0x40, "monadic ALIGN broken")
>  }
>

Did it work before your change on Aug 19, 2010?

-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 13:21                 ` H.J. Lu
@ 2010-12-16 15:49                   ` H.J. Lu
  0 siblings, 0 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 15:49 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 3:57 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 3:02 AM, Alan Modra <amodra@gmail.com> wrote:
>> On Wed, Dec 15, 2010 at 08:25:17PM -0800, H.J. Lu wrote:
>>> On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
>>> > On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
>>> >> You can try the new linker on Linux kernel.
>>> >
>>> > An x86 2.6.35 kernel built without any differences.
>>> >
>>>
>>> It caused:
>>>
>>> http://sourceware.org/bugzilla/show_bug.cgi?id=12327
>>
>> I was expecting this to cause some trouble.  You can't avoid breaking
>> some linker scripts when you change the linker expression evaluation
>> rules (really, give it some rules rather than the adhoc mess that was
>> there before).  I wonder if I should have gone a little further, and
>> removed the special case for expressions outside of an output section
>> definition.  It's what I really wanted to do, but ran into a number of
>> testsuite failures in our own testsuite when I originally tried that.
>> Now that we differentiate between plain numbers and absolute symbols,
>> only one testcase needs adjusting.
>>
>> So, if I commit this, scripts like the testcase below will need some
>> asjustment.  On the other hand, sym1 = sym2 assignments should work
>> like they used to outside of an output section statement, fixing the
>> kernel problem and
>> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
>> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking
>>
>> How to people feel about this for 2.21.1?
>>
>> ld/
>>        * ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
>>        when outside of an output section statement.
>>        * ld.texinfo (Expression Section): Update description.
>> ld/testsuite/
>>        * ld-scripts/align.t: Make ADDR absolute.
>>
>> Index: ld/ldexp.c
>> ===================================================================
>> RCS file: /cvs/src/src/ld/ldexp.c,v
>> retrieving revision 1.87
>> diff -u -p -r1.87 ldexp.c
>> --- ld/ldexp.c  1 Oct 2010 08:15:41 -0000       1.87
>> +++ ld/ldexp.c  16 Dec 2010 08:52:09 -0000
>> @@ -858,12 +858,6 @@ exp_fold_tree_1 (etree_type *tree)
>>       memset (&expld.result, 0, sizeof (expld.result));
>>       break;
>>     }
>> -
>> -  /* Any value not inside an output section statement is an
>> -     absolute value.  */
>> -  if (expld.result.valid_p
>> -      && expld.section == bfd_abs_section_ptr)
>> -    make_abs ();
>>  }
>>
>>  void
>> Index: ld/ld.texinfo
>> ===================================================================
>> RCS file: /cvs/src/src/ld/ld.texinfo,v
>> retrieving revision 1.268
>> diff -u -p -r1.268 ld.texinfo
>> --- ld/ld.texinfo       15 Dec 2010 14:56:37 -0000      1.268
>> +++ ld/ld.texinfo       16 Dec 2010 08:52:59 -0000
>> @@ -5505,15 +5505,13 @@ address, such as @code{ADDR}, @code{LOAD
>>  functions that return a non-address value, such as @code{LENGTH}.
>>
>>  When the linker evaluates an expression, the result depends on where
>> -the expression is located in a linker script.  Expressions appearing
>> -outside an output section definitions are evaluated with all terms
>> -first being converted to absolute addresses before applying operators,
>> -and evaluate to an absolute address result.  Expressions appearing
>> -inside an output section definition are evaluated with more complex
>> -rules, but the aim is to treat terms as relative addresses and produce
>> -a relative address result.  In particular, an assignment of a number
>> -to a symbol results in a symbol relative to the output section with an
>> -offset given by the number.  So, in the following simple example,
>> +the expression is located in a linker script.  Outside of an output
>> +section definition, a result that is a number is treated as an
>> +absolute address.  Inside an output section definition, a result that
>> +is a number is treated as a relative address.  In particular, an
>> +assignment of a number to a symbol results in a symbol relative to the
>> +output section with an offset given by the number.  So, in the
>> +following simple example,
>>
>>  @smallexample
>>  @group
>> @@ -5537,9 +5535,8 @@ address 0x100 in the first two assignmen
>>  @code{__data_start} are set to 0x10 relative to the @code{.data}
>>  section in the second two assignments.
>>
>> -For expressions appearing inside an output section definition
>> -involving numbers, relative addresses and absolute addresses, ld
>> -follows these rules to evaluate terms:
>> +For expressions involving numbers, relative addresses and absolute
>> +addresses, ld follows these rules to evaluate terms:
>>
>>  @itemize @bullet
>>  @item
>> Index: ld/testsuite/ld-scripts/align.t
>> ===================================================================
>> RCS file: /cvs/src/src/ld/testsuite/ld-scripts/align.t,v
>> retrieving revision 1.1
>> diff -u -p -r1.1 align.t
>> --- ld/testsuite/ld-scripts/align.t     20 Feb 2004 15:31:10 -0000      1.1
>> +++ ld/testsuite/ld-scripts/align.t     16 Dec 2010 08:52:10 -0000
>> @@ -4,5 +4,5 @@ SECTIONS
>>   .data ALIGN(0x40) : AT (ALIGN (LOADADDR (.text) + SIZEOF (.text), 0x80))
>>     {}
>>   ASSERT (LOADADDR(.data) == 0x80, "dyadic ALIGN broken")
>> -  ASSERT (ADDR(.data) == 0x40, "monadic ALIGN broken")
>> +  ASSERT (ABSOLUTE(ADDR(.data)) == 0x40, "monadic ALIGN broken")
>>  }
>>
>
> Did it work before your change on Aug 19, 2010?
>

Kernel breaks only with --emit-relocs.  Can we limit the change to
--emit-relocs?

-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 11:16               ` Alan Modra
  2010-12-16 13:21                 ` H.J. Lu
@ 2010-12-16 16:51                 ` Daniel Jacobowitz
  2010-12-16 18:28                   ` H.J. Lu
  2010-12-16 22:43                 ` H.J. Lu
  2 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-12-16 16:51 UTC (permalink / raw)
  To: H.J. Lu, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
> How to people feel about this for 2.21.1?

IMO, this is a more logical behavior.  And there's going to be some
incompatibilities in the linker script language whether we do it or
not.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 16:51                 ` Daniel Jacobowitz
@ 2010-12-16 18:28                   ` H.J. Lu
  2010-12-16 23:14                     ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 18:28 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 7:48 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
> On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
>> How to people feel about this for 2.21.1?
>
> IMO, this is a more logical behavior.  And there's going to be some
> incompatibilities in the linker script language whether we do it or
> not.
>

I am against regressions in known linker scripts, including those
in linker testsuites. We should take a closer look at what we did
and fix it properly.


-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 11:16               ` Alan Modra
  2010-12-16 13:21                 ` H.J. Lu
  2010-12-16 16:51                 ` Daniel Jacobowitz
@ 2010-12-16 22:43                 ` H.J. Lu
  2010-12-16 22:58                   ` H.J. Lu
  2 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 22:43 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

[-- Attachment #1: Type: text/plain, Size: 1977 bytes --]

On Thu, Dec 16, 2010 at 3:02 AM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Dec 15, 2010 at 08:25:17PM -0800, H.J. Lu wrote:
>> On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
>> > On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
>> >> You can try the new linker on Linux kernel.
>> >
>> > An x86 2.6.35 kernel built without any differences.
>> >
>>
>> It caused:
>>
>> http://sourceware.org/bugzilla/show_bug.cgi?id=12327
>
> I was expecting this to cause some trouble.  You can't avoid breaking
> some linker scripts when you change the linker expression evaluation
> rules (really, give it some rules rather than the adhoc mess that was
> there before).  I wonder if I should have gone a little further, and
> removed the special case for expressions outside of an output section
> definition.  It's what I really wanted to do, but ran into a number of
> testsuite failures in our own testsuite when I originally tried that.
> Now that we differentiate between plain numbers and absolute symbols,
> only one testcase needs adjusting.
>
> So, if I commit this, scripts like the testcase below will need some
> asjustment.  On the other hand, sym1 = sym2 assignments should work
> like they used to outside of an output section statement, fixing the
> kernel problem and
> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking
>
> How to people feel about this for 2.21.1?
>

This patch works for me.


-- 
H.J.
--
ld/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
	on etree_name.

ld/testsuite/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.

[-- Attachment #2: binutils-pr12327-1.patch --]
[-- Type: text/plain, Size: 1976 bytes --]

ld/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
	on etree_name.

ld/testsuite/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.

diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..4376364 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -862,7 +862,8 @@ exp_fold_tree_1 (etree_type *tree)
   /* Any value not inside an output section statement is an
      absolute value.  */
   if (expld.result.valid_p
-      && expld.section == bfd_abs_section_ptr)
+      && expld.section == bfd_abs_section_ptr
+      && tree->type.node_class != etree_name)
     make_abs ();
 }
 
diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp
index 15cc079..5742ae9 100644
--- a/ld/testsuite/ld-scripts/defined.exp
+++ b/ld/testsuite/ld-scripts/defined.exp
@@ -66,4 +66,5 @@ if ![ld_simple_link $ld tmpdir/def "$LDFLAGS -T $srcdir/$subdir/defined.t tmpdir
 set prms_id 0
 run_dump_test "defined2"
 run_dump_test "defined3"
+run_dump_test "defined4"
 set LDFLAGS "$saved_LDFLAGS"
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.d	2010-12-16 14:00:46.264217155 -0800
@@ -0,0 +1,10 @@
+#ld: -Tdefined4.t
+#nm: -B
+#source: defined4.s
+
+# Check that arithmetic on DEFINED works.
+#...
+0+0 D defined
+#...
+0+0 D defined1
+#pass
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.s	2010-12-16 12:46:23.558273203 -0800
@@ -0,0 +1,4 @@
+	.globl	defined
+	.data
+defined:
+	.word 0
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.t	2010-12-16 12:46:45.236797081 -0800
@@ -0,0 +1,6 @@
+SECTIONS {
+	.text : { *(.text) }
+	.data : { *(.data) }
+	.bss : { *(.bss) *(COMMON) }
+}
+defined1 = defined;

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 22:43                 ` H.J. Lu
@ 2010-12-16 22:58                   ` H.J. Lu
  0 siblings, 0 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 22:58 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 2:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 3:02 AM, Alan Modra <amodra@gmail.com> wrote:
>> On Wed, Dec 15, 2010 at 08:25:17PM -0800, H.J. Lu wrote:
>>> On Thu, Aug 12, 2010 at 4:38 PM, Alan Modra <amodra@gmail.com> wrote:
>>> > On Thu, Aug 12, 2010 at 08:47:25AM -0700, H.J. Lu wrote:
>>> >> You can try the new linker on Linux kernel.
>>> >
>>> > An x86 2.6.35 kernel built without any differences.
>>> >
>>>
>>> It caused:
>>>
>>> http://sourceware.org/bugzilla/show_bug.cgi?id=12327
>>
>> I was expecting this to cause some trouble.  You can't avoid breaking
>> some linker scripts when you change the linker expression evaluation
>> rules (really, give it some rules rather than the adhoc mess that was
>> there before).  I wonder if I should have gone a little further, and
>> removed the special case for expressions outside of an output section
>> definition.  It's what I really wanted to do, but ran into a number of
>> testsuite failures in our own testsuite when I originally tried that.
>> Now that we differentiate between plain numbers and absolute symbols,
>> only one testcase needs adjusting.
>>
>> So, if I commit this, scripts like the testcase below will need some
>> asjustment.  On the other hand, sym1 = sym2 assignments should work
>> like they used to outside of an output section statement, fixing the
>> kernel problem and
>> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, pie linking
>> frv-linux FAIL: FRV uClinux PIC relocs to weak undefined symbols, shared linking
>>
>> How to people feel about this for 2.21.1?
>>
>
> This patch works for me.
>
>
> --
> H.J.
> --
> ld/
>
> 2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR ld/12327
>        * ldexp.c (exp_fold_tree_1): Don't make subexpressions absolute
>        on etree_name.
>
> ld/testsuite/
>
> 2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR ld/12327
>        * ld-scripts/defined.exp: Run defined4.
>
>        * ld-scripts/defined4.d: New.
>        * ld-scripts/defined4.s: Likewise.
>        * ld-scripts/defined4.t: Likewise.
>

It failed normal kernel build:

ld: kernel image bigger than KERNEL_IMAGE_SIZE


-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 18:28                   ` H.J. Lu
@ 2010-12-16 23:14                     ` Alan Modra
  2010-12-16 23:17                       ` H.J. Lu
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-12-16 23:14 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 08:50:56AM -0800, H.J. Lu wrote:
> On Thu, Dec 16, 2010 at 7:48 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
> > On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
> >> How to people feel about this for 2.21.1?
> >
> > IMO, this is a more logical behavior. And there's going to be some
> > incompatibilities in the linker script language whether we do it or
> > not.
> >
> 
> I am against regressions in known linker scripts, including those
> in linker testsuites. We should take a closer look at what we did
> and fix it properly.

You would rather stay with expression evaluation that we couldn't even
describe?

I made a deliberate change, trying to minimize breakage but knowing
that we surely would break some scripts that use more complex
expressions.  I also knew that symbol assignment outside of an output
section statement would result in absolute symbols, but hoped this
would not affect too many people.  It seems it does, so I offered this
further patch that cures the symbol assignment problem, *and*
simplifies the linker expression evaluation rules.  The tradeoff being
that this may break more complex expressions.

Can you verify that this fixes the x86_64 kernel build breakage?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 23:14                     ` Alan Modra
@ 2010-12-16 23:17                       ` H.J. Lu
  2010-12-16 23:38                         ` H.J. Lu
  2010-12-17  0:06                         ` Alan Modra
  0 siblings, 2 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 23:17 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 2:58 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 08:50:56AM -0800, H.J. Lu wrote:
>> On Thu, Dec 16, 2010 at 7:48 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
>> > On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
>> >> How to people feel about this for 2.21.1?
>> >
>> > IMO, this is a more logical behavior. And there's going to be some
>> > incompatibilities in the linker script language whether we do it or
>> > not.
>> >
>>
>> I am against regressions in known linker scripts, including those
>> in linker testsuites. We should take a closer look at what we did
>> and fix it properly.
>
> You would rather stay with expression evaluation that we couldn't even
> describe?

Well, I consider linker tests within binutils testsuite are valid usages and
we should do our best not to break them.

> I made a deliberate change, trying to minimize breakage but knowing
> that we surely would break some scripts that use more complex
> expressions.  I also knew that symbol assignment outside of an output
> section statement would result in absolute symbols, but hoped this
> would not affect too many people.  It seems it does, so I offered this
> further patch that cures the symbol assignment problem, *and*
> simplifies the linker expression evaluation rules.  The tradeoff being
> that this may break more complex expressions.
>
> Can you verify that this fixes the x86_64 kernel build breakage?
>

Your patch doesn't work. I got

./ld: kernel image bigger than KERNEL_IMAGE_SIZE

due to arch/x86/kernel/vmlinux.lds:

----
/*
 * Build-time check on the image size:
 */
. = ASSERT((_end - _text <= (512 * 1024 * 1024)),
    "kernel image bigger than KERNEL_IMAGE_SIZE");
. = ASSERT((irq_stack_union == 0),
           "irq_stack_union is not at start of per-cpu area");
. = ASSERT(kexec_control_code_size <= 2048,
           "kexec control code size is too big");

---

-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 23:17                       ` H.J. Lu
@ 2010-12-16 23:38                         ` H.J. Lu
  2010-12-17  0:01                           ` H.J. Lu
  2010-12-17  0:06                         ` Alan Modra
  1 sibling, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-16 23:38 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 3:14 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 2:58 PM, Alan Modra <amodra@gmail.com> wrote:
>> On Thu, Dec 16, 2010 at 08:50:56AM -0800, H.J. Lu wrote:
>>> On Thu, Dec 16, 2010 at 7:48 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
>>> > On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
>>> >> How to people feel about this for 2.21.1?
>>> >
>>> > IMO, this is a more logical behavior. And there's going to be some
>>> > incompatibilities in the linker script language whether we do it or
>>> > not.
>>> >
>>>
>>> I am against regressions in known linker scripts, including those
>>> in linker testsuites. We should take a closer look at what we did
>>> and fix it properly.
>>
>> You would rather stay with expression evaluation that we couldn't even
>> describe?
>
> Well, I consider linker tests within binutils testsuite are valid usages and
> we should do our best not to break them.
>
>> I made a deliberate change, trying to minimize breakage but knowing
>> that we surely would break some scripts that use more complex
>> expressions.  I also knew that symbol assignment outside of an output
>> section statement would result in absolute symbols, but hoped this
>> would not affect too many people.  It seems it does, so I offered this
>> further patch that cures the symbol assignment problem, *and*
>> simplifies the linker expression evaluation rules.  The tradeoff being
>> that this may break more complex expressions.
>>
>> Can you verify that this fixes the x86_64 kernel build breakage?
>>
>
> Your patch doesn't work. I got
>
> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
>
> due to arch/x86/kernel/vmlinux.lds:
>
> ----
> /*
>  * Build-time check on the image size:
>  */
> . = ASSERT((_end - _text <= (512 * 1024 * 1024)),
>    "kernel image bigger than KERNEL_IMAGE_SIZE");
> . = ASSERT((irq_stack_union == 0),
>           "irq_stack_union is not at start of per-cpu area");
> . = ASSERT(kexec_control_code_size <= 2048,
>           "kexec control code size is too big");
>

This hack may work.

-- 
H.J.
---
diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..5d27287 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -691,12 +691,15 @@ fold_name (etree_type *tree)
 static void
 exp_fold_tree_1 (etree_type *tree)
 {
+  asection *defined;
+
   if (tree == NULL)
     {
       memset (&expld.result, 0, sizeof (expld.result));
       return;
     }

+  defined = NULL;
   switch (tree->type.node_class)
     {
     case etree_value:
@@ -851,6 +854,17 @@ exp_fold_tree_1 (etree_type *tree)

     case etree_name:
       fold_name (tree);
+      if (link_info.hash)
+	{
+	  struct bfd_link_hash_entry *h;
+
+	  h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+				    FALSE, FALSE, TRUE);
+	  if (h
+	      && (h->type == bfd_link_hash_defined
+		  || h->type == bfd_link_hash_defweak))
+	    defined = h->u.def.section;
+	}
       break;

     default:
@@ -862,7 +876,10 @@ exp_fold_tree_1 (etree_type *tree)
   /* Any value not inside an output section statement is an
      absolute value.  */
   if (expld.result.valid_p
-      && expld.section == bfd_abs_section_ptr)
+      && expld.section == bfd_abs_section_ptr
+      && (tree->type.node_class != etree_name
+	  || !defined
+	  || defined == bfd_abs_section_ptr))
     make_abs ();
 }

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 23:38                         ` H.J. Lu
@ 2010-12-17  0:01                           ` H.J. Lu
  0 siblings, 0 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-17  0:01 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 3:17 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 3:14 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Thu, Dec 16, 2010 at 2:58 PM, Alan Modra <amodra@gmail.com> wrote:
>>> On Thu, Dec 16, 2010 at 08:50:56AM -0800, H.J. Lu wrote:
>>>> On Thu, Dec 16, 2010 at 7:48 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote:
>>>> > On Thu, Dec 16, 2010 at 09:32:43PM +1030, Alan Modra wrote:
>>>> >> How to people feel about this for 2.21.1?
>>>> >
>>>> > IMO, this is a more logical behavior. And there's going to be some
>>>> > incompatibilities in the linker script language whether we do it or
>>>> > not.
>>>> >
>>>>
>>>> I am against regressions in known linker scripts, including those
>>>> in linker testsuites. We should take a closer look at what we did
>>>> and fix it properly.
>>>
>>> You would rather stay with expression evaluation that we couldn't even
>>> describe?
>>
>> Well, I consider linker tests within binutils testsuite are valid usages and
>> we should do our best not to break them.
>>
>>> I made a deliberate change, trying to minimize breakage but knowing
>>> that we surely would break some scripts that use more complex
>>> expressions.  I also knew that symbol assignment outside of an output
>>> section statement would result in absolute symbols, but hoped this
>>> would not affect too many people.  It seems it does, so I offered this
>>> further patch that cures the symbol assignment problem, *and*
>>> simplifies the linker expression evaluation rules.  The tradeoff being
>>> that this may break more complex expressions.
>>>
>>> Can you verify that this fixes the x86_64 kernel build breakage?
>>>
>>
>> Your patch doesn't work. I got
>>
>> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
>>
>> due to arch/x86/kernel/vmlinux.lds:
>>

I am testing this patch.


H.J.
--
diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..c8fa331 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -691,12 +691,15 @@ fold_name (etree_type *tree)
 static void
 exp_fold_tree_1 (etree_type *tree)
 {
+  bfd_boolean absolute;
+
   if (tree == NULL)
     {
       memset (&expld.result, 0, sizeof (expld.result));
       return;
     }

+  absolute = TRUE;
   switch (tree->type.node_class)
     {
     case etree_value:
@@ -851,6 +854,21 @@ exp_fold_tree_1 (etree_type *tree)

     case etree_name:
       fold_name (tree);
+      if (tree->name.name
+	  && tree->name.name[0] != '.'
+	  && tree->name.name[1] != '\0'
+	  && link_info.hash)
+	{
+	  struct bfd_link_hash_entry *h;
+
+	  /* Only make absolute symbol value absolute.  */
+	  h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+				    FALSE, FALSE, TRUE);
+	  if (h
+	      && (h->type == bfd_link_hash_defined
+		  || h->type == bfd_link_hash_defweak))
+	    absolute = (h->u.def.section == bfd_abs_section_ptr);
+	}
       break;

     default:
@@ -861,7 +879,8 @@ exp_fold_tree_1 (etree_type *tree)

   /* Any value not inside an output section statement is an
      absolute value.  */
-  if (expld.result.valid_p
+  if (absolute
+      && expld.result.valid_p
       && expld.section == bfd_abs_section_ptr)
     make_abs ();
 }

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-16 23:17                       ` H.J. Lu
  2010-12-16 23:38                         ` H.J. Lu
@ 2010-12-17  0:06                         ` Alan Modra
  2010-12-17  4:17                           ` H.J. Lu
  1 sibling, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-12-17  0:06 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Dec 16, 2010 at 03:14:38PM -0800, H.J. Lu wrote:
> Your patch doesn't work. I got
> 
> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
> 
> due to arch/x86/kernel/vmlinux.lds:
> 
> ----
> /*
>  * Build-time check on the image size:
>  */
> . = ASSERT((_end - _text <= (512 * 1024 * 1024)),
>     "kernel image bigger than KERNEL_IMAGE_SIZE");

Extracting the relevant parts from the kernel link script:

SECTIONS
{
  . = 0xc000;
  .text :
  {
    _text = .;
    *(.text)
  }
  _end = .;
}
ASSERT (_end - _text <= 0x100, "fail");

You'd think that under the new rules, this ought to work.  "_end" is
an absolute address, so when evaluating "_end - _text", "_text" ought
to be converted from relative to absolute, the subtraction resuling in
an absolute address.  Then 0x100 gets converted from a number to
absolute address before being compared.

The trouble is that "_end" is *not* treated as an absolute address but
as a plain number.  That makes ld convert "_end" to a .text relative
address when evaluation "_end - _text", which doesn't cause a problem
at that stage, but the result is a relative address.  That means 0x100
is converted to a .text relative address too, which gives the wrong
result.

The underlying problem is that we don't distinguish between plain
numbers and absolute addresses once values are stored in symbols.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-17  0:06                         ` Alan Modra
@ 2010-12-17  4:17                           ` H.J. Lu
  2010-12-17 19:55                             ` H.J. Lu
  0 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2010-12-17  4:17 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

[-- Attachment #1: Type: text/plain, Size: 1960 bytes --]

On Thu, Dec 16, 2010 at 4:01 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 03:14:38PM -0800, H.J. Lu wrote:
>> Your patch doesn't work. I got
>>
>> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
>>
>> due to arch/x86/kernel/vmlinux.lds:
>>
>> ----
>> /*
>>  * Build-time check on the image size:
>>  */
>> . = ASSERT((_end - _text <= (512 * 1024 * 1024)),
>>     "kernel image bigger than KERNEL_IMAGE_SIZE");
>
> Extracting the relevant parts from the kernel link script:
>
> SECTIONS
> {
>  . = 0xc000;
>  .text :
>  {
>    _text = .;
>    *(.text)
>  }
>  _end = .;
> }
> ASSERT (_end - _text <= 0x100, "fail");
>
> You'd think that under the new rules, this ought to work.  "_end" is
> an absolute address, so when evaluating "_end - _text", "_text" ought
> to be converted from relative to absolute, the subtraction resuling in
> an absolute address.  Then 0x100 gets converted from a number to
> absolute address before being compared.
>
> The trouble is that "_end" is *not* treated as an absolute address but
> as a plain number.  That makes ld convert "_end" to a .text relative
> address when evaluation "_end - _text", which doesn't cause a problem
> at that stage, but the result is a relative address.  That means 0x100
> is converted to a .text relative address too, which gives the wrong
> result.
>
> The underlying problem is that we don't distinguish between plain
> numbers and absolute addresses once values are stored in symbols.
>

I am putting this into the Linux binutils.


-- 
H.J.
---
ld/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
	absolute.

ld/testsuite/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.

[-- Attachment #2: binutils-pr12327-1.patch --]
[-- Type: text/plain, Size: 2845 bytes --]

ld/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
	absolute.

ld/testsuite/

2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.

diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..c8fa331 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -691,12 +691,15 @@ fold_name (etree_type *tree)
 static void
 exp_fold_tree_1 (etree_type *tree)
 {
+  bfd_boolean absolute;
+
   if (tree == NULL)
     {
       memset (&expld.result, 0, sizeof (expld.result));
       return;
     }
 
+  absolute = TRUE;
   switch (tree->type.node_class)
     {
     case etree_value:
@@ -851,6 +854,21 @@ exp_fold_tree_1 (etree_type *tree)
 
     case etree_name:
       fold_name (tree);
+      if (tree->name.name
+	  && tree->name.name[0] != '.'
+	  && tree->name.name[1] != '\0'
+	  && link_info.hash)
+	{
+	  struct bfd_link_hash_entry *h;
+
+	  /* Only make absolute symbol value absolute.  */
+	  h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+				    FALSE, FALSE, TRUE);
+	  if (h
+	      && (h->type == bfd_link_hash_defined
+		  || h->type == bfd_link_hash_defweak))
+	    absolute = (h->u.def.section == bfd_abs_section_ptr);
+	}
       break;
 
     default:
@@ -861,7 +879,8 @@ exp_fold_tree_1 (etree_type *tree)
 
   /* Any value not inside an output section statement is an
      absolute value.  */
-  if (expld.result.valid_p
+  if (absolute
+      && expld.result.valid_p
       && expld.section == bfd_abs_section_ptr)
     make_abs ();
 }
diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp
index 15cc079..5742ae9 100644
--- a/ld/testsuite/ld-scripts/defined.exp
+++ b/ld/testsuite/ld-scripts/defined.exp
@@ -66,4 +66,5 @@ if ![ld_simple_link $ld tmpdir/def "$LDFLAGS -T $srcdir/$subdir/defined.t tmpdir
 set prms_id 0
 run_dump_test "defined2"
 run_dump_test "defined3"
+run_dump_test "defined4"
 set LDFLAGS "$saved_LDFLAGS"
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.d	2010-12-16 14:00:46.264217155 -0800
@@ -0,0 +1,10 @@
+#ld: -Tdefined4.t
+#nm: -B
+#source: defined4.s
+
+# Check that arithmetic on DEFINED works.
+#...
+0+0 D defined
+#...
+0+0 D defined1
+#pass
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.s	2010-12-16 12:46:23.558273203 -0800
@@ -0,0 +1,4 @@
+	.globl	defined
+	.data
+defined:
+	.word 0
--- /dev/null	2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.t	2010-12-16 12:46:45.236797081 -0800
@@ -0,0 +1,6 @@
+SECTIONS {
+	.text : { *(.text) }
+	.data : { *(.data) }
+	.bss : { *(.bss) *(COMMON) }
+}
+defined1 = defined;

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-17  4:17                           ` H.J. Lu
@ 2010-12-17 19:55                             ` H.J. Lu
  2010-12-20 13:04                               ` Alan Modra
  2010-12-20 15:25                               ` Alan Modra
  0 siblings, 2 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-17 19:55 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]

On Thu, Dec 16, 2010 at 4:06 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 4:01 PM, Alan Modra <amodra@gmail.com> wrote:
>> On Thu, Dec 16, 2010 at 03:14:38PM -0800, H.J. Lu wrote:
>>> Your patch doesn't work. I got
>>>
>>> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
>>>
>>> due to arch/x86/kernel/vmlinux.lds:
>>>
>>> ----
>>> /*
>>>  * Build-time check on the image size:
>>>  */
>>> . = ASSERT((_end - _text <= (512 * 1024 * 1024)),
>>>     "kernel image bigger than KERNEL_IMAGE_SIZE");
>>
>> Extracting the relevant parts from the kernel link script:
>>
>> SECTIONS
>> {
>>  . = 0xc000;
>>  .text :
>>  {
>>    _text = .;
>>    *(.text)
>>  }
>>  _end = .;
>> }
>> ASSERT (_end - _text <= 0x100, "fail");
>>
>> You'd think that under the new rules, this ought to work.  "_end" is
>> an absolute address, so when evaluating "_end - _text", "_text" ought
>> to be converted from relative to absolute, the subtraction resuling in
>> an absolute address.  Then 0x100 gets converted from a number to
>> absolute address before being compared.
>>
>> The trouble is that "_end" is *not* treated as an absolute address but
>> as a plain number.  That makes ld convert "_end" to a .text relative
>> address when evaluation "_end - _text", which doesn't cause a problem
>> at that stage, but the result is a relative address.  That means 0x100
>> is converted to a .text relative address too, which gives the wrong
>> result.
>>
>> The underlying problem is that we don't distinguish between plain
>> numbers and absolute addresses once values are stored in symbols.
>>
>
> I am putting this into the Linux binutils.
>
>
> --
> H.J.
> ---
> ld/
>
> 2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR ld/12327
>        * ldexp.c (exp_fold_tree_1): Only make absolute symbol value
>        absolute.
>
> ld/testsuite/
>
> 2010-12-16  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR ld/12327
>        * ld-scripts/defined.exp: Run defined4.
>
>        * ld-scripts/defined4.d: New.
>        * ld-scripts/defined4.s: Likewise.
>        * ld-scripts/defined4.t: Likewise.
>

The updated patch with a new testcase.

-- 
H.J.
---
ld/

2010-12-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
	absolute.

ld/testsuite/

2010-12-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.
	* ld-scripts/expr2.d: Likewise.
	* ld-scripts/expr2.s: Likewise.
	* ld-scripts/expr2.t: Likewise.

	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/expr.exp: Run expr2.

[-- Attachment #2: binutils-pr12327-2.patch --]
[-- Type: text/plain, Size: 4750 bytes --]

ld/

2010-12-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
	absolute.

ld/testsuite/

2010-12-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/12327
	* ld-scripts/defined4.d: New.
	* ld-scripts/defined4.s: Likewise.
	* ld-scripts/defined4.t: Likewise.
	* ld-scripts/expr2.d: Likewise.
	* ld-scripts/expr2.s: Likewise.
	* ld-scripts/expr2.t: Likewise.

	* ld-scripts/defined.exp: Run defined4.

	* ld-scripts/expr.exp: Run expr2.

diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..c8fa331 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -691,12 +691,15 @@ fold_name (etree_type *tree)
 static void
 exp_fold_tree_1 (etree_type *tree)
 {
+  bfd_boolean absolute;
+
   if (tree == NULL)
     {
       memset (&expld.result, 0, sizeof (expld.result));
       return;
     }
 
+  absolute = TRUE;
   switch (tree->type.node_class)
     {
     case etree_value:
@@ -851,6 +854,21 @@ exp_fold_tree_1 (etree_type *tree)
 
     case etree_name:
       fold_name (tree);
+      if (tree->name.name
+	  && tree->name.name[0] != '.'
+	  && tree->name.name[1] != '\0'
+	  && link_info.hash)
+	{
+	  struct bfd_link_hash_entry *h;
+
+	  /* Only make absolute symbol value absolute.  */
+	  h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+				    FALSE, FALSE, TRUE);
+	  if (h
+	      && (h->type == bfd_link_hash_defined
+		  || h->type == bfd_link_hash_defweak))
+	    absolute = (h->u.def.section == bfd_abs_section_ptr);
+	}
       break;
 
     default:
@@ -861,7 +879,8 @@ exp_fold_tree_1 (etree_type *tree)
 
   /* Any value not inside an output section statement is an
      absolute value.  */
-  if (expld.result.valid_p
+  if (absolute
+      && expld.result.valid_p
       && expld.section == bfd_abs_section_ptr)
     make_abs ();
 }
diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp
index 15cc079..6d0c9d5 100644
--- a/ld/testsuite/ld-scripts/defined.exp
+++ b/ld/testsuite/ld-scripts/defined.exp
@@ -1,6 +1,6 @@
 # Test DEFINED in a linker script.
 # By Ian Lance Taylor, Cygnus Support.
-#   Copyright 2001, 2003. 2005, 2006, 2007
+#   Copyright 2001, 2003, 2005, 2006, 2007, 2010
 #   Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
@@ -66,4 +66,5 @@ if ![ld_simple_link $ld tmpdir/def "$LDFLAGS -T $srcdir/$subdir/defined.t tmpdir
 set prms_id 0
 run_dump_test "defined2"
 run_dump_test "defined3"
+run_dump_test "defined4"
 set LDFLAGS "$saved_LDFLAGS"
diff --git a/ld/testsuite/ld-scripts/defined4.d b/ld/testsuite/ld-scripts/defined4.d
new file mode 100644
index 0000000..2c3a6ea
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined4.d
@@ -0,0 +1,10 @@
+#ld: -Tdefined4.t
+#nm: -B
+#source: defined4.s
+
+# Check that arithmetic on DEFINED works.
+#...
+0+0 D defined
+#...
+0+0 D defined1
+#pass
diff --git a/ld/testsuite/ld-scripts/defined4.s b/ld/testsuite/ld-scripts/defined4.s
new file mode 100644
index 0000000..5969a44
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined4.s
@@ -0,0 +1,4 @@
+	.globl	defined
+	.data
+defined:
+	.word 0
diff --git a/ld/testsuite/ld-scripts/defined4.t b/ld/testsuite/ld-scripts/defined4.t
new file mode 100644
index 0000000..1221df2
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined4.t
@@ -0,0 +1,6 @@
+SECTIONS {
+	.text : { *(.text) }
+	.data : { *(.data) }
+	.bss : { *(.bss) *(COMMON) }
+}
+defined1 = defined;
diff --git a/ld/testsuite/ld-scripts/expr.exp b/ld/testsuite/ld-scripts/expr.exp
index 34829e5..467abcb 100644
--- a/ld/testsuite/ld-scripts/expr.exp
+++ b/ld/testsuite/ld-scripts/expr.exp
@@ -1,6 +1,6 @@
-# Test ALIGN in a linker script.
+# Test expressions in a linker script.
 # By Nathan Sidwell, CodeSourcery LLC
-#   Copyright 2006, 2007
+#   Copyright 2006, 2007, 2010
 #   Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
@@ -21,3 +21,4 @@
 # MA 02110-1301, USA.
 
 run_dump_test expr1
+run_dump_test expr2
diff --git a/ld/testsuite/ld-scripts/expr2.d b/ld/testsuite/ld-scripts/expr2.d
new file mode 100644
index 0000000..6f7e253
--- /dev/null
+++ b/ld/testsuite/ld-scripts/expr2.d
@@ -0,0 +1,6 @@
+# ld: -T expr2.t
+#nm: -B
+
+#...
+.* D defined
+#pass
diff --git a/ld/testsuite/ld-scripts/expr2.s b/ld/testsuite/ld-scripts/expr2.s
new file mode 100644
index 0000000..5969a44
--- /dev/null
+++ b/ld/testsuite/ld-scripts/expr2.s
@@ -0,0 +1,4 @@
+	.globl	defined
+	.data
+defined:
+	.word 0
diff --git a/ld/testsuite/ld-scripts/expr2.t b/ld/testsuite/ld-scripts/expr2.t
new file mode 100644
index 0000000..634eab2
--- /dev/null
+++ b/ld/testsuite/ld-scripts/expr2.t
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  . = 0xc000;
+  .text :
+  {
+    _text = .;
+    *(.text)
+  }
+  _end = .;
+}
+ASSERT (_end - _text <= 0x100, "fail");

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-17 19:55                             ` H.J. Lu
@ 2010-12-20 13:04                               ` Alan Modra
  2010-12-21 16:15                                 ` Daniel Jacobowitz
                                                   ` (2 more replies)
  2010-12-20 15:25                               ` Alan Modra
  1 sibling, 3 replies; 48+ messages in thread
From: Alan Modra @ 2010-12-20 13:04 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Fri, Dec 17, 2010 at 11:41:40AM -0800, H.J. Lu wrote:
> The updated patch with a new testcase.

I think this is a better solution, works on current binutils testsuite,
the testcases in PR12066, and on kernel builds I tried.  You can
even describe linker behaviour without too much embarassment.

I added an option to allow people to experiment with a consistent
linker expression resolver by setting
  __ld_compatibility = 221 ;
somewhere in their linker scripts.  This treats numbers and absolute
symbols as numbers everywhere, the most flexible arrangement since
you can force a number to be an absolute address by using ABSOLUTE(),
but you can't do the reverse.

	* ld.texinfo (Expression Section): Describe treatment of numbers
	and absolute symbols.
	* ldemul.c (after_open_default): Look up __ld_compatibility.
	* ldexp.c (fold_name): Convert absolute symbols to numbers when
	inside output section definitions, or when __ld_compatibility >= 221.
	(exp_fold_tree_1): Convert numbers to absolute when not in output
	section definition and __ld_compatibility < 221.  Don't always
	convert values outside an output section definition to absolute.
	* ldexp.h (uses_defined): Comment.
	* ldlang.c (ld_compatibility): New variable.
	* ldlang.h (ld_compatibility): Declare.
	* emultempl/aix.em, * emultempl/armcoff.em, * emultempl/beos.em,
	* emultempl/elf32.em, * emultempl/genelf.em, * emultempl/lnk960.em,
	* emultempl/m68kcoff.em, * emultempl/mmo.em, * emultempl/pe.em,
	* emultempl/pep.em, * emultempl/sunos.em, * emultempl/z80.em: Call
	after_open_default from after_open function.

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.268
diff -u -p -r1.268 ld.texinfo
--- ld/ld.texinfo	15 Dec 2010 14:56:37 -0000	1.268
+++ ld/ld.texinfo	20 Dec 2010 06:35:30 -0000
@@ -5503,17 +5503,17 @@ section relative symbols and for builtin
 address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and
 @code{SEGMENT_START}.  Other terms are simply numbers, or are builtin
 functions that return a non-address value, such as @code{LENGTH}.
+One complication is that unless you assign @code{__ld_compatibility}
+a value of 221 or larger, numbers and absolute symbols are treated
+differently depending on their location, for compatibility with older
+versions of @code{ld}.  Expressions appearing outside an output
+section definition treat all numbers as absolute addresses.
+Expressions appearing inside an output section definition treat
+absolute symbols as numbers.  If @code{__ld_compatibility} is assigned
+a value larger than 221, then absolute symbols and numbers are simply
+treated as numbers everywhere.
 
-When the linker evaluates an expression, the result depends on where
-the expression is located in a linker script.  Expressions appearing
-outside an output section definitions are evaluated with all terms
-first being converted to absolute addresses before applying operators,
-and evaluate to an absolute address result.  Expressions appearing
-inside an output section definition are evaluated with more complex
-rules, but the aim is to treat terms as relative addresses and produce
-a relative address result.  In particular, an assignment of a number
-to a symbol results in a symbol relative to the output section with an
-offset given by the number.  So, in the following simple example,
+In the following simple example,
 
 @smallexample
 @group
@@ -5537,9 +5537,8 @@ address 0x100 in the first two assignmen
 @code{__data_start} are set to 0x10 relative to the @code{.data}
 section in the second two assignments.
 
-For expressions appearing inside an output section definition
-involving numbers, relative addresses and absolute addresses, ld
-follows these rules to evaluate terms:
+For expressions involving numbers, relative addresses and absolute
+addresses, ld follows these rules to evaluate terms:
 
 @itemize @bullet
 @item
Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.34
diff -u -p -r1.34 ldemul.c
--- ld/ldemul.c	28 Oct 2010 06:45:33 -0000	1.34
+++ ld/ldemul.c	20 Dec 2010 06:35:30 -0000
@@ -226,6 +226,16 @@ after_parse_default (void)
 void
 after_open_default (void)
 {
+  struct bfd_link_hash_entry *h;
+
+  h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+				    &link_info,
+				    "__ld_compatibility",
+				    FALSE, FALSE, TRUE);
+  if (h != NULL
+      && (h->type == bfd_link_hash_defined
+	  || h->type == bfd_link_hash_defweak))
+    ld_compatibility = h->u.def.value;
 }
 
 void
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.88
diff -u -p -r1.88 ldexp.c
--- ld/ldexp.c	20 Dec 2010 06:27:10 -0000	1.88
+++ ld/ldexp.c	20 Dec 2010 06:35:31 -0000
@@ -553,7 +553,9 @@ fold_name (etree_type *tree)
 			     " referenced in expression\n"),
 			   tree->name.name);
 		}
-	      else if (output_section == bfd_abs_section_ptr)
+	      else if (output_section == bfd_abs_section_ptr
+		       && (expld.section != bfd_abs_section_ptr
+			   || ld_compatibility >= 221))
 		new_number (h->u.def.value + h->u.def.section->output_offset);
 	      else
 		new_rel (h->u.def.value + h->u.def.section->output_offset,
@@ -700,7 +702,11 @@ exp_fold_tree_1 (etree_type *tree)
   switch (tree->type.node_class)
     {
     case etree_value:
-      new_number (tree->value.value);
+      if (expld.section == bfd_abs_section_ptr
+	  && ld_compatibility < 221)
+	new_abs (tree->value.value);
+      else
+	new_number (tree->value.value);
       expld.result.str = tree->value.str;
       break;
 
@@ -860,12 +866,6 @@ exp_fold_tree_1 (etree_type *tree)
       memset (&expld.result, 0, sizeof (expld.result));
       break;
     }
-
-  /* Any value not inside an output section statement is an
-     absolute value.  */
-  if (expld.result.valid_p
-      && expld.section == bfd_abs_section_ptr)
-    make_abs ();
 }
 
 void
Index: ld/ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.24
diff -u -p -r1.24 ldexp.h
--- ld/ldexp.h	20 Dec 2010 06:27:10 -0000	1.24
+++ ld/ldexp.h	20 Dec 2010 06:35:31 -0000
@@ -127,6 +127,7 @@ struct ldexp_control {
   /* Working results.  */
   etree_value_type result;
   bfd_vma dot;
+  /* Set if an expression contains DEFINED().  */
   bfd_boolean uses_defined;
 
   /* Current dot and section passed to ldexp folder.  */
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.354
diff -u -p -r1.354 ldlang.c
--- ld/ldlang.c	20 Dec 2010 06:27:10 -0000	1.354
+++ ld/ldlang.c	20 Dec 2010 06:35:34 -0000
@@ -109,6 +109,7 @@ bfd_boolean delete_output_file_on_failur
 struct lang_phdr *lang_phdr_list;
 struct lang_nocrossrefs *nocrossref_list;
 bfd_boolean missing_file = FALSE;
+int ld_compatibility;
 
  /* Functions that traverse the linker script and might evaluate
     DEFINED() need to increment this.  */
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.92
diff -u -p -r1.92 ldlang.h
--- ld/ldlang.h	6 Dec 2010 00:07:06 -0000	1.92
+++ ld/ldlang.h	20 Dec 2010 06:35:34 -0000
@@ -469,6 +469,7 @@ extern bfd_boolean entry_from_cmdline;
 extern lang_statement_list_type file_chain;
 extern lang_statement_list_type input_file_chain;
 
+extern int ld_compatibility;
 extern int lang_statement_iteration;
 extern bfd_boolean missing_file;
 
Index: ld/emultempl/aix.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/aix.em,v
retrieving revision 1.56
diff -u -p -r1.56 aix.em
--- ld/emultempl/aix.em	6 Dec 2010 00:07:06 -0000	1.56
+++ ld/emultempl/aix.em	20 Dec 2010 06:35:35 -0000
@@ -608,6 +608,8 @@ gld${EMULATION_NAME}_after_open (void)
   bfd_boolean r;
   struct set_info *p;
 
+  after_open_default ();
+
   /* Call ldctor_build_sets, after pretending that this is a
      relocatable link.  We do this because AIX requires relocation
      entries for all references to symbols, even in a final
Index: ld/emultempl/armcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armcoff.em,v
retrieving revision 1.31
diff -u -p -r1.31 armcoff.em
--- ld/emultempl/armcoff.em	2 Sep 2009 07:25:35 -0000	1.31
+++ ld/emultempl/armcoff.em	20 Dec 2010 06:35:35 -0000
@@ -133,6 +133,8 @@ gld${EMULATION_NAME}_before_allocation (
 static void
 gld${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
   if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
     {
       /* The arm backend needs special fields in the output hash structure.
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.44
diff -u -p -r1.44 beos.em
--- ld/emultempl/beos.em	16 Feb 2009 07:25:52 -0000	1.44
+++ ld/emultempl/beos.em	20 Dec 2010 06:35:36 -0000
@@ -376,6 +376,8 @@ gld_${EMULATION_NAME}_set_symbols (void)
 static void
 gld_${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
   /* Pass the wacky PE command line options into the output bfd.
      FIXME: This should be done via a function, rather than by
      including an internal BFD header.  */
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.215
diff -u -p -r1.215 elf32.em
--- ld/emultempl/elf32.em	6 Dec 2010 00:07:06 -0000	1.215
+++ ld/emultempl/elf32.em	20 Dec 2010 06:35:37 -0000
@@ -1059,6 +1059,8 @@ gld${EMULATION_NAME}_after_open (void)
   struct bfd_link_needed_list *needed, *l;
   struct elf_link_hash_table *htab;
 
+  after_open_default ();
+
   htab = elf_hash_table (&link_info);
   if (!is_elf_hash_table (htab))
     return;
Index: ld/emultempl/genelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/genelf.em,v
retrieving revision 1.7
diff -u -p -r1.7 genelf.em
--- ld/emultempl/genelf.em	19 Feb 2010 01:47:14 -0000	1.7
+++ ld/emultempl/genelf.em	20 Dec 2010 06:35:37 -0000
@@ -35,6 +35,8 @@ gld${EMULATION_NAME}_after_open (void)
   asection *sec;
   asymbol **syms;
 
+  after_open_default ();
+
   if (link_info.relocatable)
     for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
       if ((syms = bfd_get_outsymbols (ibfd)) != NULL
Index: ld/emultempl/lnk960.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/lnk960.em,v
retrieving revision 1.25
diff -u -p -r1.25 lnk960.em
--- ld/emultempl/lnk960.em	15 Feb 2008 03:35:53 -0000	1.25
+++ ld/emultempl/lnk960.em	20 Dec 2010 06:35:37 -0000
@@ -265,7 +265,7 @@ struct ld_emulation_xfer_struct ld_lnk96
   lnk960_syslib,
   lnk960_hll,
   lnk960_after_parse,
-  NULL,			/* after_open */
+  after_open_default,
   lnk960_after_allocation,
   lnk960_set_output_arch,
   lnk960_choose_target,
Index: ld/emultempl/m68kcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/m68kcoff.em,v
retrieving revision 1.20
diff -u -p -r1.20 m68kcoff.em
--- ld/emultempl/m68kcoff.em	7 Jul 2008 00:46:51 -0000	1.20
+++ ld/emultempl/m68kcoff.em	20 Dec 2010 06:35:37 -0000
@@ -62,6 +62,8 @@ gld${EMULATION_NAME}_after_open (void)
 {
   bfd *abfd;
 
+  after_open_default ();
+
   if (! command_line.embedded_relocs
       || link_info.relocatable)
     return;
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.26
diff -u -p -r1.26 mmo.em
--- ld/emultempl/mmo.em	2 Sep 2009 07:25:35 -0000	1.26
+++ ld/emultempl/mmo.em	20 Dec 2010 06:35:37 -0000
@@ -151,6 +151,7 @@ mmo_after_open (void)
 		   is->the_bfd);
 	}
     }
+  after_open_default ();
 }
 EOF
 
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.164
diff -u -p -r1.164 pe.em
--- ld/emultempl/pe.em	6 Dec 2010 00:07:06 -0000	1.164
+++ ld/emultempl/pe.em	20 Dec 2010 06:35:38 -0000
@@ -1219,6 +1219,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNU
 static void
 gld_${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
 #ifdef DLL_SUPPORT
   if (pe_dll_extra_pe_debug)
     {
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.40
diff -u -p -r1.40 pep.em
--- ld/emultempl/pep.em	6 Dec 2010 00:07:06 -0000	1.40
+++ ld/emultempl/pep.em	20 Dec 2010 06:35:39 -0000
@@ -1151,6 +1151,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNU
 static void
 gld_${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
   is_underscoring ();
 #ifdef DLL_SUPPORT
   if (pep_dll_extra_pe_debug)
Index: ld/emultempl/sunos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sunos.em,v
retrieving revision 1.32
diff -u -p -r1.32 sunos.em
--- ld/emultempl/sunos.em	6 Dec 2010 00:07:06 -0000	1.32
+++ ld/emultempl/sunos.em	20 Dec 2010 06:35:40 -0000
@@ -366,6 +366,8 @@ gld${EMULATION_NAME}_after_open (void)
 {
   struct bfd_link_needed_list *needed, *l;
 
+  after_open_default ();
+
   /* We only need to worry about this when doing a final link.  */
   if (link_info.relocatable || link_info.shared)
     return;
Index: ld/emultempl/z80.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/z80.em,v
retrieving revision 1.5
diff -u -p -r1.5 z80.em
--- ld/emultempl/z80.em	2 Sep 2009 07:25:35 -0000	1.5
+++ ld/emultempl/z80.em	20 Dec 2010 06:35:40 -0000
@@ -79,6 +79,8 @@ gldz80_after_open (void)
 {
   unsigned long mach_type;
 
+  after_open_default ();
+
   switch (result_mach_type)
     {
     case M_Z80STRICT:

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-17 19:55                             ` H.J. Lu
  2010-12-20 13:04                               ` Alan Modra
@ 2010-12-20 15:25                               ` Alan Modra
  1 sibling, 0 replies; 48+ messages in thread
From: Alan Modra @ 2010-12-20 15:25 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Daniel Jacobowitz, binutils, Kazu Hirata

On Fri, Dec 17, 2010 at 11:41:40AM -0800, H.J. Lu wrote:
> 	PR ld/12327
> 	* ld-scripts/defined4.d: New.
> 	* ld-scripts/defined4.s: Likewise.
> 	* ld-scripts/defined4.t: Likewise.
> 	* ld-scripts/expr2.d: Likewise.
> 	* ld-scripts/expr2.s: Likewise.
> 	* ld-scripts/expr2.t: Likewise.
> 
> 	* ld-scripts/defined.exp: Run defined4.
> 
> 	* ld-scripts/expr.exp: Run expr2.

This part is OK.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-20 13:04                               ` Alan Modra
@ 2010-12-21 16:15                                 ` Daniel Jacobowitz
  2010-12-22  3:31                                   ` Alan Modra
  2010-12-28 11:37                                 ` H.J. Lu
  2011-01-19  6:49                                 ` Maciej W. Rozycki
  2 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-12-21 16:15 UTC (permalink / raw)
  To: H.J. Lu, binutils, Kazu Hirata

On Mon, Dec 20, 2010 at 11:29:09PM +1030, Alan Modra wrote:
> On Fri, Dec 17, 2010 at 11:41:40AM -0800, H.J. Lu wrote:
> > The updated patch with a new testcase.
> 
> I think this is a better solution, works on current binutils testsuite,
> the testcases in PR12066, and on kernel builds I tried.  You can
> even describe linker behaviour without too much embarassment.
> 
> I added an option to allow people to experiment with a consistent
> linker expression resolver by setting
>   __ld_compatibility = 221 ;
> somewhere in their linker scripts.  This treats numbers and absolute
> symbols as numbers everywhere, the most flexible arrangement since
> you can force a number to be an absolute address by using ABSOLUTE(),
> but you can't do the reverse.

I'd use a new syntax for setting the compatibility version, because
if a program relies on the new behavior, then the linker script ought
to be rejected by an old linker.

I have a wee bit of fear in maintaining more than one version...

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-21 16:15                                 ` Daniel Jacobowitz
@ 2010-12-22  3:31                                   ` Alan Modra
  2010-12-22 12:22                                     ` Daniel Jacobowitz
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2010-12-22  3:31 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: H.J. Lu, binutils, Kazu Hirata

On Tue, Dec 21, 2010 at 11:05:36AM -0500, Daniel Jacobowitz wrote:
> I'd use a new syntax for setting the compatibility version, because
> if a program relies on the new behavior, then the linker script ought
> to be rejected by an old linker.

I chose to use a symbol so that an old linker *could* use the script.
At least with relatively simple scripts it should be possible to write
a script that works with both old and new rules.  For example, instead
of

SECTIONS
{
  . = 0xc000;
  .text :
  {
    *(.hdr);
    _text = .;
    *(.text)
  }
ASSERT (_text == 0xc000+0x100, "header wrong size!");
}

write the ASSERT as
ASSERT (ABSOLUTE(_text) == 0xc000+0x100, "header wrong size!");


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-22  3:31                                   ` Alan Modra
@ 2010-12-22 12:22                                     ` Daniel Jacobowitz
  2010-12-24  9:27                                       ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Daniel Jacobowitz @ 2010-12-22 12:22 UTC (permalink / raw)
  To: Alan Modra; +Cc: H.J. Lu, binutils, Kazu Hirata

On Wed, Dec 22, 2010 at 11:42:58AM +1030, Alan Modra wrote:
> On Tue, Dec 21, 2010 at 11:05:36AM -0500, Daniel Jacobowitz wrote:
> > I'd use a new syntax for setting the compatibility version, because
> > if a program relies on the new behavior, then the linker script ought
> > to be rejected by an old linker.
> 
> I chose to use a symbol so that an old linker *could* use the script.
> At least with relatively simple scripts it should be possible to write
> a script that works with both old and new rules.

Don't these two statements go in opposite directions?  If you're going
to bother to make the script work with both rules, then you don't need
to request the new behavior.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-22 12:22                                     ` Daniel Jacobowitz
@ 2010-12-24  9:27                                       ` Alan Modra
  0 siblings, 0 replies; 48+ messages in thread
From: Alan Modra @ 2010-12-24  9:27 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: H.J. Lu, binutils, Kazu Hirata

On Tue, Dec 21, 2010 at 10:31:33PM -0500, Daniel Jacobowitz wrote:
> On Wed, Dec 22, 2010 at 11:42:58AM +1030, Alan Modra wrote:
> > On Tue, Dec 21, 2010 at 11:05:36AM -0500, Daniel Jacobowitz wrote:
> > > I'd use a new syntax for setting the compatibility version, because
> > > if a program relies on the new behavior, then the linker script ought
> > > to be rejected by an old linker.
> > 
> > I chose to use a symbol so that an old linker *could* use the script.
> > At least with relatively simple scripts it should be possible to write
> > a script that works with both old and new rules.
> 
> Don't these two statements go in opposite directions?  If you're going
> to bother to make the script work with both rules, then you don't need
> to request the new behavior.

You're probably right.  I just wanted to make the feature easy to use
in the hope that people would tidy their old scripts, but I guess that
isn't so likely.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-20 13:04                               ` Alan Modra
  2010-12-21 16:15                                 ` Daniel Jacobowitz
@ 2010-12-28 11:37                                 ` H.J. Lu
  2011-01-19  6:49                                 ` Maciej W. Rozycki
  2 siblings, 0 replies; 48+ messages in thread
From: H.J. Lu @ 2010-12-28 11:37 UTC (permalink / raw)
  To: Daniel Jacobowitz, binutils, Kazu Hirata

On Mon, Dec 20, 2010 at 4:59 AM, Alan Modra <amodra@gmail.com> wrote:
> On Fri, Dec 17, 2010 at 11:41:40AM -0800, H.J. Lu wrote:
>> The updated patch with a new testcase.
>
> I think this is a better solution, works on current binutils testsuite,
> the testcases in PR12066, and on kernel builds I tried.  You can
> even describe linker behaviour without too much embarassment.
>
> I added an option to allow people to experiment with a consistent
> linker expression resolver by setting
>  __ld_compatibility = 221 ;
> somewhere in their linker scripts.  This treats numbers and absolute
> symbols as numbers everywhere, the most flexible arrangement since
> you can force a number to be an absolute address by using ABSOLUTE(),
> but you can't do the reverse.
>
>        * ld.texinfo (Expression Section): Describe treatment of numbers
>        and absolute symbols.
>        * ldemul.c (after_open_default): Look up __ld_compatibility.
>        * ldexp.c (fold_name): Convert absolute symbols to numbers when
>        inside output section definitions, or when __ld_compatibility >= 221.
>        (exp_fold_tree_1): Convert numbers to absolute when not in output
>        section definition and __ld_compatibility < 221.  Don't always
>        convert values outside an output section definition to absolute.
>        * ldexp.h (uses_defined): Comment.
>        * ldlang.c (ld_compatibility): New variable.
>        * ldlang.h (ld_compatibility): Declare.
>        * emultempl/aix.em, * emultempl/armcoff.em, * emultempl/beos.em,
>        * emultempl/elf32.em, * emultempl/genelf.em, * emultempl/lnk960.em,
>        * emultempl/m68kcoff.em, * emultempl/mmo.em, * emultempl/pe.em,
>        * emultempl/pep.em, * emultempl/sunos.em, * emultempl/z80.em: Call
>        after_open_default from after_open function.
>

I am not sure how useful "__ld_compatibility" will be. I don't think we
should change the behaviors of known linker scripts. Those failure
caused by changing behaviors of linker scripts may be hard to debug.
In some cases, changing linker scripts, which have been used for
years, may not be a viable option.


-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2010-12-20 13:04                               ` Alan Modra
  2010-12-21 16:15                                 ` Daniel Jacobowitz
  2010-12-28 11:37                                 ` H.J. Lu
@ 2011-01-19  6:49                                 ` Maciej W. Rozycki
  2011-01-19  8:25                                   ` Alan Modra
  2 siblings, 1 reply; 48+ messages in thread
From: Maciej W. Rozycki @ 2011-01-19  6:49 UTC (permalink / raw)
  To: Alan Modra; +Cc: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

On Mon, 20 Dec 2010, Alan Modra wrote:

> I think this is a better solution, works on current binutils testsuite,
> the testcases in PR12066, and on kernel builds I tried.  You can
> even describe linker behaviour without too much embarassment.
> 
> I added an option to allow people to experiment with a consistent
> linker expression resolver by setting
>   __ld_compatibility = 221 ;
> somewhere in their linker scripts.  This treats numbers and absolute
> symbols as numbers everywhere, the most flexible arrangement since
> you can force a number to be an absolute address by using ABSOLUTE(),
> but you can't do the reverse.
> 
> 	* ld.texinfo (Expression Section): Describe treatment of numbers
> 	and absolute symbols.
> 	* ldemul.c (after_open_default): Look up __ld_compatibility.
> 	* ldexp.c (fold_name): Convert absolute symbols to numbers when
> 	inside output section definitions, or when __ld_compatibility >= 221.
> 	(exp_fold_tree_1): Convert numbers to absolute when not in output
> 	section definition and __ld_compatibility < 221.  Don't always
> 	convert values outside an output section definition to absolute.
> 	* ldexp.h (uses_defined): Comment.
> 	* ldlang.c (ld_compatibility): New variable.
> 	* ldlang.h (ld_compatibility): Declare.
> 	* emultempl/aix.em, * emultempl/armcoff.em, * emultempl/beos.em,
> 	* emultempl/elf32.em, * emultempl/genelf.em, * emultempl/lnk960.em,
> 	* emultempl/m68kcoff.em, * emultempl/mmo.em, * emultempl/pe.em,
> 	* emultempl/pep.em, * emultempl/sunos.em, * emultempl/z80.em: Call
> 	after_open_default from after_open function.

 This change broke the following case (ripped out of real-life code):

$ cat script.s # empty
$ cat script.ld
OUTPUT_ARCH(mips)
ENTRY(foobar)

MEMORY
{
  ram (rwx) : ORIGIN = 0x80000000 + 0x1000, LENGTH = 128M - 0x1000
}

PROVIDE(foobar = (bar - foo));

SECTIONS
{
  .rodata : ALIGN (4)
  {
    foo = .;
    LONG (0)
    LONG (1)
    LONG (2)
    LONG (3)
    LONG (4)
    LONG (5)
    bar = .;
  }
}
$ mips-sde-elf-as -o script.o script.s
$ mips-sde-elf-ld -efoobar -Tscript.ld -o script script.o

Before your change this correctly yielded the following symbols:

$ mips-sde-elf-objdump -t script

script:     file format elf32-tradbigmips

SYMBOL TABLE:
80001000 l    d  .rodata	00000000 .rodata
00000000 l    d  .reginfo	00000000 .reginfo
00000018 g       *ABS*	00000000 foobar
80001000 g       .rodata	00000000 foo
80001018 g       .rodata	00000000 bar

With your change in place it produces the following output:

$ mips-sde-elf-objdump -t script

script:     file format elf32-tradbigmips

SYMBOL TABLE:
80001000 l    d  .rodata	00000000 .rodata
00000000 l    d  .reginfo	00000000 .reginfo
80001018 g       .rodata	00000000 foobar
80001000 g       .rodata	00000000 foo
80001018 g       .rodata	00000000 bar

As you can see the subtraction operation was ignored together with the 
subtrahend (foo), and the minuend (bar) assigned to the symbol requested 
(foobar).

 Is that intended behaviour?  From your update to the manual I infer 
otherwise and it looks to me like a mishandled case that slipped through, 
but perhaps I'm missing something.  Either way I find it plain wrong that 
a difference of two symbols (both coming from/relative to the same 
section) yields a plain number in GAS, but not in an LD script.  Hmm...

  Maciej

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-19  6:49                                 ` Maciej W. Rozycki
@ 2011-01-19  8:25                                   ` Alan Modra
  2011-01-19 12:28                                     ` H.J. Lu
  2011-01-19 14:25                                     ` Ian Lance Taylor
  0 siblings, 2 replies; 48+ messages in thread
From: Alan Modra @ 2011-01-19  8:25 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

On Wed, Jan 19, 2011 at 06:48:51AM +0000, Maciej W. Rozycki wrote:
>  Is that intended behaviour?  From your update to the manual I infer 
> otherwise and it looks to me like a mishandled case that slipped through, 
> but perhaps I'm missing something.  Either way I find it plain wrong that 
> a difference of two symbols (both coming from/relative to the same 
> section) yields a plain number in GAS, but not in an LD script.  Hmm...

ld actually does follow the current ld.texinfo description.  The two
symbols are in the same section, so the operation (subtraction in this
case) is performed on their offsets, yielding a result in the same
section.

Admittedly, this does lead to an odd result.  Should we special case
subtraction?  Exclusive or too?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-19  8:25                                   ` Alan Modra
@ 2011-01-19 12:28                                     ` H.J. Lu
  2011-01-20 12:26                                       ` Alan Modra
  2011-01-19 14:25                                     ` Ian Lance Taylor
  1 sibling, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2011-01-19 12:28 UTC (permalink / raw)
  To: Maciej W. Rozycki, Daniel Jacobowitz, binutils, Kazu Hirata

On Wed, Jan 19, 2011 at 12:25 AM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Jan 19, 2011 at 06:48:51AM +0000, Maciej W. Rozycki wrote:
>>  Is that intended behaviour?  From your update to the manual I infer
>> otherwise and it looks to me like a mishandled case that slipped through,
>> but perhaps I'm missing something.  Either way I find it plain wrong that
>> a difference of two symbols (both coming from/relative to the same
>> section) yields a plain number in GAS, but not in an LD script.  Hmm...
>
> ld actually does follow the current ld.texinfo description.  The two
> symbols are in the same section, so the operation (subtraction in this
> case) is performed on their offsets, yielding a result in the same
> section.
>
> Admittedly, this does lead to an odd result.  Should we special case
> subtraction?  Exclusive or too?
>

I got a linker regression report on symbol subtraction on x86. I am waiting
for a testcase.


-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-19  8:25                                   ` Alan Modra
  2011-01-19 12:28                                     ` H.J. Lu
@ 2011-01-19 14:25                                     ` Ian Lance Taylor
  1 sibling, 0 replies; 48+ messages in thread
From: Ian Lance Taylor @ 2011-01-19 14:25 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

Alan Modra <amodra@gmail.com> writes:

> On Wed, Jan 19, 2011 at 06:48:51AM +0000, Maciej W. Rozycki wrote:
>>  Is that intended behaviour?  From your update to the manual I infer 
>> otherwise and it looks to me like a mishandled case that slipped through, 
>> but perhaps I'm missing something.  Either way I find it plain wrong that 
>> a difference of two symbols (both coming from/relative to the same 
>> section) yields a plain number in GAS, but not in an LD script.  Hmm...
>
> ld actually does follow the current ld.texinfo description.  The two
> symbols are in the same section, so the operation (subtraction in this
> case) is performed on their offsets, yielding a result in the same
> section.
>
> Admittedly, this does lead to an odd result.  Should we special case
> subtraction?  Exclusive or too?

The last time I worked through these issues I came up with the code in
expr() in gas/expr.c.  It makes subtraction of two symbols in the same
section be absolute, whereas of course subtracting a constant gives a
result in the same section.

Ian

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-19 12:28                                     ` H.J. Lu
@ 2011-01-20 12:26                                       ` Alan Modra
  2011-01-20 17:18                                         ` Maciej W. Rozycki
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2011-01-20 12:26 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Maciej W. Rozycki, Daniel Jacobowitz, binutils, Kazu Hirata

On Wed, Jan 19, 2011 at 04:27:53AM -0800, H.J. Lu wrote:
> On Wed, Jan 19, 2011 at 12:25 AM, Alan Modra <amodra@gmail.com> wrote:
> > On Wed, Jan 19, 2011 at 06:48:51AM +0000, Maciej W. Rozycki wrote:
> >>  Is that intended behaviour?  From your update to the manual I infer
> >> otherwise and it looks to me like a mishandled case that slipped through,
> >> but perhaps I'm missing something.  Either way I find it plain wrong that
> >> a difference of two symbols (both coming from/relative to the same
> >> section) yields a plain number in GAS, but not in an LD script.  Hmm...
> >
> > ld actually does follow the current ld.texinfo description.  The two
> > symbols are in the same section, so the operation (subtraction in this
> > case) is performed on their offsets, yielding a result in the same
> > section.
> >
> > Admittedly, this does lead to an odd result.  Should we special case
> > subtraction?  Exclusive or too?
> >
> 
> I got a linker regression report on symbol subtraction on x86. I am waiting
> for a testcase.

I'd like to see the testcase too.

I have two possible patches.  The first only changes subtraction and
xor of two symbols so that the result is simply a number, even if the
symbols are not in the same section.  That I think is the correct
result and uncontroversial.  However, this patch leaves (x + -y) with
a section, a result that differs now from (x - y).

The second patch changes all binary arithmetic and logical operations
on two symbols to always return a plain number, fixing the case above.
Unfortunately it does make some other subexpressions inconsistent.
For example, (2 * a) has section while (a + a) does not.  It's a toss
up which patch to choose.  Here's the second one.

	* 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/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	20 Jan 2011 03:42:26 -0000
@@ -335,11 +335,15 @@ 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;
+	      lhs.section = NULL;
+	    }
 	}
 
       switch (tree->type.node_code)
@@ -363,6 +367,8 @@ fold_binary (etree_type *tree)
 #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;
 
 #define BOPN(x, y) \
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.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-20 12:26                                       ` Alan Modra
@ 2011-01-20 17:18                                         ` Maciej W. Rozycki
  2011-01-21  4:02                                           ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Maciej W. Rozycki @ 2011-01-20 17:18 UTC (permalink / raw)
  To: Alan Modra; +Cc: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, 20 Jan 2011, Alan Modra wrote:

> > I got a linker regression report on symbol subtraction on x86. I am waiting
> > for a testcase.
> 
> I'd like to see the testcase too.
> 
> I have two possible patches.  The first only changes subtraction and
> xor of two symbols so that the result is simply a number, even if the
> symbols are not in the same section.  That I think is the correct
> result and uncontroversial.  However, this patch leaves (x + -y) with
> a section, a result that differs now from (x - y).

 Yes, that I find that natural actually.

 With this program:

$ cat sub.s
foo:
	.long	4
bar:
	.long	bar - foo
	.long	bar + -foo
	.long	bar ^ foo

I get this:

$ mips-linux-gnu-as -o sub.o sub.s
sub.s: Assembler messages:
sub.s:5: Error: invalid section for operation on `foo'
sub.s:6: Error: invalid sections for operation on `bar' and `foo'

so I'm happy with both the unary arithmetic negation and the XOR operator 
to return a result that is different to a binary subtraction (we don't 
have to fail as does GAS, at least on the final link).

 I've been looking through the thread (including the August part), trying 
to understand what the origin of your changes has been.  What has struck 
me is nobody proposed an approach that would be equivalent to what GAS 
(and to some extent C) expression evaluation is.

 My idea is to divide operands and operations into three classes:

1. Plain symbol references, possibly with an offset yield an expression
   relative to the symbol's section.  Examples:

   foo
   foo + 4
   foo - 2 - (3 * 5)
   -7 + foo

2. Plain numbers and any operations made on them plus subtraction of two 
   section-relative expressions (i.e. anything that falls into #1 above) 
   yield a plain number.  Examples:

   0
   3 + 7
   foo - bar
   bar - foo + 2
   (bar + 2) - foo
   (bar - 10) - (foo + (~4 ^ 12))

3. Anything else yields an absolute expression (I would see no problem if 
   it failed altogether on an incremental link, though I understand we 
   may not want to do this for compatibility reasons).  You can make it 
   section-relative again by adding it to a section-relative expression.  
   Examples:

   foo + bar
   -foo + bar
   2 * foo
   foo & 1
   foo ^ bar
   etc., etc...

(note that #1 and #2 are how pointer arithmetics works in C too).  This 
for example implies that:

   foo + foo + foo

and:

   foo + 2 * foo

are relative, but:

   3 * foo

is not.

 Does it make any sense to you or anybody?

 Thanks for your work on this issue.

  Maciej

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-20 17:18                                         ` Maciej W. Rozycki
@ 2011-01-21  4:02                                           ` Alan Modra
  2011-01-21 13:19                                             ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2011-01-21  4:02 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

On Thu, Jan 20, 2011 at 05:18:11PM +0000, Maciej W. Rozycki wrote:
>  I've been looking through the thread (including the August part), trying 
> to understand what the origin of your changes has been.

I started looking at a bug, and decided the old ld expression
evaluation code was just so inconsistent that it needed cleaning up.

> 1. Plain symbol references, possibly with an offset yield an expression
>    relative to the symbol's section.  Examples:
> 
>    foo
>    foo + 4
>    foo - 2 - (3 * 5)
>    -7 + foo

New expression code does this, except for compatibility with old ld we
return absolute section values if the expression is outside of an
output section statement.

Also of course, expressions like min(x,y), max(x,y), align(x,4) with x
and y in the same section should return a section relative result.

> 2. Plain numbers and any operations made on them plus subtraction of two 
>    section-relative expressions (i.e. anything that falls into #1 above) 
>    yield a plain number.  Examples:
> 
>    0
>    3 + 7
>    foo - bar
>    bar - foo + 2
>    (bar + 2) - foo
>    (bar - 10) - (foo + (~4 ^ 12))

With either of my fixes the new code will do this too.  Old ld code
will sometimes return section relative or absolute values.

> 3. Anything else yields an absolute expression (I would see no problem if 
>    it failed altogether on an incremental link, though I understand we 
>    may not want to do this for compatibility reasons).  You can make it 
>    section-relative again by adding it to a section-relative expression.  
>    Examples:
> 
>    foo + bar
>    -foo + bar
>    2 * foo
>    foo & 1
>    foo ^ bar
>    etc., etc...
> 
> (note that #1 and #2 are how pointer arithmetics works in C too).  This 
> for example implies that:
> 
>    foo + foo + foo
> 
> and:
> 
>    foo + 2 * foo
> 
> are relative, but:
> 
>    3 * foo
> 
> is not.

Yes, these are the sort of oddities we get with *any* choice we make
regarding expressions involving two or more relative symbols.

We've also got the constraint of compatibility with old ld behaviour,
at least for the simple expressions likely to be used in many existing
linker scripts.  That makes your #3 a bit of a problem.  For instance

x = 2;
y = 3;
z = x * y;

ought to always result in z having a value of 6, assuming x, y, and z
are all outside any output section statement, or all in one
particular output section statement.  In the latter case, z should be
section relative.  What happens when z is set in a different output
section statement to x and y is open to change from the old ld, I'd
say.

Note that the new code makes the distinction between a plain number
and an absolute symbol, so the result section of "x * y" could either
be NULL (plain number) as I do in my second patch, or the same section
as x and y as in the first patch, and still satisfy this compatibility
requirement.  You could not make the result of "x * y" an absolute
value as that would cause z to be absolute.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-21  4:02                                           ` Alan Modra
@ 2011-01-21 13:19                                             ` Alan Modra
  2011-01-21 13:21                                               ` H.J. Lu
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2011-01-21 13:19 UTC (permalink / raw)
  To: Maciej W. Rozycki, H.J. Lu, Daniel Jacobowitz, binutils, Kazu Hirata

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

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-21 13:19                                             ` Alan Modra
@ 2011-01-21 13:21                                               ` H.J. Lu
  2011-01-23  3:29                                                 ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: H.J. Lu @ 2011-01-21 13:21 UTC (permalink / raw)
  To: Maciej W. Rozycki, Daniel Jacobowitz, binutils, Kazu Hirata

On Fri, Jan 21, 2011 at 5:18 AM, Alan Modra <amodra@gmail.com> wrote:
> 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.
>

You should add at least one testcase to verify it.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-21 13:21                                               ` H.J. Lu
@ 2011-01-23  3:29                                                 ` Alan Modra
  2011-01-25  1:14                                                   ` Hans-Peter Nilsson
  0 siblings, 1 reply; 48+ messages in thread
From: Alan Modra @ 2011-01-23  3:29 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Maciej W. Rozycki, Daniel Jacobowitz, binutils, Kazu Hirata

On Fri, Jan 21, 2011 at 05:21:17AM -0800, H.J. Lu wrote:
> You should add at least one testcase to verify it.

It takes a while to write a proper testcase that doesn't introduce
failures on some target.  This one fails on x86_64-mingw32 for
reasons that I haven't fully investigated, but suspect that the
failure is showing a real bug.  It looks like a case of address wrap.

	* ld-scripts/sane1.d, * ld-scripts/sane1.t: New test.
	* ld-scripts/expr.exp: Run it.

Index: ld/testsuite/ld-scripts/expr.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-scripts/expr.exp,v
retrieving revision 1.3
diff -u -p -r1.3 expr.exp
--- ld/testsuite/ld-scripts/expr.exp	28 Dec 2010 18:04:10 -0000	1.3
+++ ld/testsuite/ld-scripts/expr.exp	23 Jan 2011 03:24:05 -0000
@@ -22,3 +22,4 @@
 
 run_dump_test expr1
 run_dump_test expr2
+run_dump_test sane1
Index: ld/testsuite/ld-scripts/sane1.d
===================================================================
RCS file: ld/testsuite/ld-scripts/sane1.d
diff -N ld/testsuite/ld-scripts/sane1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-scripts/sane1.d	23 Jan 2011 03:24:05 -0000
@@ -0,0 +1,33 @@
+# source: data.s
+# ld: -T sane1.t
+# nm: -B
+# notarget: mmix-* pdp11-* rs6000-*-aix* tic30-*-aout
+# mmix symbol sections are wrong, pdp sign extends 16-bit addresses
+# rs6000-aix and tic30 don't like empty .text
+
+#...
+0+8004 D d1
+0+8024 D d2
+0+0020 A diff
+0+0100 A e1
+0+0080 A e2
+0+8000 A e3
+0+0090 A prod
+0+8002 D s1
+0+8001 D s2
+0+8007 D s3
+0+8002 A s4
+0+0004 A s5
+0+19a0 A s6
+0+8020 D s_diff
+0+8090 D s_prod
+0+8028 D s_sum
+0+8020 D s_sum_neg
+0+0028 A sum
+0+0020 A sum_neg
+0+8002 D x1
+0+8001 D x2
+0+8007 D x3
+0+8002 A x4
+0+0004 A x5
+0+19a0 A x6
Index: ld/testsuite/ld-scripts/sane1.t
===================================================================
RCS file: ld/testsuite/ld-scripts/sane1.t
diff -N ld/testsuite/ld-scripts/sane1.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-scripts/sane1.t	23 Jan 2011 03:24:05 -0000
@@ -0,0 +1,36 @@
+LD_FEATURE("SANE_EXPR")
+e1 = 0x100;
+e2 = 0x80;
+e3 = e1 * e2;
+SECTIONS
+{
+  . = e3;
+  .data :
+  {
+    d1 = 4;
+    . += d1 + 5 << 2;
+    d2 = .;
+    s_diff = d2 - d1;
+    s_sum_neg = d2 + -d1;
+    s_sum = d2 + d1;
+    s_prod = d2 * d1;
+    s1 = d1 - 2;
+    s2 = d2 % 5;
+    s3 = d2 / 5;
+    s4 = ABSOLUTE (d1) - 2;
+    s5 = ABSOLUTE (d2) % 5;
+    s6 = ABSOLUTE (d2) / 5;
+  }
+  /DISCARD/ : {*(*)}
+
+diff = d2 - d1;
+sum_neg = d2 + -d1;
+sum = d2 + d1;
+prod = d2 * d1;
+x1 = d1 - 2;
+x2 = d2 % 5;
+x3 = d2 / 5;
+x4 = ABSOLUTE (d1) - 2;
+x5 = ABSOLUTE (d2) % 5;
+x6 = ABSOLUTE (d2) / 5;
+}

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-23  3:29                                                 ` Alan Modra
@ 2011-01-25  1:14                                                   ` Hans-Peter Nilsson
  2011-01-25  5:50                                                     ` Alan Modra
  0 siblings, 1 reply; 48+ messages in thread
From: Hans-Peter Nilsson @ 2011-01-25  1:14 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

On Sun, 23 Jan 2011, Alan Modra wrote:
> Index: ld/testsuite/ld-scripts/sane1.d
> +# notarget: mmix-* pdp11-* rs6000-*-aix* tic30-*-aout
> +# mmix symbol sections are wrong,

For failing test-cases due to a known or suspected bug, pretty
please xfail the test rather than skip it.

brgds, H-P

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: Relative expressions and ASSERT
  2011-01-25  1:14                                                   ` Hans-Peter Nilsson
@ 2011-01-25  5:50                                                     ` Alan Modra
  0 siblings, 0 replies; 48+ messages in thread
From: Alan Modra @ 2011-01-25  5:50 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: binutils

On Mon, Jan 24, 2011 at 08:14:00PM -0500, Hans-Peter Nilsson wrote:
> On Sun, 23 Jan 2011, Alan Modra wrote:
> > Index: ld/testsuite/ld-scripts/sane1.d
> > +# notarget: mmix-* pdp11-* rs6000-*-aix* tic30-*-aout
> > +# mmix symbol sections are wrong,
> 
> For failing test-cases due to a known or suspected bug, pretty
> please xfail the test rather than skip it.

Feel free to change it for mmix if you'd like.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2011-01-25  5:50 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-10 22:20 Relative expressions and ASSERT Daniel Jacobowitz
2010-08-11  6:31 ` Alan Modra
2010-08-11 23:11   ` Daniel Jacobowitz
2010-08-12 13:48     ` Alan Modra
2010-08-12 15:47       ` Alan Modra
2010-08-12 16:19         ` H.J. Lu
2010-08-13  0:05           ` Alan Modra
2010-12-16  8:01             ` H.J. Lu
2010-12-16 11:16               ` Alan Modra
2010-12-16 13:21                 ` H.J. Lu
2010-12-16 15:49                   ` H.J. Lu
2010-12-16 16:51                 ` Daniel Jacobowitz
2010-12-16 18:28                   ` H.J. Lu
2010-12-16 23:14                     ` Alan Modra
2010-12-16 23:17                       ` H.J. Lu
2010-12-16 23:38                         ` H.J. Lu
2010-12-17  0:01                           ` H.J. Lu
2010-12-17  0:06                         ` Alan Modra
2010-12-17  4:17                           ` H.J. Lu
2010-12-17 19:55                             ` H.J. Lu
2010-12-20 13:04                               ` Alan Modra
2010-12-21 16:15                                 ` Daniel Jacobowitz
2010-12-22  3:31                                   ` Alan Modra
2010-12-22 12:22                                     ` Daniel Jacobowitz
2010-12-24  9:27                                       ` Alan Modra
2010-12-28 11:37                                 ` H.J. Lu
2011-01-19  6:49                                 ` Maciej W. Rozycki
2011-01-19  8:25                                   ` Alan Modra
2011-01-19 12:28                                     ` H.J. Lu
2011-01-20 12:26                                       ` Alan Modra
2011-01-20 17:18                                         ` Maciej W. Rozycki
2011-01-21  4:02                                           ` Alan Modra
2011-01-21 13:19                                             ` Alan Modra
2011-01-21 13:21                                               ` H.J. Lu
2011-01-23  3:29                                                 ` Alan Modra
2011-01-25  1:14                                                   ` Hans-Peter Nilsson
2011-01-25  5:50                                                     ` Alan Modra
2011-01-19 14:25                                     ` Ian Lance Taylor
2010-12-20 15:25                               ` Alan Modra
2010-12-16 22:43                 ` H.J. Lu
2010-12-16 22:58                   ` H.J. Lu
2010-08-13 14:51         ` Ian Lance Taylor
2010-08-16 15:49           ` Alan Modra
2010-08-19 12:44             ` Alan Modra
2010-08-19 20:01               ` Daniel Jacobowitz
2010-08-31  4:06                 ` Alan Modra
2010-08-31  5:33                   ` Hans-Peter Nilsson
2010-10-01  8:20             ` PR12066 Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).