diff options
author | Alan Modra <amodra@gmail.com> | 2014-12-22 11:11:50 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-12-23 23:36:51 +1030 |
commit | 422f1c65c9e9d30a7e82d136b2d4c6cd901f0245 (patch) | |
tree | 6f5004d8051d90e72a640740d76cafa8fe276102 | |
parent | 12b2843a6bb12292d8e36d8df22c788a3c91cb2f (diff) | |
download | fsf-binutils-gdb-422f1c65c9e9d30a7e82d136b2d4c6cd901f0245.zip fsf-binutils-gdb-422f1c65c9e9d30a7e82d136b2d4c6cd901f0245.tar.gz fsf-binutils-gdb-422f1c65c9e9d30a7e82d136b2d4c6cd901f0245.tar.bz2 |
Report an error for script multiply defined symbols
or maybe not just yet, but this is better than a FIXME.
* ldexp.c (update_definedness): Return false if script symbol is
redefining a strong symbol in an object.
(exp_fold_tree_1 <etree_assign>): Set up for reporting a multiple
definition error, but for now leave disabled.
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/ldexp.c | 36 |
2 files changed, 34 insertions, 9 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 7f6eca2..154def7 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,12 @@ 2014-12-23 Alan Modra <amodra@gmail.com> + * ldexp.c (update_definedness): Return false if script symbol is + redefining a strong symbol in an object. + (exp_fold_tree_1 <etree_assign>): Set up for reporting a multiple + definition error, but for now leave disabled. + +2014-12-23 Alan Modra <amodra@gmail.com> + * ldexp.c (exp_fold_tree_1 <etree_provide>): Test linker_def. 2014-12-23 Alan Modra <amodra@gmail.com> @@ -291,11 +291,13 @@ symbol_defined (const char *name) bfd_hash_lookup (&definedness_table, name, FALSE, FALSE)); } -/* Update the definedness state of NAME. */ +/* Update the definedness state of NAME. Return FALSE if script symbol + is multiply defining a strong symbol in an object. */ -static void +static bfd_boolean update_definedness (const char *name, struct bfd_link_hash_entry *h) { + bfd_boolean ret; struct definedness_hash_entry *defentry = (struct definedness_hash_entry *) bfd_hash_lookup (&definedness_table, name, TRUE, FALSE); @@ -305,14 +307,22 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h) /* If the symbol was already defined, and not by a script, then it must be defined by an object file or by the linker target code. */ + ret = TRUE; if (!defentry->by_script && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak || h->type == bfd_link_hash_common)) - defentry->by_object = 1; + { + defentry->by_object = 1; + if (h->type == bfd_link_hash_defined + && h->u.def.section->output_section != NULL + && !h->linker_def) + ret = FALSE; + } defentry->by_script = 1; defentry->iteration = lang_statement_iteration; + return ret; } static void @@ -1108,19 +1118,27 @@ exp_fold_tree_1 (etree_type *tree) tree->assign.dst); } - /* FIXME: Should we worry if the symbol is already - defined? */ - update_definedness (tree->assign.dst, h); - h->type = bfd_link_hash_defined; - h->u.def.value = expld.result.value; if (expld.result.section == NULL) expld.result.section = expld.section; + if (!update_definedness (tree->assign.dst, h) && 0) + { + /* Symbol was already defined. For now this error + is disabled because it causes failures in the ld + testsuite: ld-elf/var1, ld-scripts/defined5, and + ld-scripts/pr14962. Some of these no doubt + reflect scripts used in the wild. */ + (*link_info.callbacks->multiple_definition) + (&link_info, h, link_info.output_bfd, + expld.result.section, expld.result.value); + } + h->type = bfd_link_hash_defined; + h->u.def.value = expld.result.value; h->u.def.section = expld.result.section; if (tree->type.node_class == etree_provide) tree->type.node_class = etree_provided; /* Copy the symbol type if this is a simple assignment of - one symbol to another. This could be more general + one symbol to another. This could be more general (e.g. a ?: operator with NAMEs in each branch). */ if (tree->assign.src->type.node_class == etree_name) { |