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.
This commit is contained in:
Alan Modra 2015-08-06 15:56:34 +09:30
parent 0cf003f49e
commit e0a3af227e
4 changed files with 43 additions and 52 deletions

View 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.

View 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

View 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"

View 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}}