From e0a3af227ee0602ae69320fd6f931c363f14975b Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 6 Aug 2015 15:56:34 +0930 Subject: [PATCH] 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 ): 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 (): Correct description. --- ld/ChangeLog | 9 +++++ ld/ld.texinfo | 2 +- ld/ldexp.c | 80 +++++++++++++++++-------------------------- ld/scripttempl/elf.sc | 4 +-- 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 + + * ldexp.c (align_dot_val): Delete. + (fold_unary ): 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 (): Correct description. + 2015-08-04 Andrew Burgess * 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 <