* elf64-ppc.c (ppc_type_of_stub): Check both func desc and func

entry sym before deciding no stub is needed.
	(ppc64_elf_size_stubs): When calculating branch destination,
	don't use func desc sym for old ABI objects unless func entry
	is undefined.
This commit is contained in:
Alan Modra
2005-09-30 07:32:50 +00:00
parent 288424419e
commit 7fe2b9a6a6
2 changed files with 42 additions and 28 deletions

View File

@ -1,3 +1,11 @@
2005-09-30 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc_type_of_stub): Check both func desc and func
entry sym before deciding no stub is needed.
(ppc64_elf_size_stubs): When calculating branch destination,
don't use func desc sym for old ABI objects unless func entry
is undefined.
2005-09-28 H.J. Lu <hongjiu.lu@intel.com> 2005-09-28 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/1321 PR binutils/1321

View File

@ -7888,26 +7888,34 @@ ppc_type_of_stub (asection *input_sec,
if (h != NULL) if (h != NULL)
{ {
if (h->oh != NULL struct ppc_link_hash_entry *fdh = h;
&& h->oh->is_func_descriptor) if (fdh->oh != NULL
h = h->oh; && fdh->oh->is_func_descriptor)
fdh = fdh->oh;
if (h->elf.dynindx != -1) if (fdh->elf.dynindx != -1)
{ {
struct plt_entry *ent; struct plt_entry *ent;
for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next) for (ent = fdh->elf.plt.plist; ent != NULL; ent = ent->next)
if (ent->addend == rel->r_addend if (ent->addend == rel->r_addend
&& ent->plt.offset != (bfd_vma) -1) && ent->plt.offset != (bfd_vma) -1)
{ {
*hash = h; *hash = fdh;
return ppc_stub_plt_call; return ppc_stub_plt_call;
} }
} }
if (!(h->elf.root.type == bfd_link_hash_defined /* Here, we know we don't have a plt entry. If we don't have a
either a defined function descriptor or a defined entry symbol
in a regular object file, then it is pointless trying to make
any other type of stub. */
if (!((fdh->elf.root.type == bfd_link_hash_defined
|| fdh->elf.root.type == bfd_link_hash_defweak)
&& fdh->elf.root.u.def.section->output_section != NULL)
&& !((h->elf.root.type == bfd_link_hash_defined
|| h->elf.root.type == bfd_link_hash_defweak) || h->elf.root.type == bfd_link_hash_defweak)
|| h->elf.root.u.def.section->output_section == NULL) && h->elf.root.u.def.section->output_section != NULL))
return ppc_stub_none; return ppc_stub_none;
} }
@ -8951,16 +8959,25 @@ ppc64_elf_size_stubs (bfd *output_bfd,
ok_dest = FALSE; ok_dest = FALSE;
fdh = NULL; fdh = NULL;
sym_value = 0;
if (hash == NULL) if (hash == NULL)
{ {
sym_value = sym->st_value; sym_value = sym->st_value;
ok_dest = TRUE; ok_dest = TRUE;
} }
else else if (hash->elf.root.type == bfd_link_hash_defined
|| hash->elf.root.type == bfd_link_hash_defweak)
{
sym_value = hash->elf.root.u.def.value;
if (sym_sec->output_section != NULL)
ok_dest = TRUE;
}
else if (hash->elf.root.type == bfd_link_hash_undefweak
|| hash->elf.root.type == bfd_link_hash_undefined)
{ {
sym_value = 0;
/* Recognise an old ABI func code entry sym, and /* Recognise an old ABI func code entry sym, and
use the func descriptor sym instead. */ use the func descriptor sym instead if it is
defined. */
if (hash->elf.root.root.string[0] == '.' if (hash->elf.root.root.string[0] == '.'
&& (fdh = get_fdh (hash, htab)) != NULL) && (fdh = get_fdh (hash, htab)) != NULL)
{ {
@ -8975,23 +8992,12 @@ ppc64_elf_size_stubs (bfd *output_bfd,
else else
fdh = NULL; fdh = NULL;
} }
else if (hash->elf.root.type == bfd_link_hash_defined
|| hash->elf.root.type == bfd_link_hash_defweak)
{
sym_value = hash->elf.root.u.def.value;
if (sym_sec->output_section != NULL)
ok_dest = TRUE;
} }
else if (hash->elf.root.type == bfd_link_hash_undefweak)
;
else if (hash->elf.root.type == bfd_link_hash_undefined)
;
else else
{ {
bfd_set_error (bfd_error_bad_value); bfd_set_error (bfd_error_bad_value);
goto error_ret_free_internal; goto error_ret_free_internal;
} }
}
destination = 0; destination = 0;
if (ok_dest) if (ok_dest)