aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-01-20 21:28:42 +1030
committerAlan Modra <amodra@gmail.com>2014-01-20 21:28:42 +1030
commitfa72205cb90527fd34753203993859907a53ead2 (patch)
tree287b960405c90fec23679e85d9a8688e8d5dec17 /ld/ldexp.c
parent24ef1aa73ed312282bd1a755b3ac94681c9f1544 (diff)
downloadgdb-fa72205cb90527fd34753203993859907a53ead2.zip
gdb-fa72205cb90527fd34753203993859907a53ead2.tar.gz
gdb-fa72205cb90527fd34753203993859907a53ead2.tar.bz2
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 <lang_definedness_table>): 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 <DEFINED>): Update. (fold_name <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.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c31
1 files changed, 23 insertions, 8 deletions
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)