Revert ALIGN changes
authorAlan Modra <amodra@gmail.com>
Thu, 6 Aug 2015 06:26:34 +0000 (15:56 +0930)
committerAlan Modra <amodra@gmail.com>
Thu, 6 Aug 2015 06:35:40 +0000 (16:05 +0930)
Reverts a2c59f28 and e474ab13.  Since the unary form of ALIGN only
references "dot" implicitly, there isn't really a strong argument for
making ALIGN use a relative value when inside an output section.

* ldexp.c (align_dot_val): Delete.
(fold_unary <ALIGN_K, NEXT>): Revert 2015-07-10 change.
(is_align_conditional): Revert 2015-07-20 change.
(exp_fold_tree_1): Likewise, but keep expanded comment.
* scripttempl/elf.sc (.ldata, .bss): Revert 2015-07-20 change.
* ld.texinfo (<ALIGN>): Correct description.

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

index 23b12c8617543614e8644c7d0aff77bf65014e31..5f1094a37c4958b9d687366015e08e3306365929 100644 (file)
@@ -1,3 +1,12 @@
+2015-08-06  Alan Modra  <amodra@gmail.com>
+
+       * ldexp.c (align_dot_val): Delete.
+       (fold_unary <ALIGN_K, NEXT>): Revert 2015-07-10 change.
+       (is_align_conditional): Revert 2015-07-20 change.
+       (exp_fold_tree_1): Likewise, but keep expanded comment.
+       * scripttempl/elf.sc (.ldata, .bss): Revert 2015-07-20 change.
+       * ld.texinfo (<ALIGN>): Correct description.
+
 2015-08-04  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * ld.texinfo (Options): Document --require-defined option.
index bddf926b3c77cb868bb96841b724d8a15c76d523..cf3b586a0e2df99497711122b2e6c2b6f47bfc60 100644 (file)
@@ -5992,7 +5992,7 @@ to the next @var{align} boundary.  The single operand @code{ALIGN}
 doesn't change the value of the location counter---it just does
 arithmetic on it.  The two operand @code{ALIGN} allows an arbitrary
 expression to be aligned upwards (@code{ALIGN(@var{align})} is
-equivalent to @code{ALIGN(., @var{align})}).
+equivalent to @code{ALIGN(ABSOLUTE(.), @var{align})}).
 
 Here is an example which aligns the output @code{.data} section to the
 next @code{0x2000} byte boundary after the preceding section and sets a
index f02f576698ebab50663f65af2a9f93a052f843c9..642f8d667b88651799473679efaabcfd0bdae8a4 100644 (file)
@@ -257,14 +257,6 @@ new_rel_from_abs (bfd_vma value)
   expld.result.section = s;
 }
 
-static void
-align_dot_val (bfd_vma align)
-{
-  bfd_vma base = expld.section->vma;
-
-  new_rel_from_abs (base + align_n (expld.dot - base, align));
-}
-
 /* New-function for the definedness hash table.  */
 
 static struct bfd_hash_entry *
@@ -343,7 +335,7 @@ fold_unary (etree_type *tree)
        {
        case ALIGN_K:
          if (expld.phase != lang_first_phase_enum)
-           align_dot_val (expld.result.value);
+           new_rel_from_abs (align_n (expld.dot, expld.result.value));
          else
            expld.result.valid_p = FALSE;
          break;
@@ -373,7 +365,7 @@ fold_unary (etree_type *tree)
          if (expld.phase != lang_first_phase_enum)
            {
              make_abs ();
-             align_dot_val (expld.result.value);
+             expld.result.value = align_n (expld.dot, expld.result.value);
            }
          else
            expld.result.valid_p = FALSE;
@@ -951,28 +943,20 @@ 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)",
-   or equivalent binary ALIGN expressions.  */
+/* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)".  */
 
 static bfd_boolean
 is_align_conditional (const etree_type *tree)
 {
-  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));
+  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;
 }
 
 static void
@@ -1039,13 +1023,30 @@ 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).
+                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
+                 && !(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"
@@ -1065,25 +1066,6 @@ 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 37e435110fe879126bc29b4d6abccbc2c40041ec..ec78c908267ffe92d536443e0285cfe0a8496644 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 (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
+    ${RELOCATING+. = ALIGN(. != 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 (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
+   ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
   }
   ${OTHER_BSS_SECTIONS}
   ${LARGE_BSS_AFTER_BSS+${LARGE_BSS}}