This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ALIGN change affects standard scripts


a2c59f28 changed the way the unary ALIGN behaved inside output sections,
resulting in cris-elf testsuite regressions.  This patch pads out .bss
in the same manner as it was prior to the ALIGN change.

	* scripttempl/elf.sc (.ldata, .bss): Align absolute value of dot.
	* ldexp.c (is_align_conditional): Handle binary ALIGN.
	(exp_fold_tree_1): Move code setting SEC_KEEP for assignments to
	dot inside output sections.  Handle absolute expressions.

diff --git a/ld/ldexp.c b/ld/ldexp.c
index 2c0fe5a..f02f576 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -951,20 +951,28 @@ is_dot_plus_0 (const etree_type *tree)
 	      || is_sym_value (tree->binary.rhs, 0)));
 }
 
-/* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)".  */
+/* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)",
+   or equivalent binary ALIGN expressions.  */
 
 static bfd_boolean
 is_align_conditional (const etree_type *tree)
 {
-  if (tree->type.node_class == etree_unary
-      && tree->type.node_code == ALIGN_K)
-    {
-      tree = tree->unary.child;
-      return (tree->type.node_class == etree_trinary
-	      && is_dot_ne_0 (tree->trinary.cond)
-	      && is_value (tree->trinary.rhs, 1));
-    }
-  return 0;
+  if (tree->type.node_code != ALIGN_K)
+    return 0;
+  else if (tree->type.node_class == etree_unary)
+    tree = tree->unary.child;
+  else if (tree->type.node_class == etree_binary
+	   && (is_dot (tree->binary.lhs)
+	       || (tree->binary.lhs->type.node_class == etree_unary
+		   && tree->binary.lhs->type.node_code == ABSOLUTE
+		   && is_dot (tree->binary.lhs->unary.child))))
+    tree = tree->binary.rhs;
+  else
+    return 0;
+
+  return (tree->type.node_class == etree_trinary
+	  && is_dot_ne_0 (tree->trinary.cond)
+	  && is_value (tree->trinary.rhs, 1));
 }
 
 static void
@@ -1031,25 +1039,13 @@ exp_fold_tree_1 (etree_type *tree)
 	      exp_fold_tree_1 (tree->assign.src);
 	      expld.assigning_to_dot = FALSE;
 
-	      /* If we are assigning to dot inside an output section
-		 arrange to keep the section, except for certain
-		 expressions that evaluate to zero.  We ignore . = 0,
-		 . = . + 0, and . = ALIGN (. != 0 ? expr : 1).  */
-	      if (expld.phase == lang_mark_phase_enum
-		  && expld.section != bfd_abs_section_ptr
-		  && !(expld.result.valid_p
-		       && expld.result.value == 0
-		       && (is_value (tree->assign.src, 0)
-			   || is_sym_value (tree->assign.src, 0)
-			   || is_dot_plus_0 (tree->assign.src)
-			   || is_align_conditional (tree->assign.src))))
-		expld.section->flags |= SEC_KEEP;
-
 	      if (!expld.result.valid_p)
 		{
 		  if (expld.phase != lang_mark_phase_enum)
 		    einfo (_("%F%S invalid assignment to"
 			     " location counter\n"), tree);
+		  else if (expld.section != bfd_abs_section_ptr)
+		    expld.section->flags |= SEC_KEEP;
 		}
 	      else if (expld.dotp == NULL)
 		einfo (_("%F%S assignment to location counter"
@@ -1069,6 +1065,25 @@ exp_fold_tree_1 (etree_type *tree)
 		    nextdot += expld.result.section->vma;
 		  else
 		    nextdot += expld.section->vma;
+
+		  /* If we are assigning to dot inside an output
+		     section arrange to keep the section, except for
+		     certain expressions that evaluate to zero.  We
+		     can't ignore all expressions that evaluate to
+		     zero because an otherwise empty section might
+		     have padding added by an alignment expression
+		     that changes with relaxation.  Such a section
+		     might have zero size before relaxation and so be
+		     stripped incorrectly.  */
+		  if (expld.phase == lang_mark_phase_enum
+		      && expld.section != bfd_abs_section_ptr
+		      && !(nextdot == expld.section->vma
+			   && (is_value (tree->assign.src, 0)
+			       || is_sym_value (tree->assign.src, 0)
+			       || is_dot_plus_0 (tree->assign.src)
+			       || is_align_conditional (tree->assign.src))))
+		    expld.section->flags |= SEC_KEEP;
+
 		  if (nextdot < expld.dot
 		      && expld.section != bfd_abs_section_ptr)
 		    einfo (_("%F%S cannot move location counter backwards"
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index c6dfe5d..5a15a68 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -240,7 +240,7 @@ test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS="
   .ldata ${RELOCATING-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} :
   {
     *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
-    ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
+    ${RELOCATING+. = ALIGN (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
   }"
 if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
   SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))"
@@ -628,7 +628,7 @@ cat <<EOF
       .bss section disappears because there are no input sections.
       FIXME: Why do we need it? When there is no .bss section, we don't
       pad the .data section.  */
-   ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
+   ${RELOCATING+. = ALIGN (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
   }
   ${OTHER_BSS_SECTIONS}
   ${LARGE_BSS_AFTER_BSS+${LARGE_BSS}}

-- 
Alan Modra
Australia Development Lab, IBM


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