mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
bfd/
* elf64-ppc.c (follow_link, elf_follow_link, ppc_follow_link): New functions. Use throughout. (ppc64_elf_copy_indirect_symbol): Set direct symbol "oh" field from indirect symbol. (lookup_fdh): Rename from get_fdh. Follow indirect sym links. (add_symbol_adjust): Simplify. (defined_code_entry, defined_func_desc): New functions. (ppc64_elf_gc_keep): Follow indirect sym links. Use defined_code_entry. (ppc64_elf_gc_mark_dynamic_ref): Use defined_func_desc and defined_code_entry to follow indirect sym links. (ppc64_elf_gc_mark_hook, func_desc_adjust): Likewise. (ppc_type_of_stub): Follow indirect sym links. (toc_adjusting_stub_needed): Likewise. (ppc_build_one_stub): Likewise. Make undefined dot-symbols weak rather than defining them at stub. (ppc64_elf_relocate_section): Rewrite call test to avoid multiple assignments in test. ld/testsuite/ * ld-powerpc/tlsso.d: Update. * ld-powerpc/tlsso.r: Update. * ld-powerpc/tlstocso.d: Update. * ld-powerpc/tlstocso.r: Update.
This commit is contained in:
@ -1,3 +1,23 @@
|
|||||||
|
2009-09-18 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf64-ppc.c (follow_link, elf_follow_link, ppc_follow_link): New
|
||||||
|
functions. Use throughout.
|
||||||
|
(ppc64_elf_copy_indirect_symbol): Set direct symbol "oh" field
|
||||||
|
from indirect symbol.
|
||||||
|
(lookup_fdh): Rename from get_fdh. Follow indirect sym links.
|
||||||
|
(add_symbol_adjust): Simplify.
|
||||||
|
(defined_code_entry, defined_func_desc): New functions.
|
||||||
|
(ppc64_elf_gc_keep): Follow indirect sym links. Use defined_code_entry.
|
||||||
|
(ppc64_elf_gc_mark_dynamic_ref): Use defined_func_desc and
|
||||||
|
defined_code_entry to follow indirect sym links.
|
||||||
|
(ppc64_elf_gc_mark_hook, func_desc_adjust): Likewise.
|
||||||
|
(ppc_type_of_stub): Follow indirect sym links.
|
||||||
|
(toc_adjusting_stub_needed): Likewise.
|
||||||
|
(ppc_build_one_stub): Likewise. Make undefined dot-symbols weak
|
||||||
|
rather than defining them at stub.
|
||||||
|
(ppc64_elf_relocate_section): Rewrite call test to avoid multiple
|
||||||
|
assignments in test.
|
||||||
|
|
||||||
2009-09-16 Tristan Gingold <gingold@adacore.com>
|
2009-09-16 Tristan Gingold <gingold@adacore.com>
|
||||||
|
|
||||||
* mach-o.h (bfd_mach_o_filetype): Add new constants from darwin10.
|
* mach-o.h (bfd_mach_o_filetype): Add new constants from darwin10.
|
||||||
|
251
bfd/elf64-ppc.c
251
bfd/elf64-ppc.c
@ -4282,6 +4282,29 @@ ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Follow indirect and warning symbol links. */
|
||||||
|
|
||||||
|
static inline struct bfd_link_hash_entry *
|
||||||
|
follow_link (struct bfd_link_hash_entry *h)
|
||||||
|
{
|
||||||
|
while (h->type == bfd_link_hash_indirect
|
||||||
|
|| h->type == bfd_link_hash_warning)
|
||||||
|
h = h->u.i.link;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct elf_link_hash_entry *
|
||||||
|
elf_follow_link (struct elf_link_hash_entry *h)
|
||||||
|
{
|
||||||
|
return (struct elf_link_hash_entry *) follow_link (&h->root);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct ppc_link_hash_entry *
|
||||||
|
ppc_follow_link (struct ppc_link_hash_entry *h)
|
||||||
|
{
|
||||||
|
return (struct ppc_link_hash_entry *) follow_link (&h->elf.root);
|
||||||
|
}
|
||||||
|
|
||||||
/* Merge PLT info on FROM with that on TO. */
|
/* Merge PLT info on FROM with that on TO. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -4364,6 +4387,8 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
|||||||
edir->is_func |= eind->is_func;
|
edir->is_func |= eind->is_func;
|
||||||
edir->is_func_descriptor |= eind->is_func_descriptor;
|
edir->is_func_descriptor |= eind->is_func_descriptor;
|
||||||
edir->tls_mask |= eind->tls_mask;
|
edir->tls_mask |= eind->tls_mask;
|
||||||
|
if (eind->oh != NULL)
|
||||||
|
edir->oh = ppc_follow_link (eind->oh);
|
||||||
|
|
||||||
/* If called to transfer flags for a weakdef during processing
|
/* If called to transfer flags for a weakdef during processing
|
||||||
of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
|
of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
|
||||||
@ -4433,7 +4458,7 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
|
|||||||
hash entry FH. Link the entries via their OH fields. */
|
hash entry FH. Link the entries via their OH fields. */
|
||||||
|
|
||||||
static struct ppc_link_hash_entry *
|
static struct ppc_link_hash_entry *
|
||||||
get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
|
lookup_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
|
||||||
{
|
{
|
||||||
struct ppc_link_hash_entry *fdh = fh->oh;
|
struct ppc_link_hash_entry *fdh = fh->oh;
|
||||||
|
|
||||||
@ -4443,16 +4468,16 @@ get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
|
|||||||
|
|
||||||
fdh = (struct ppc_link_hash_entry *)
|
fdh = (struct ppc_link_hash_entry *)
|
||||||
elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
|
elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
|
||||||
if (fdh != NULL)
|
if (fdh == NULL)
|
||||||
{
|
return fdh;
|
||||||
fdh->is_func_descriptor = 1;
|
|
||||||
fdh->oh = fh;
|
fdh->is_func_descriptor = 1;
|
||||||
fh->is_func = 1;
|
fdh->oh = fh;
|
||||||
fh->oh = fdh;
|
fh->is_func = 1;
|
||||||
}
|
fh->oh = fdh;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fdh;
|
return ppc_follow_link (fdh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a fake function descriptor sym for the code sym FH. */
|
/* Make a fake function descriptor sym for the code sym FH. */
|
||||||
@ -4574,23 +4599,24 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
|
|||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
htab = ppc_hash_table (info);
|
htab = ppc_hash_table (info);
|
||||||
fdh = get_fdh (eh, htab);
|
fdh = lookup_fdh (eh, htab);
|
||||||
if (fdh == NULL
|
if (fdh == NULL)
|
||||||
&& !info->relocatable
|
|
||||||
&& (eh->elf.root.type == bfd_link_hash_undefined
|
|
||||||
|| eh->elf.root.type == bfd_link_hash_undefweak)
|
|
||||||
&& eh->elf.ref_regular)
|
|
||||||
{
|
{
|
||||||
/* Make an undefweak function descriptor sym, which is enough to
|
if (!info->relocatable
|
||||||
pull in an --as-needed shared lib, but won't cause link
|
&& (eh->elf.root.type == bfd_link_hash_undefined
|
||||||
errors. Archives are handled elsewhere. */
|
|| eh->elf.root.type == bfd_link_hash_undefweak)
|
||||||
fdh = make_fdh (info, eh);
|
&& eh->elf.ref_regular)
|
||||||
if (fdh == NULL)
|
{
|
||||||
return FALSE;
|
/* Make an undefweak function descriptor sym, which is enough to
|
||||||
else
|
pull in an --as-needed shared lib, but won't cause link
|
||||||
fdh->elf.ref_regular = 1;
|
errors. Archives are handled elsewhere. */
|
||||||
|
fdh = make_fdh (info, eh);
|
||||||
|
if (fdh == NULL)
|
||||||
|
return FALSE;
|
||||||
|
fdh->elf.ref_regular = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (fdh != NULL)
|
else
|
||||||
{
|
{
|
||||||
unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
|
unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
|
||||||
unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
|
unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
|
||||||
@ -4839,9 +4865,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
while (h->root.type == bfd_link_hash_indirect
|
h = elf_follow_link (h);
|
||||||
|| h->root.type == bfd_link_hash_warning)
|
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_type = 0;
|
tls_type = 0;
|
||||||
@ -5199,7 +5223,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
{
|
{
|
||||||
if (h->root.root.string[0] == '.'
|
if (h->root.root.string[0] == '.'
|
||||||
&& h->root.root.string[1] != 0
|
&& h->root.root.string[1] != 0
|
||||||
&& get_fdh ((struct ppc_link_hash_entry *) h, htab))
|
&& lookup_fdh ((struct ppc_link_hash_entry *) h, htab))
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
((struct ppc_link_hash_entry *) h)->is_func = 1;
|
((struct ppc_link_hash_entry *) h)->is_func = 1;
|
||||||
@ -5452,9 +5476,7 @@ opd_entry_value (asection *opd_sec,
|
|||||||
|
|
||||||
sym_hashes = elf_sym_hashes (opd_bfd);
|
sym_hashes = elf_sym_hashes (opd_bfd);
|
||||||
rh = sym_hashes[symndx - symtab_hdr->sh_info];
|
rh = sym_hashes[symndx - symtab_hdr->sh_info];
|
||||||
while (rh->root.type == bfd_link_hash_indirect
|
rh = elf_follow_link (rh);
|
||||||
|| rh->root.type == bfd_link_hash_warning)
|
|
||||||
rh = ((struct elf_link_hash_entry *) rh->root.u.i.link);
|
|
||||||
BFD_ASSERT (rh->root.type == bfd_link_hash_defined
|
BFD_ASSERT (rh->root.type == bfd_link_hash_defined
|
||||||
|| rh->root.type == bfd_link_hash_defweak);
|
|| rh->root.type == bfd_link_hash_defweak);
|
||||||
val = rh->root.u.def.value;
|
val = rh->root.u.def.value;
|
||||||
@ -5475,6 +5497,39 @@ opd_entry_value (asection *opd_sec,
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If FDH is a function descriptor symbol, return the associated code
|
||||||
|
entry symbol if it is defined. Return NULL otherwise. */
|
||||||
|
|
||||||
|
static struct ppc_link_hash_entry *
|
||||||
|
defined_code_entry (struct ppc_link_hash_entry *fdh)
|
||||||
|
{
|
||||||
|
if (fdh->is_func_descriptor)
|
||||||
|
{
|
||||||
|
struct ppc_link_hash_entry *fh = ppc_follow_link (fdh->oh);
|
||||||
|
if (fh->elf.root.type == bfd_link_hash_defined
|
||||||
|
|| fh->elf.root.type == bfd_link_hash_defweak)
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If FH is a function code entry symbol, return the associated
|
||||||
|
function descriptor symbol if it is defined. Return NULL otherwise. */
|
||||||
|
|
||||||
|
static struct ppc_link_hash_entry *
|
||||||
|
defined_func_desc (struct ppc_link_hash_entry *fh)
|
||||||
|
{
|
||||||
|
if (fh->oh != NULL
|
||||||
|
&& fh->oh->is_func_descriptor)
|
||||||
|
{
|
||||||
|
struct ppc_link_hash_entry *fdh = ppc_follow_link (fh->oh);
|
||||||
|
if (fdh->elf.root.type == bfd_link_hash_defined
|
||||||
|
|| fdh->elf.root.type == bfd_link_hash_defweak)
|
||||||
|
return fdh;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark all our entry sym sections, both opd and code section. */
|
/* Mark all our entry sym sections, both opd and code section. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5485,22 +5540,21 @@ ppc64_elf_gc_keep (struct bfd_link_info *info)
|
|||||||
|
|
||||||
for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
|
for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
|
||||||
{
|
{
|
||||||
struct ppc_link_hash_entry *eh;
|
struct ppc_link_hash_entry *eh, *fh;
|
||||||
asection *sec;
|
asection *sec;
|
||||||
|
|
||||||
eh = (struct ppc_link_hash_entry *)
|
eh = (struct ppc_link_hash_entry *)
|
||||||
elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
|
elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, TRUE);
|
||||||
if (eh == NULL)
|
if (eh == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (eh->elf.root.type != bfd_link_hash_defined
|
if (eh->elf.root.type != bfd_link_hash_defined
|
||||||
&& eh->elf.root.type != bfd_link_hash_defweak)
|
&& eh->elf.root.type != bfd_link_hash_defweak)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (eh->is_func_descriptor
|
fh = defined_code_entry (eh);
|
||||||
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|
if (fh != NULL)
|
||||||
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
|
|
||||||
{
|
{
|
||||||
sec = eh->oh->elf.root.u.def.section;
|
sec = fh->elf.root.u.def.section;
|
||||||
sec->flags |= SEC_KEEP;
|
sec->flags |= SEC_KEEP;
|
||||||
}
|
}
|
||||||
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
||||||
@ -5523,16 +5577,15 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
|
|||||||
{
|
{
|
||||||
struct bfd_link_info *info = (struct bfd_link_info *) inf;
|
struct bfd_link_info *info = (struct bfd_link_info *) inf;
|
||||||
struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
|
struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
|
||||||
|
struct ppc_link_hash_entry *fdh;
|
||||||
|
|
||||||
if (eh->elf.root.type == bfd_link_hash_warning)
|
if (eh->elf.root.type == bfd_link_hash_warning)
|
||||||
eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link;
|
eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link;
|
||||||
|
|
||||||
/* Dynamic linking info is on the func descriptor sym. */
|
/* Dynamic linking info is on the func descriptor sym. */
|
||||||
if (eh->oh != NULL
|
fdh = defined_func_desc (eh);
|
||||||
&& eh->oh->is_func_descriptor
|
if (fdh != NULL)
|
||||||
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|
eh = fdh;
|
||||||
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
|
|
||||||
eh = eh->oh;
|
|
||||||
|
|
||||||
if ((eh->elf.root.type == bfd_link_hash_defined
|
if ((eh->elf.root.type == bfd_link_hash_defined
|
||||||
|| eh->elf.root.type == bfd_link_hash_defweak)
|
|| eh->elf.root.type == bfd_link_hash_defweak)
|
||||||
@ -5543,15 +5596,18 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
|
|||||||
&& ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN)))
|
&& ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN)))
|
||||||
{
|
{
|
||||||
asection *code_sec;
|
asection *code_sec;
|
||||||
|
struct ppc_link_hash_entry *fh;
|
||||||
|
|
||||||
eh->elf.root.u.def.section->flags |= SEC_KEEP;
|
eh->elf.root.u.def.section->flags |= SEC_KEEP;
|
||||||
|
|
||||||
/* Function descriptor syms cause the associated
|
/* Function descriptor syms cause the associated
|
||||||
function code sym section to be marked. */
|
function code sym section to be marked. */
|
||||||
if (eh->is_func_descriptor
|
fh = defined_code_entry (eh);
|
||||||
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|
if (fh != NULL)
|
||||||
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
|
{
|
||||||
eh->oh->elf.root.u.def.section->flags |= SEC_KEEP;
|
code_sec = fh->elf.root.u.def.section;
|
||||||
|
code_sec->flags |= SEC_KEEP;
|
||||||
|
}
|
||||||
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
||||||
&& opd_entry_value (eh->elf.root.u.def.section,
|
&& opd_entry_value (eh->elf.root.u.def.section,
|
||||||
eh->elf.root.u.def.value,
|
eh->elf.root.u.def.value,
|
||||||
@ -5583,7 +5639,7 @@ ppc64_elf_gc_mark_hook (asection *sec,
|
|||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
enum elf_ppc64_reloc_type r_type;
|
enum elf_ppc64_reloc_type r_type;
|
||||||
struct ppc_link_hash_entry *eh;
|
struct ppc_link_hash_entry *eh, *fh, *fdh;
|
||||||
|
|
||||||
r_type = ELF64_R_TYPE (rel->r_info);
|
r_type = ELF64_R_TYPE (rel->r_info);
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
@ -5598,22 +5654,19 @@ ppc64_elf_gc_mark_hook (asection *sec,
|
|||||||
case bfd_link_hash_defined:
|
case bfd_link_hash_defined:
|
||||||
case bfd_link_hash_defweak:
|
case bfd_link_hash_defweak:
|
||||||
eh = (struct ppc_link_hash_entry *) h;
|
eh = (struct ppc_link_hash_entry *) h;
|
||||||
if (eh->oh != NULL
|
fdh = defined_func_desc (eh);
|
||||||
&& eh->oh->is_func_descriptor
|
if (fdh != NULL)
|
||||||
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|
eh = fdh;
|
||||||
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
|
|
||||||
eh = eh->oh;
|
|
||||||
|
|
||||||
/* Function descriptor syms cause the associated
|
/* Function descriptor syms cause the associated
|
||||||
function code sym section to be marked. */
|
function code sym section to be marked. */
|
||||||
if (eh->is_func_descriptor
|
fh = defined_code_entry (eh);
|
||||||
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|
if (fh != NULL)
|
||||||
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
|
|
||||||
{
|
{
|
||||||
/* They also mark their opd section. */
|
/* They also mark their opd section. */
|
||||||
eh->elf.root.u.def.section->gc_mark = 1;
|
eh->elf.root.u.def.section->gc_mark = 1;
|
||||||
|
|
||||||
rsec = eh->oh->elf.root.u.def.section;
|
rsec = fh->elf.root.u.def.section;
|
||||||
}
|
}
|
||||||
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
||||||
&& opd_entry_value (eh->elf.root.u.def.section,
|
&& opd_entry_value (eh->elf.root.u.def.section,
|
||||||
@ -5693,9 +5746,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
|||||||
struct ppc_dyn_relocs *p;
|
struct ppc_dyn_relocs *p;
|
||||||
|
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
while (h->root.type == bfd_link_hash_indirect
|
h = elf_follow_link (h);
|
||||||
|| h->root.type == bfd_link_hash_warning)
|
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
|
||||||
eh = (struct ppc_link_hash_entry *) h;
|
eh = (struct ppc_link_hash_entry *) h;
|
||||||
|
|
||||||
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
|
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
|
||||||
@ -6081,18 +6132,17 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
|
|||||||
in dynamic objects are handled elsewhere. */
|
in dynamic objects are handled elsewhere. */
|
||||||
if (fh->elf.root.type == bfd_link_hash_undefweak
|
if (fh->elf.root.type == bfd_link_hash_undefweak
|
||||||
&& fh->was_undefined
|
&& fh->was_undefined
|
||||||
&& (fh->oh->elf.root.type == bfd_link_hash_defined
|
&& (fdh = defined_func_desc (fh)) != NULL
|
||||||
|| fh->oh->elf.root.type == bfd_link_hash_defweak)
|
&& get_opd_info (fdh->elf.root.u.def.section) != NULL
|
||||||
&& get_opd_info (fh->oh->elf.root.u.def.section) != NULL
|
&& opd_entry_value (fdh->elf.root.u.def.section,
|
||||||
&& opd_entry_value (fh->oh->elf.root.u.def.section,
|
fdh->elf.root.u.def.value,
|
||||||
fh->oh->elf.root.u.def.value,
|
|
||||||
&fh->elf.root.u.def.section,
|
&fh->elf.root.u.def.section,
|
||||||
&fh->elf.root.u.def.value) != (bfd_vma) -1)
|
&fh->elf.root.u.def.value) != (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
fh->elf.root.type = fh->oh->elf.root.type;
|
fh->elf.root.type = fdh->elf.root.type;
|
||||||
fh->elf.forced_local = 1;
|
fh->elf.forced_local = 1;
|
||||||
fh->elf.def_regular = fh->oh->elf.def_regular;
|
fh->elf.def_regular = fdh->elf.def_regular;
|
||||||
fh->elf.def_dynamic = fh->oh->elf.def_dynamic;
|
fh->elf.def_dynamic = fdh->elf.def_dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a function code symbol, transfer dynamic linking
|
/* If this is a function code symbol, transfer dynamic linking
|
||||||
@ -6111,12 +6161,7 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
|
|||||||
/* Find the corresponding function descriptor symbol. Create it
|
/* Find the corresponding function descriptor symbol. Create it
|
||||||
as undefined if necessary. */
|
as undefined if necessary. */
|
||||||
|
|
||||||
fdh = get_fdh (fh, htab);
|
fdh = lookup_fdh (fh, htab);
|
||||||
if (fdh != NULL)
|
|
||||||
while (fdh->elf.root.type == bfd_link_hash_indirect
|
|
||||||
|| fdh->elf.root.type == bfd_link_hash_warning)
|
|
||||||
fdh = (struct ppc_link_hash_entry *) fdh->elf.root.u.i.link;
|
|
||||||
|
|
||||||
if (fdh == NULL
|
if (fdh == NULL
|
||||||
&& !info->executable
|
&& !info->executable
|
||||||
&& (fh->elf.root.type == bfd_link_hash_undefined
|
&& (fh->elf.root.type == bfd_link_hash_undefined
|
||||||
@ -6454,9 +6499,7 @@ get_sym_h (struct elf_link_hash_entry **hp,
|
|||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
|
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
while (h->root.type == bfd_link_hash_indirect
|
h = elf_follow_link (h);
|
||||||
|| h->root.type == bfd_link_hash_warning)
|
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
|
||||||
|
|
||||||
if (hp != NULL)
|
if (hp != NULL)
|
||||||
*hp = h;
|
*hp = h;
|
||||||
@ -7024,8 +7067,8 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
|
|||||||
if (h != NULL
|
if (h != NULL
|
||||||
&& h->root.root.string[0] == '.')
|
&& h->root.root.string[0] == '.')
|
||||||
{
|
{
|
||||||
fdh = get_fdh ((struct ppc_link_hash_entry *) h,
|
fdh = lookup_fdh ((struct ppc_link_hash_entry *) h,
|
||||||
ppc_hash_table (info));
|
ppc_hash_table (info));
|
||||||
if (fdh != NULL
|
if (fdh != NULL
|
||||||
&& fdh->elf.root.type != bfd_link_hash_defined
|
&& fdh->elf.root.type != bfd_link_hash_defined
|
||||||
&& fdh->elf.root.type != bfd_link_hash_defweak)
|
&& fdh->elf.root.type != bfd_link_hash_defweak)
|
||||||
@ -7208,9 +7251,7 @@ branch_reloc_hash_match (const bfd *ibfd,
|
|||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
|
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
while (h->root.type == bfd_link_hash_indirect
|
h = elf_follow_link (h);
|
||||||
|| h->root.type == bfd_link_hash_warning)
|
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
|
||||||
if (h == &hash1->elf || h == &hash2->elf)
|
if (h == &hash1->elf || h == &hash2->elf)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -8668,9 +8709,9 @@ ppc_type_of_stub (asection *input_sec,
|
|||||||
{
|
{
|
||||||
struct plt_entry *ent;
|
struct plt_entry *ent;
|
||||||
struct ppc_link_hash_entry *fdh = h;
|
struct ppc_link_hash_entry *fdh = h;
|
||||||
if (fdh->oh != NULL
|
if (h->oh != NULL
|
||||||
&& fdh->oh->is_func_descriptor)
|
&& h->oh->is_func_descriptor)
|
||||||
fdh = fdh->oh;
|
fdh = ppc_follow_link (h->oh);
|
||||||
|
|
||||||
for (ent = fdh->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
|
||||||
@ -8944,7 +8985,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
hashes[symndx] = &h->elf;
|
hashes[symndx] = &h->elf;
|
||||||
r->r_info = ELF64_R_INFO (symndx, R_PPC64_REL24);
|
r->r_info = ELF64_R_INFO (symndx, R_PPC64_REL24);
|
||||||
if (h->oh != NULL && h->oh->is_func)
|
if (h->oh != NULL && h->oh->is_func)
|
||||||
h = h->oh;
|
h = ppc_follow_link (h->oh);
|
||||||
if (h->elf.root.u.def.section != stub_entry->target_section)
|
if (h->elf.root.u.def.section != stub_entry->target_section)
|
||||||
/* H is an opd symbol. The addend must be zero. */
|
/* H is an opd symbol. The addend must be zero. */
|
||||||
r->r_addend = 0;
|
r->r_addend = 0;
|
||||||
@ -9109,22 +9150,20 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ppc_stub_plt_call:
|
case ppc_stub_plt_call:
|
||||||
/* Do the best we can for shared libraries built without
|
|
||||||
exporting ".foo" for each "foo". This can happen when symbol
|
|
||||||
versioning scripts strip all bar a subset of symbols. */
|
|
||||||
if (stub_entry->h != NULL
|
if (stub_entry->h != NULL
|
||||||
&& stub_entry->h->oh != NULL
|
&& stub_entry->h->is_func_descriptor
|
||||||
&& stub_entry->h->oh->elf.root.type != bfd_link_hash_defined
|
&& stub_entry->h->oh != NULL)
|
||||||
&& stub_entry->h->oh->elf.root.type != bfd_link_hash_defweak)
|
|
||||||
{
|
{
|
||||||
/* Point the symbol at the stub. There may be multiple stubs,
|
struct ppc_link_hash_entry *fh = ppc_follow_link (stub_entry->h->oh);
|
||||||
we don't really care; The main thing is to make this sym
|
|
||||||
defined somewhere. Maybe defining the symbol in the stub
|
/* If the old-ABI "dot-symbol" is undefined make it weak so
|
||||||
section is a silly idea. If we didn't do this, htab->top_id
|
we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL.
|
||||||
could disappear. */
|
FIXME: We used to define the symbol on one of the call
|
||||||
stub_entry->h->oh->elf.root.type = bfd_link_hash_defined;
|
stubs instead, which is why we test symbol section id
|
||||||
stub_entry->h->oh->elf.root.u.def.section = stub_entry->stub_sec;
|
against htab->top_id in various places. Likely all
|
||||||
stub_entry->h->oh->elf.root.u.def.value = stub_entry->stub_offset;
|
these checks could now disappear. */
|
||||||
|
if (fh->elf.root.type == bfd_link_hash_undefined)
|
||||||
|
fh->elf.root.type = bfd_link_hash_undefweak;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now build the stub. */
|
/* Now build the stub. */
|
||||||
@ -9561,7 +9600,7 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
|
|||||||
if (eh != NULL
|
if (eh != NULL
|
||||||
&& (eh->elf.plt.plist != NULL
|
&& (eh->elf.plt.plist != NULL
|
||||||
|| (eh->oh != NULL
|
|| (eh->oh != NULL
|
||||||
&& eh->oh->elf.plt.plist != NULL)))
|
&& ppc_follow_link (eh->oh)->elf.plt.plist != NULL)))
|
||||||
{
|
{
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
@ -10000,7 +10039,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||||||
use the func descriptor sym instead if it is
|
use the func descriptor sym instead if it is
|
||||||
defined. */
|
defined. */
|
||||||
if (hash->elf.root.root.string[0] == '.'
|
if (hash->elf.root.root.string[0] == '.'
|
||||||
&& (fdh = get_fdh (hash, htab)) != NULL)
|
&& (fdh = lookup_fdh (hash, htab)) != NULL)
|
||||||
{
|
{
|
||||||
if (fdh->elf.root.type == bfd_link_hash_defined
|
if (fdh->elf.root.type == bfd_link_hash_defined
|
||||||
|| fdh->elf.root.type == bfd_link_hash_defweak)
|
|| fdh->elf.root.type == bfd_link_hash_defweak)
|
||||||
@ -11188,10 +11227,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
base pointer. */
|
base pointer. */
|
||||||
stub_entry = NULL;
|
stub_entry = NULL;
|
||||||
fdh = h;
|
fdh = h;
|
||||||
if (((h != NULL
|
if (h != NULL
|
||||||
&& (((fdh = h->oh) != NULL
|
&& h->oh != NULL
|
||||||
&& fdh->elf.plt.plist != NULL)
|
&& h->oh->is_func_descriptor)
|
||||||
|| (fdh = h)->elf.plt.plist != NULL))
|
fdh = ppc_follow_link (h->oh);
|
||||||
|
if (((fdh != NULL
|
||||||
|
&& fdh->elf.plt.plist != NULL)
|
||||||
|| (sec != NULL
|
|| (sec != NULL
|
||||||
&& sec->output_section != NULL
|
&& sec->output_section != NULL
|
||||||
&& sec->id <= htab->top_id
|
&& sec->id <= htab->top_id
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2009-09-18 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* ld-powerpc/tlsso.d: Update.
|
||||||
|
* ld-powerpc/tlsso.r: Update.
|
||||||
|
* ld-powerpc/tlstocso.d: Update.
|
||||||
|
* ld-powerpc/tlstocso.r: Update.
|
||||||
|
|
||||||
2009-09-15 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
2009-09-15 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||||
|
|
||||||
* ld-elfcomm/elfcomm.exp: Add appropriate emulation option
|
* ld-elfcomm/elfcomm.exp: Add appropriate emulation option
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Disassembly of section \.text:
|
Disassembly of section \.text:
|
||||||
|
|
||||||
.* <\.__tls_get_addr>:
|
.*:
|
||||||
.* f8 41 00 28 std r2,40\(r1\)
|
.* f8 41 00 28 std r2,40\(r1\)
|
||||||
.* e9 62 80 78 ld r11,-32648\(r2\)
|
.* e9 62 80 78 ld r11,-32648\(r2\)
|
||||||
.* 7d 69 03 a6 mtctr r11
|
.* 7d 69 03 a6 mtctr r11
|
||||||
@ -18,16 +18,16 @@ Disassembly of section \.text:
|
|||||||
|
|
||||||
.* <_start>:
|
.* <_start>:
|
||||||
.* 38 62 80 20 addi r3,r2,-32736
|
.* 38 62 80 20 addi r3,r2,-32736
|
||||||
.* 4b ff ff e5 bl .* <\.__tls_get_addr>
|
.* 4b ff ff e5 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 50 addi r3,r2,-32688
|
.* 38 62 80 50 addi r3,r2,-32688
|
||||||
.* 4b ff ff d9 bl .* <\.__tls_get_addr>
|
.* 4b ff ff d9 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 38 addi r3,r2,-32712
|
.* 38 62 80 38 addi r3,r2,-32712
|
||||||
.* 4b ff ff cd bl .* <\.__tls_get_addr>
|
.* 4b ff ff cd bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 50 addi r3,r2,-32688
|
.* 38 62 80 50 addi r3,r2,-32688
|
||||||
.* 4b ff ff c1 bl .* <\.__tls_get_addr>
|
.* 4b ff ff c1 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 39 23 80 40 addi r9,r3,-32704
|
.* 39 23 80 40 addi r9,r3,-32704
|
||||||
.* 3d 23 00 00 addis r9,r3,0
|
.* 3d 23 00 00 addis r9,r3,0
|
||||||
@ -40,10 +40,10 @@ Disassembly of section \.text:
|
|||||||
.* 3d 2d 00 00 addis r9,r13,0
|
.* 3d 2d 00 00 addis r9,r13,0
|
||||||
.* 99 49 00 00 stb r10,0\(r9\)
|
.* 99 49 00 00 stb r10,0\(r9\)
|
||||||
.* 38 62 80 08 addi r3,r2,-32760
|
.* 38 62 80 08 addi r3,r2,-32760
|
||||||
.* 4b ff ff 8d bl .* <\.__tls_get_addr>
|
.* 4b ff ff 8d bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 50 addi r3,r2,-32688
|
.* 38 62 80 50 addi r3,r2,-32688
|
||||||
.* 4b ff ff 81 bl .* <\.__tls_get_addr>
|
.* 4b ff ff 81 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* f9 43 80 08 std r10,-32760\(r3\)
|
.* f9 43 80 08 std r10,-32760\(r3\)
|
||||||
.* 3d 23 00 00 addis r9,r3,0
|
.* 3d 23 00 00 addis r9,r3,0
|
||||||
|
@ -110,7 +110,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|||||||
.* TLS +LOCAL +DEFAULT +7 le4
|
.* TLS +LOCAL +DEFAULT +7 le4
|
||||||
.* TLS +LOCAL +DEFAULT +7 le5
|
.* TLS +LOCAL +DEFAULT +7 le5
|
||||||
.* OBJECT +LOCAL +HIDDEN +ABS _DYNAMIC
|
.* OBJECT +LOCAL +HIDDEN +ABS _DYNAMIC
|
||||||
.* NOTYPE +LOCAL +DEFAULT +6 \.__tls_get_addr
|
.* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
|
||||||
.* TLS +GLOBAL DEFAULT +UND gd
|
.* TLS +GLOBAL DEFAULT +UND gd
|
||||||
.* TLS +GLOBAL DEFAULT +8 le0
|
.* TLS +GLOBAL DEFAULT +8 le0
|
||||||
.* NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
|
.* NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Disassembly of section \.text:
|
Disassembly of section \.text:
|
||||||
|
|
||||||
.* <\.__tls_get_addr>:
|
.*:
|
||||||
.* f8 41 00 28 std r2,40\(r1\)
|
.* f8 41 00 28 std r2,40\(r1\)
|
||||||
.* e9 62 80 70 ld r11,-32656\(r2\)
|
.* e9 62 80 70 ld r11,-32656\(r2\)
|
||||||
.* 7d 69 03 a6 mtctr r11
|
.* 7d 69 03 a6 mtctr r11
|
||||||
@ -18,16 +18,16 @@ Disassembly of section \.text:
|
|||||||
|
|
||||||
.* <_start>:
|
.* <_start>:
|
||||||
.* 38 62 80 08 addi r3,r2,-32760
|
.* 38 62 80 08 addi r3,r2,-32760
|
||||||
.* 4b ff ff e5 bl .* <\.__tls_get_addr>
|
.* 4b ff ff e5 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 18 addi r3,r2,-32744
|
.* 38 62 80 18 addi r3,r2,-32744
|
||||||
.* 4b ff ff d9 bl .* <\.__tls_get_addr>
|
.* 4b ff ff d9 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 28 addi r3,r2,-32728
|
.* 38 62 80 28 addi r3,r2,-32728
|
||||||
.* 4b ff ff cd bl .* <\.__tls_get_addr>
|
.* 4b ff ff cd bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 38 62 80 38 addi r3,r2,-32712
|
.* 38 62 80 38 addi r3,r2,-32712
|
||||||
.* 4b ff ff c1 bl .* <\.__tls_get_addr>
|
.* 4b ff ff c1 bl .*
|
||||||
.* e8 41 00 28 ld r2,40\(r1\)
|
.* e8 41 00 28 ld r2,40\(r1\)
|
||||||
.* 39 23 80 40 addi r9,r3,-32704
|
.* 39 23 80 40 addi r9,r3,-32704
|
||||||
.* 3d 23 00 00 addis r9,r3,0
|
.* 3d 23 00 00 addis r9,r3,0
|
||||||
|
@ -106,7 +106,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
|
|||||||
.* TLS +LOCAL +DEFAULT +7 le5
|
.* TLS +LOCAL +DEFAULT +7 le5
|
||||||
.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
|
.* NOTYPE +LOCAL +DEFAULT +11 \.Lie0
|
||||||
.* OBJECT +LOCAL +HIDDEN +ABS _DYNAMIC
|
.* OBJECT +LOCAL +HIDDEN +ABS _DYNAMIC
|
||||||
.* NOTYPE +LOCAL +DEFAULT +6 \.__tls_get_addr
|
.* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
|
||||||
.* TLS +GLOBAL DEFAULT +UND gd
|
.* TLS +GLOBAL DEFAULT +UND gd
|
||||||
.* TLS +GLOBAL DEFAULT +8 le0
|
.* TLS +GLOBAL DEFAULT +8 le0
|
||||||
.* NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
|
.* NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
|
||||||
|
Reference in New Issue
Block a user