summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2003-04-25 15:17:51 +0000
committerH.J. Lu <hjl@lucon.org>2003-04-25 15:17:51 +0000
commitaba2bc343c8ae8956ebfe28bafe76d93f3f3de69 (patch)
tree0c75b9a1e53440cc32d34dd67255b356beff5ab0 /bfd
parent1f67c642520432f17b229c2bf984d5b311df3fe5 (diff)
downloadgdb-aba2bc343c8ae8956ebfe28bafe76d93f3f3de69.tar.gz
2003-04-25 Alan Modra <amodra@bigpond.net.au>
* elflink.h (elf_merge_symbol): When we find a regular definition for an indirect symbol, flip the indirection so that the old direct symbol now points to the new definition.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elflink.h45
2 files changed, 36 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 22f055f999f..10a5957aabb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2003-04-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_merge_symbol): When we find a regular definition
+ for an indirect symbol, flip the indirection so that the old
+ direct symbol now points to the new definition.
+
2003-04-24 Roland McGrath <roland@redhat.com>
* elf.c (bfd_section_from_phdr): Map PT_GNU_EH_FRAME to "eh_frame_hdr".
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 12f91ef4ef5..505bfb12154 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -479,6 +479,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
{
asection *sec;
struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry *flip;
int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
@@ -769,6 +770,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
As above, we permit a non-weak definition in a shared object to
override a weak definition in a regular object. */
+ flip = NULL;
if (! newdyn
&& (newdef
|| (bfd_is_com_section (sec)
@@ -797,19 +799,13 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
if (bfd_is_com_section (sec))
*type_change_ok = TRUE;
- /* This union may have been set to be non-NULL when this symbol
- was seen in a dynamic object. We must force the union to be
- NULL, so that it is correct for a regular symbol. */
-
- h->verinfo.vertree = NULL;
-
- /* In this special case, if H is the target of an indirection,
- we want the caller to frob with H rather than with the
- indirect symbol. That will permit the caller to redefine the
- target of the indirection, rather than the indirect symbol
- itself. FIXME: This will break the -y option if we store a
- symbol with a different name. */
- *sym_hash = h;
+ if ((*sym_hash)->root.type == bfd_link_hash_indirect)
+ flip = *sym_hash;
+ else
+ /* This union may have been set to be non-NULL when this symbol
+ was seen in a dynamic object. We must force the union to be
+ NULL, so that it is correct for a regular symbol. */
+ h->verinfo.vertree = NULL;
}
/* Handle the special case of a new common symbol merging with an
@@ -849,7 +845,26 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
*size_change_ok = TRUE;
*type_change_ok = TRUE;
- h->verinfo.vertree = NULL;
+ if ((*sym_hash)->root.type == bfd_link_hash_indirect)
+ flip = *sym_hash;
+ else
+ h->verinfo.vertree = NULL;
+ }
+
+ if (flip != NULL)
+ {
+ /* Handle the case where we had a versioned symbol in a dynamic
+ library and now find a definition in a normal object. In this
+ case, we make the versioned symbol point to the normal one. */
+ flip->root.type = h->root.type;
+ flip->root.u.undef.abfd = h->root.u.undef.abfd;
+ h->root.type = bfd_link_hash_indirect;
+ h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
+ if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
+ {
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
+ flip->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ }
}
/* Handle the special case of a weak definition in a regular object
@@ -883,7 +898,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
/* Handle the special case of a non-weak definition in a shared
object followed by a weak definition in a regular object. In
- this case we prefer to definition in the shared object. To make
+ this case we prefer the definition in the shared object. To make
this work we have to tell the caller to not treat the new symbol
as a definition. */
if (olddef