This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Binutils is broken by the linker change
On Fri, Mar 19, 2004 at 08:39:36AM +1030, Alan Modra wrote:
> On Thu, Mar 18, 2004 at 11:47:24AM -0800, H. J. Lu wrote:
> > The linker change caused massive failures in "make check" in gcc. I
> > will try to come up with a small testcase.
>
> Oops. Once again, I've proven how useless comments are. Some of the
> "dead code" that I eliminated, which the comment said was dealing with
> "the special case of a weak definition in a regular object followed by a
> non-weak definition in a shared object", was actually dealing with weak
> and non-weak in two shared objects as well. Reinstating the code..
>
Here is a patch. Basically, a weak definition is treated as strong if
the other comes from a shared library.
H.J.
----
2004-03-18 H.J. Lu <hongjiu.lu@intel.com>
* elflink.c (_bfd_elf_merge_symbol): Remove dt_needed.
Properly handle weak definition.
(_bfd_elf_add_default_symbol): Updated.
(elflink.h): Updated.
* elf-bfd.h (_bfd_elf_merge_symbol): Updated.
(_bfd_elf_add_default_symbol): Likewise.
--- bfd/elf-bfd.h.weak 2004-03-18 10:29:14.000000000 -0800
+++ bfd/elf-bfd.h 2004-03-18 14:39:26.000000000 -0800
@@ -1476,12 +1476,12 @@ extern bfd_boolean _bfd_elf_maybe_strip_
extern bfd_boolean _bfd_elf_merge_symbol
(bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
asection **, bfd_vma *, struct elf_link_hash_entry **, bfd_boolean *,
- bfd_boolean *, bfd_boolean *, bfd_boolean *, bfd_boolean);
+ bfd_boolean *, bfd_boolean *, bfd_boolean *);
extern bfd_boolean _bfd_elf_add_default_symbol
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
- bfd_boolean *, bfd_boolean, bfd_boolean);
+ bfd_boolean *, bfd_boolean);
extern bfd_boolean _bfd_elf_export_symbol
(struct elf_link_hash_entry *, void *);
--- bfd/elflink.c.weak 2004-03-18 10:11:04.000000000 -0800
+++ bfd/elflink.c 2004-03-18 14:39:17.000000000 -0800
@@ -653,8 +653,7 @@ _bfd_elf_link_renumber_dynsyms (bfd *out
TYPE_CHANGE_OK if it is OK for the type to change. We set
SIZE_CHANGE_OK if it is OK for the size to change. By OK to
change, we mean that we shouldn't warn if the type or size does
- change. DT_NEEDED indicates if it comes from a DT_NEEDED entry of
- a shared object. */
+ change. */
bfd_boolean
_bfd_elf_merge_symbol (bfd *abfd,
@@ -667,8 +666,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
bfd_boolean *skip,
bfd_boolean *override,
bfd_boolean *type_change_ok,
- bfd_boolean *size_change_ok,
- bfd_boolean dt_needed)
+ bfd_boolean *size_change_ok)
{
asection *sec;
struct elf_link_hash_entry *h;
@@ -887,6 +885,15 @@ _bfd_elf_merge_symbol (bfd *abfd,
oldweak = (h->root.type == bfd_link_hash_defweak
|| h->root.type == bfd_link_hash_undefweak);
+ /* If a new weak definition comes from a regular file and the old
+ symbol comes from a dynamic library, we treat the new one as
+ strong. Further, an old weak definition is treated as strong
+ when the new symbol comes from a dynamic library. */
+ if (newdef && !newdyn && olddyn)
+ newweak = FALSE;
+ if (olddef && newdyn)
+ oldweak = FALSE;
+
/* It's OK to change the type if either the existing symbol or the
new symbol is weak. A type change is also OK if the old symbol
is undefined and the new symbol is defined. */
@@ -904,17 +911,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
|| h->root.type == bfd_link_hash_undefined)
*size_change_ok = TRUE;
- /* If a new weak symbol comes from a regular file and the old symbol
- comes from a dynamic library, we treat the new one as strong.
- Similarly, an old weak symbol from a regular file is treated as
- strong when the new symbol comes from a dynamic library. Further,
- an old weak symbol from a dynamic library is treated as strong if
- the new symbol is from a DT_NEEDED dynamic library. */
- if (!newdyn && olddyn)
- newweak = FALSE;
- if ((!olddyn || dt_needed) && newdyn)
- oldweak = FALSE;
-
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
object. If a symbol appears in an uninitialized section, and is
@@ -1171,8 +1167,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
asection **psec,
bfd_vma *value,
bfd_boolean *dynsym,
- bfd_boolean override,
- bfd_boolean dt_needed)
+ bfd_boolean override)
{
bfd_boolean type_change_ok;
bfd_boolean size_change_ok;
@@ -1233,7 +1228,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
&hi, &skip, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ &size_change_ok))
return FALSE;
if (skip)
@@ -1340,7 +1335,7 @@ nondefault:
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
&hi, &skip, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ &size_change_ok))
return FALSE;
if (skip)
--- bfd/elflink.h.weak 2004-03-18 10:11:10.000000000 -0800
+++ bfd/elflink.h 2004-03-18 14:40:09.000000000 -0800
@@ -147,7 +147,6 @@ elf_link_add_object_symbols (bfd *abfd,
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
const struct elf_backend_data *bed;
- bfd_boolean dt_needed;
bfd_boolean add_needed;
struct elf_link_hash_table * hash_table;
bfd_size_type amt;
@@ -254,7 +253,6 @@ elf_link_add_object_symbols (bfd *abfd,
}
}
- dt_needed = FALSE;
add_needed = TRUE;
if (! dynamic)
{
@@ -298,7 +296,6 @@ elf_link_add_object_symbols (bfd *abfd,
case DYN_NORMAL:
break;
case DYN_DT_NEEDED:
- dt_needed = TRUE;
/* Fall thru */
case DYN_AS_NEEDED:
add_needed = FALSE;
@@ -775,8 +772,7 @@ elf_link_add_object_symbols (bfd *abfd,
if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
sym_hash, &skip, &override,
- &type_change_ok, &size_change_ok,
- dt_needed))
+ &type_change_ok, &size_change_ok))
goto error_free_vers;
if (skip)
@@ -1033,7 +1029,7 @@ elf_link_add_object_symbols (bfd *abfd,
if (definition || h->root.type == bfd_link_hash_common)
if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
&sec, &value, &dynsym,
- override, dt_needed))
+ override))
goto error_free_vers;
if (definition && !dynamic)