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

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