* elf64-ppc.c (struct ppc_link_hash_entry): Expand adjust_done comment.

(ppc64_elf_add_symbol_hook): Test for NULL section.
	(get_sym_h): Formatting.
	(ppc64_elf_size_stubs): Include reloc addend in value stored as
	stub target_value.
This commit is contained in:
Alan Modra
2004-08-09 05:38:48 +00:00
parent b25116a9c7
commit 8843416a51
2 changed files with 31 additions and 12 deletions

View File

@ -1,5 +1,11 @@
2004-08-09 Alan Modra <amodra@bigpond.net.au> 2004-08-09 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (struct ppc_link_hash_entry): Expand adjust_done comment.
(ppc64_elf_add_symbol_hook): Test for NULL section.
(get_sym_h): Formatting.
(ppc64_elf_size_stubs): Include reloc addend in value stored as
stub target_value.
* elf64-ppc.c (ppc64_elf_relocate_section): Combine handling of * elf64-ppc.c (ppc64_elf_relocate_section): Combine handling of
long branch stubs with code handling plt and r2off branch stubs. long branch stubs with code handling plt and r2off branch stubs.

View File

@ -2777,7 +2777,9 @@ struct ppc_link_hash_entry
unsigned int is_func:1; unsigned int is_func:1;
unsigned int is_func_descriptor:1; unsigned int is_func_descriptor:1;
/* Whether global opd sym has been adjusted or not. */ /* Whether global opd sym has been adjusted or not.
After ppc64_elf_edit_opd has run, this flag should be set for all
globals defined in any opd section. */
unsigned int adjust_done:1; unsigned int adjust_done:1;
/* Contexts in which symbol is used in the GOT (or TOC). /* Contexts in which symbol is used in the GOT (or TOC).
@ -3472,7 +3474,8 @@ ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
asection **sec, asection **sec,
bfd_vma *value ATTRIBUTE_UNUSED) bfd_vma *value ATTRIBUTE_UNUSED)
{ {
if (strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0) if (*sec != NULL
&& strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0)
isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC); isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
return TRUE; return TRUE;
} }
@ -4790,9 +4793,13 @@ ppc64_elf_hide_symbol (struct bfd_link_info *info,
} }
static bfd_boolean static bfd_boolean
get_sym_h (struct elf_link_hash_entry **hp, Elf_Internal_Sym **symp, get_sym_h (struct elf_link_hash_entry **hp,
asection **symsecp, char **tls_maskp, Elf_Internal_Sym **locsymsp, Elf_Internal_Sym **symp,
unsigned long r_symndx, bfd *ibfd) asection **symsecp,
char **tls_maskp,
Elf_Internal_Sym **locsymsp,
unsigned long r_symndx,
bfd *ibfd)
{ {
Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
@ -6938,6 +6945,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
asection *sym_sec; asection *sym_sec;
bfd_vma sym_value; bfd_vma sym_value;
bfd_vma destination; bfd_vma destination;
bfd_boolean ok_dest;
struct ppc_link_hash_entry *hash; struct ppc_link_hash_entry *hash;
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym; Elf_Internal_Sym *sym;
@ -6962,19 +6970,17 @@ ppc64_elf_size_stubs (bfd *output_bfd,
/* Now determine the call target, its name, value, /* Now determine the call target, its name, value,
section. */ section. */
destination = 0;
if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms, if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
r_indx, input_bfd)) r_indx, input_bfd))
goto error_ret_free_internal; goto error_ret_free_internal;
hash = (struct ppc_link_hash_entry *) h; hash = (struct ppc_link_hash_entry *) h;
ok_dest = FALSE;
if (hash == NULL) if (hash == NULL)
{ {
/* It's a local symbol. */ /* It's a local symbol. */
sym_value = sym->st_value; sym_value = sym->st_value;
destination = (sym_value + irela->r_addend ok_dest = TRUE;
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
} }
else else
{ {
@ -6985,9 +6991,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
{ {
sym_value = hash->elf.root.u.def.value; sym_value = hash->elf.root.u.def.value;
if (sym_sec->output_section != NULL) if (sym_sec->output_section != NULL)
destination = (sym_value + irela->r_addend ok_dest = TRUE;
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
} }
else if (hash->elf.root.type == bfd_link_hash_undefweak) else if (hash->elf.root.type == bfd_link_hash_undefweak)
; ;
@ -7000,6 +7004,15 @@ ppc64_elf_size_stubs (bfd *output_bfd,
} }
} }
destination = 0;
if (ok_dest)
{
sym_value += irela->r_addend;
destination = (sym_value
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
}
/* Determine what (if any) linker stub is needed. */ /* Determine what (if any) linker stub is needed. */
stub_type = ppc_type_of_stub (section, irela, &hash, stub_type = ppc_type_of_stub (section, irela, &hash,
destination); destination);