summaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2005-02-03 14:48:53 +0000
committerAlan Modra <amodra@bigpond.net.au>2005-02-03 14:48:53 +0000
commit11a6c11130b40bbd3602852f83b0c0d2403ba2df (patch)
tree15a397f41ec16f1197f7d33b1a5330f5079fd2dc /bfd/elf64-ppc.c
parent036036c57ba1a06ad6418422ae3cda1abb7023fa (diff)
downloadgdb-11a6c11130b40bbd3602852f83b0c0d2403ba2df.tar.gz
* elf64-ppc.c (struct ppc_link_hash_entry): Add "fake".
(link_hash_newfunc): Clear all locals using memset. (make_fdh): Remove flags param. Always create fake func desc weak. Link the descriptor with the code entry sym. (ppc64_elf_archive_symbol_lookup): Don't return fake syms. (add_symbol_adjust): Adjust make_fdh call. (func_desc_adjust): Likewise. Twiddle any pre-existing fake descriptor to strong undefined if code entry is strong.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 54396713633..cc460870429 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -3208,6 +3208,7 @@ struct ppc_link_hash_entry
/* Flag function code and descriptor symbols. */
unsigned int is_func:1;
unsigned int is_func_descriptor:1;
+ unsigned int fake:1;
/* Whether global opd/toc sym has been adjusted or not.
After ppc64_elf_edit_opd/ppc64_elf_edit_toc has run, this flag
@@ -3430,14 +3431,9 @@ link_hash_newfunc (struct bfd_hash_entry *entry,
{
struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) entry;
- eh->stub_cache = NULL;
- eh->dyn_relocs = NULL;
- eh->oh = NULL;
- eh->is_func = 0;
- eh->is_func_descriptor = 0;
- eh->adjust_done = 0;
- eh->was_undefined = 0;
- eh->tls_mask = 0;
+ memset (&eh->stub_cache, 0,
+ (sizeof (struct ppc_link_hash_entry)
+ - offsetof (struct ppc_link_hash_entry, stub_cache)));
}
return entry;
@@ -3941,8 +3937,7 @@ get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
static struct ppc_link_hash_entry *
make_fdh (struct bfd_link_info *info,
- struct ppc_link_hash_entry *fh,
- flagword flags)
+ struct ppc_link_hash_entry *fh)
{
bfd *abfd;
asymbol *newsym;
@@ -3954,7 +3949,7 @@ make_fdh (struct bfd_link_info *info,
newsym->name = fh->elf.root.root.string + 1;
newsym->section = bfd_und_section_ptr;
newsym->value = 0;
- newsym->flags = flags;
+ newsym->flags = BSF_WEAK;
bh = NULL;
if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
@@ -3965,6 +3960,11 @@ make_fdh (struct bfd_link_info *info,
fdh = (struct ppc_link_hash_entry *) bh;
fdh->elf.non_elf = 0;
+ fdh->fake = 1;
+ fdh->is_func_descriptor = 1;
+ fdh->oh = fh;
+ fh->is_func = 1;
+ fh->oh = fdh;
return fdh;
}
@@ -4002,7 +4002,9 @@ ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
}
/* This function makes an old ABI object reference to ".bar" cause the
- inclusion of a new ABI object archive that defines "bar". */
+ inclusion of a new ABI object archive that defines "bar".
+ NAME is a symbol defined in an archive. Return a symbol in the hash
+ table that might be satisfied by the archive symbols. */
static struct elf_link_hash_entry *
ppc64_elf_archive_symbol_lookup (bfd *abfd,
@@ -4014,7 +4016,11 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
size_t len;
h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
- if (h != NULL)
+ if (h != NULL
+ /* Don't return this sym if it is a fake function descriptor
+ created by add_symbol_adjust. */
+ && !(h->root.type == bfd_link_hash_undefweak
+ && ((struct ppc_link_hash_entry *) h)->fake))
return h;
if (name[0] == '.')
@@ -4075,7 +4081,7 @@ add_symbol_adjust (struct elf_link_hash_entry *h, void *inf)
/* Make an undefweak function descriptor sym, which is enough to
pull in an --as-needed shared lib, but won't cause link
errors. Archives are handled elsewhere. */
- fdh = make_fdh (data->info, eh, BSF_WEAK);
+ fdh = make_fdh (data->info, eh);
if (fdh == NULL)
data->ok = FALSE;
else
@@ -5414,14 +5420,23 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
&& (fh->elf.root.type == bfd_link_hash_undefined
|| fh->elf.root.type == bfd_link_hash_undefweak))
{
- flagword flags = 0;
- if (fh->elf.root.type == bfd_link_hash_undefweak)
- flags = BSF_WEAK;
- fdh = make_fdh (info, fh, flags);
+ fdh = make_fdh (info, fh);
if (fdh == NULL)
return FALSE;
}
+ /* Fake function descriptors are made undefweak. If the function
+ code symbol is strong undefined, make the fake sym the same. */
+
+ if (fdh != NULL
+ && fdh->fake
+ && fdh->elf.root.type == bfd_link_hash_undefweak
+ && fh->elf.root.type == bfd_link_hash_undefined)
+ {
+ fdh->elf.root.type = bfd_link_hash_undefined;
+ bfd_link_add_undef (&htab->elf.root, &fdh->elf.root);
+ }
+
if (fdh != NULL
&& !fdh->elf.forced_local
&& (info->shared