From fa72205cb90527fd34753203993859907a53ead2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 20 Jan 2014 21:28:42 +1030 Subject: Allow self-assignment for absolute symbols defined in a linker script Modifies ld machinery tracking linker script assignments to notice all assignments, not just those symbols mentioned in DEFINED(). ld/ PR ld/14962 * ldlang.h (struct lang_definedness_hash_entry): Add by_object and by_script. Make iteration a single bit field. (lang_track_definedness, lang_symbol_definition_iteration): Delete. (lang_symbol_defined): Declare. * ldlang.c (lang_statement_iteration): Expand comment a little. (lang_init ): Make it bigger. (lang_track_definedness, lang_symbol_definition): Delete. (lang_definedness_newfunc): Update. (lang_symbol_defined): New function. (lang_update_definedness): Create entries here. Do track whether script definition of symbol is valid, even when also defined in an object file. * ldexp.c (fold_name ): Update. (fold_name ): Allow self-assignment for absolute symbols defined in a linker script. ld/testsuite/ * ld-scripts/pr14962-2.d, * ld-scripts/pr14962-2.t: New test. * ld-scripts/expr.exp: Run it. --- ld/ldexp.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'ld/ldexp.c') diff --git a/ld/ldexp.c b/ld/ldexp.c index 49e7c65..9a529db 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -575,13 +575,10 @@ fold_name (etree_type *tree) break; case DEFINED: - if (expld.phase == lang_first_phase_enum) - lang_track_definedness (tree->name.name); - else + if (expld.phase != lang_first_phase_enum) { struct bfd_link_hash_entry *h; - int def_iteration - = lang_symbol_definition_iteration (tree->name.name); + struct lang_definedness_hash_entry *def; h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info, @@ -591,15 +588,33 @@ fold_name (etree_type *tree) && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak || h->type == bfd_link_hash_common) - && (def_iteration == lang_statement_iteration - || def_iteration == -1)); + && ((def = lang_symbol_defined (tree->name.name)) == NULL + || def->by_object + || def->iteration == (lang_statement_iteration & 1))); } break; case NAME: if (expld.assign_name != NULL && strcmp (expld.assign_name, tree->name.name) == 0) - expld.assign_name = NULL; + { + /* Self-assignment is only allowed for absolute symbols + defined in a linker script. */ + struct bfd_link_hash_entry *h; + struct lang_definedness_hash_entry *def; + + h = bfd_wrapped_link_hash_lookup (link_info.output_bfd, + &link_info, + tree->name.name, + FALSE, FALSE, TRUE); + if (!(h != NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && h->u.def.section == bfd_abs_section_ptr + && (def = lang_symbol_defined (tree->name.name)) != NULL + && def->iteration == (lang_statement_iteration & 1))) + expld.assign_name = NULL; + } if (expld.phase == lang_first_phase_enum) ; else if (tree->name.name[0] == '.' && tree->name.name[1] == 0) -- cgit v1.1