ALIGN change affects standard scripts
authorAlan Modra <amodra@gmail.com>
Mon, 20 Jul 2015 04:59:21 +0000 (14:29 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 20 Jul 2015 04:59:21 +0000 (14:29 +0930)
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.

ld/ChangeLog
ld/ldexp.c
ld/scripttempl/elf.sc

index 3dd0a6f031f19bfcf59199108d6ec3525abd8415..ba6eded1330d37e9b0cf8209b143d885dcba0ba8 100644 (file)
@@ -1,3 +1,10 @@
+2015-07-20  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2015-07-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Make
index 2c0fe5a16fdebd3a2b6d60f02c82e33650ee52a1..f02f576698ebab50663f65af2a9f93a052f843c9 100644 (file)
@@ -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"
index c6dfe5d01a426c3eb4439213f124a3c1dbd98f29..5a15a68916ec20f765e9335c0b19c6d9a03f8357 100644 (file)
@@ -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}}