diff options
author | Alan Modra <amodra@gmail.com> | 2015-08-06 15:56:34 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-08-06 16:05:40 +0930 |
commit | e0a3af227ee0602ae69320fd6f931c363f14975b (patch) | |
tree | 4987f91beb70806b6267baa7fe3b6cb44a10bfb9 | |
parent | 0cf003f49ee8bbd5dc5f1ce45193c7ae056c69b8 (diff) | |
download | gdb-e0a3af227ee0602ae69320fd6f931c363f14975b.zip gdb-e0a3af227ee0602ae69320fd6f931c363f14975b.tar.gz gdb-e0a3af227ee0602ae69320fd6f931c363f14975b.tar.bz2 |
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.
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/ld.texinfo | 2 | ||||
-rw-r--r-- | ld/ldexp.c | 80 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 4 |
4 files changed, 43 insertions, 52 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 23b12c8..5f1094a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index bddf926..cf3b586 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 @@ -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 37e4351..ec78c90 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 <<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}} |