/* This module handles expression trees.
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
This file is part of the GNU Binutils.
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);
/* 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
case LENGTH:
{
- lang_memory_region_type *mem;
-
- mem = lang_memory_region_lookup (tree->name.name, FALSE);
- if (mem != NULL)
- new_number (mem->length);
- else
- einfo (_("%F%S: undefined MEMORY region `%s'"
- " referenced in expression\n"),
- tree, tree->name.name);
+ if (expld.phase != lang_first_phase_enum)
+ {
+ lang_memory_region_type *mem;
+
+ mem = lang_memory_region_lookup (tree->name.name, FALSE);
+ if (mem != NULL)
+ new_number (mem->length);
+ else
+ einfo (_("%F%S: undefined MEMORY region `%s'"
+ " referenced in expression\n"),
+ tree, tree->name.name);
+ }
}
break;
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)
{