summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-12-22 11:11:50 +1030
committerAlan Modra <amodra@gmail.com>2014-12-23 23:36:51 +1030
commit422f1c65c9e9d30a7e82d136b2d4c6cd901f0245 (patch)
tree6f5004d8051d90e72a640740d76cafa8fe276102
parent12b2843a6bb12292d8e36d8df22c788a3c91cb2f (diff)
downloadbinutils-gdb-422f1c65c9e9d30a7e82d136b2d4c6cd901f0245.tar.gz
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/ChangeLog7
-rw-r--r--ld/ldexp.c36
2 files changed, 34 insertions, 9 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7f6eca28cf1..154def71767 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>
diff --git a/ld/ldexp.c b/ld/ldexp.c
index b4af893c86e..bd2266b4d28 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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)
{