ALIGN change affects standard scripts
a2c59f28
changed the way the unary ALIGN behaved inside output sections,
resulting in cris-elf testsuite regressions. This patch pads out .bss
in the same manner as it was prior to the ALIGN change.
* scripttempl/elf.sc (.ldata, .bss): Align absolute value of dot.
* ldexp.c (is_align_conditional): Handle binary ALIGN.
(exp_fold_tree_1): Move code setting SEC_KEEP for assignments to
dot inside output sections. Handle absolute expressions.
This commit is contained in:
parent
5e63e45255
commit
e474ab13ec
|
@ -1,3 +1,10 @@
|
||||||
|
2015-07-20 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* scripttempl/elf.sc (.ldata, .bss): Align absolute value of dot.
|
||||||
|
* ldexp.c (is_align_conditional): Handle binary ALIGN.
|
||||||
|
(exp_fold_tree_1): Move code setting SEC_KEEP for assignments to
|
||||||
|
dot inside output sections. Handle absolute expressions.
|
||||||
|
|
||||||
2015-07-14 H.J. Lu <hongjiu.lu@intel.com>
|
2015-07-14 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Make
|
* emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Make
|
||||||
|
|
63
ld/ldexp.c
63
ld/ldexp.c
|
@ -951,20 +951,28 @@ is_dot_plus_0 (const etree_type *tree)
|
||||||
|| is_sym_value (tree->binary.rhs, 0)));
|
|| is_sym_value (tree->binary.rhs, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)". */
|
/* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)",
|
||||||
|
or equivalent binary ALIGN expressions. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
is_align_conditional (const etree_type *tree)
|
is_align_conditional (const etree_type *tree)
|
||||||
{
|
{
|
||||||
if (tree->type.node_class == etree_unary
|
if (tree->type.node_code != ALIGN_K)
|
||||||
&& tree->type.node_code == ALIGN_K)
|
return 0;
|
||||||
{
|
else if (tree->type.node_class == etree_unary)
|
||||||
tree = tree->unary.child;
|
tree = tree->unary.child;
|
||||||
return (tree->type.node_class == etree_trinary
|
else if (tree->type.node_class == etree_binary
|
||||||
&& is_dot_ne_0 (tree->trinary.cond)
|
&& (is_dot (tree->binary.lhs)
|
||||||
&& is_value (tree->trinary.rhs, 1));
|
|| (tree->binary.lhs->type.node_class == etree_unary
|
||||||
}
|
&& tree->binary.lhs->type.node_code == ABSOLUTE
|
||||||
return 0;
|
&& 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1031,25 +1039,13 @@ exp_fold_tree_1 (etree_type *tree)
|
||||||
exp_fold_tree_1 (tree->assign.src);
|
exp_fold_tree_1 (tree->assign.src);
|
||||||
expld.assigning_to_dot = FALSE;
|
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). */
|
|
||||||
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.result.valid_p)
|
||||||
{
|
{
|
||||||
if (expld.phase != lang_mark_phase_enum)
|
if (expld.phase != lang_mark_phase_enum)
|
||||||
einfo (_("%F%S invalid assignment to"
|
einfo (_("%F%S invalid assignment to"
|
||||||
" location counter\n"), tree);
|
" location counter\n"), tree);
|
||||||
|
else if (expld.section != bfd_abs_section_ptr)
|
||||||
|
expld.section->flags |= SEC_KEEP;
|
||||||
}
|
}
|
||||||
else if (expld.dotp == NULL)
|
else if (expld.dotp == NULL)
|
||||||
einfo (_("%F%S assignment to location counter"
|
einfo (_("%F%S assignment to location counter"
|
||||||
|
@ -1069,6 +1065,25 @@ exp_fold_tree_1 (etree_type *tree)
|
||||||
nextdot += expld.result.section->vma;
|
nextdot += expld.result.section->vma;
|
||||||
else
|
else
|
||||||
nextdot += expld.section->vma;
|
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
|
if (nextdot < expld.dot
|
||||||
&& expld.section != bfd_abs_section_ptr)
|
&& expld.section != bfd_abs_section_ptr)
|
||||||
einfo (_("%F%S cannot move location counter backwards"
|
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-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} :
|
||||||
{
|
{
|
||||||
*(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
|
*(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
|
||||||
${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
|
${RELOCATING+. = ALIGN (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
|
||||||
}"
|
}"
|
||||||
if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
|
if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
|
||||||
SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))"
|
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.
|
.bss section disappears because there are no input sections.
|
||||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||||
pad the .data section. */
|
pad the .data section. */
|
||||||
${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
|
${RELOCATING+. = ALIGN (ABSOLUTE (.), . != 0 ? ${ALIGNMENT} : 1);}
|
||||||
}
|
}
|
||||||
${OTHER_BSS_SECTIONS}
|
${OTHER_BSS_SECTIONS}
|
||||||
${LARGE_BSS_AFTER_BSS+${LARGE_BSS}}
|
${LARGE_BSS_AFTER_BSS+${LARGE_BSS}}
|
||||||
|
|
Loading…
Reference in New Issue