summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-08-06 15:56:34 +0930
committerAlan Modra <amodra@gmail.com>2015-08-06 16:05:40 +0930
commite0a3af227ee0602ae69320fd6f931c363f14975b (patch)
tree4987f91beb70806b6267baa7fe3b6cb44a10bfb9
parent0cf003f49ee8bbd5dc5f1ce45193c7ae056c69b8 (diff)
downloadbinutils-gdb-e0a3af227ee0602ae69320fd6f931c363f14975b.tar.gz
Revert ALIGN changes
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.
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/ld.texinfo2
-rw-r--r--ld/ldexp.c80
-rw-r--r--ld/scripttempl/elf.sc4
4 files changed, 43 insertions, 52 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 23b12c86175..5f1094a37c4 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index bddf926b3c7..cf3b586a0e2 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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
diff --git a/ld/ldexp.c b/ld/ldexp.c
index f02f576698e..642f8d667b8 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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"
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 37e435110fe..ec78c908267 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 (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}}