Revert ALIGN changes
Revertsa2c59f28
ande474ab13
. 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:
parent
0cf003f49e
commit
e0a3af227e
4 changed files with 43 additions and 52 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
80
ld/ldexp.c
80
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"
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in a new issue