This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: ld/2300: ld does not report duplicate symbols defined in script file
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Wed, 8 Feb 2006 16:06:29 -0800
- Subject: PATCH: ld/2300: ld does not report duplicate symbols defined in script file
We don't check if a symbol is already defined when we make assignment.
This patch handle that. I can't use multiple_definition to check if
a multiple definition is real or not since it always returns TRUE.
I am not sure about the bfd_link_hash_defweak check. Can an
assignment override a weak definition?
H.J.
----
2006-02-08 H.J. Lu <hongjiu.lu@intel.com>
PR ld/2300:
* ldexp.c (exp_fold_tree_1): Check if a symbol has been defined
in input objects.
* ldmain.c (multiple_definition): Renamed to ...
(check_multiple_definition): This. Return FALSE if there is no
multiple definition.
(multiple_definition): Call check_multiple_definition and
return TRUE.
* ldmain.h (check_multiple_definition): New.
--- ld/ldexp.c.dup 2005-12-08 07:06:38.000000000 -0800
+++ ld/ldexp.c 2006-02-08 15:56:44.000000000 -0800
@@ -749,8 +749,28 @@ exp_fold_tree_1 (etree_type *tree)
tree->assign.dst);
}
- /* FIXME: Should we worry if the symbol is already
- defined? */
+ if (!link_info.allow_multiple_definition)
+ {
+ /* Check if the symbol is already defined. */
+ while (h->type == bfd_link_hash_indirect
+ || h->type == bfd_link_hash_warning)
+ h = h->u.i.link;
+
+ if ((h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
+ && h->u.def.section->owner != output_bfd
+ && h->u.def.section->owner != NULL
+ && (h->u.def.section->owner->flags & DYNAMIC) == 0
+ && check_multiple_definition (tree->assign.dst,
+ h->u.def.section->owner,
+ h->u.def.section,
+ h->u.def.value,
+ output_bfd,
+ expld.result.section,
+ expld.result.value))
+ einfo (_("%F%S: assignment to defined symbol\n"));
+ }
+
lang_update_definedness (tree->assign.dst, h);
h->type = bfd_link_hash_defined;
h->u.def.value = expld.result.value;
--- ld/ldmain.c.dup 2005-11-11 10:48:53.000000000 -0800
+++ ld/ldmain.c 2006-02-08 15:49:18.000000000 -0800
@@ -982,18 +982,16 @@ add_archive_element (struct bfd_link_inf
return TRUE;
}
-/* This is called when BFD has discovered a symbol which is defined
- multiple times. */
+/* Return TRUE if a symbol is defined multiple times. */
-static bfd_boolean
-multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
- const char *name,
- bfd *obfd,
- asection *osec,
- bfd_vma oval,
- bfd *nbfd,
- asection *nsec,
- bfd_vma nval)
+bfd_boolean
+check_multiple_definition (const char *name,
+ bfd *obfd,
+ asection *osec,
+ bfd_vma oval,
+ bfd *nbfd,
+ asection *nsec,
+ bfd_vma nval)
{
/* If either section has the output_section field set to
bfd_abs_section_ptr, it means that the section is being
@@ -1006,7 +1004,7 @@ multiple_definition (struct bfd_link_inf
|| (nsec->output_section != NULL
&& ! bfd_is_abs_section (nsec)
&& bfd_is_abs_section (nsec->output_section)))
- return TRUE;
+ return FALSE;
einfo (_("%X%C: multiple definition of `%T'\n"),
nbfd, nsec, nval, name);
@@ -1022,6 +1020,25 @@ multiple_definition (struct bfd_link_inf
return TRUE;
}
+/* This is called when BFD has discovered a symbol which is defined
+ multiple times. */
+
+static bfd_boolean
+multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name,
+ bfd *obfd,
+ asection *osec,
+ bfd_vma oval,
+ bfd *nbfd,
+ asection *nsec,
+ bfd_vma nval)
+{
+ /* FIXME: The return value from check_multiple_definition is
+ ignored. */
+ check_multiple_definition (name, obfd, osec, oval, nbfd, nsec, nval);
+ return TRUE;
+}
+
/* This is called when there is a definition of a common symbol, or
when a common symbol is found for a symbol that is already defined,
or when two common symbols are found. We only do something if
--- ld/ldmain.h.dup 2005-05-16 11:04:40.000000000 -0700
+++ ld/ldmain.h 2006-02-08 15:48:06.000000000 -0800
@@ -43,5 +43,8 @@ extern int overflow_cutoff_limit;
extern void add_ysym (const char *);
extern void add_wrap (const char *);
extern void add_keepsyms_file (const char *);
+extern bfd_boolean check_multiple_definition (const char *,
+ bfd *, asection *, bfd_vma,
+ bfd *, asection *, bfd_vma);
#endif