mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 09:58:19 +08:00
Allocate ppc64 got and dynrelocs before plt
The idea being to make undefined weak syms dynamic, before deciding whether a sym needs a plt entry. Fixes pr19719 ld testcase. * elf64-ppc.c (allocate_dynrelocs): Allocate got and other dynamic relocs before plt relocs.
This commit is contained in:
@ -1,3 +1,8 @@
|
||||
2016-05-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf64-ppc.c (allocate_dynrelocs): Allocate got and other dynamic
|
||||
relocs before plt relocs.
|
||||
|
||||
2016-05-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf64-ppc.c (ppc64_elf_branch_reloc): Check for NULL owner
|
||||
|
167
bfd/elf64-ppc.c
167
bfd/elf64-ppc.c
@ -5150,7 +5150,7 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
|
||||
}
|
||||
|
||||
/* We need to fix the undefs list for any syms we have twiddled to
|
||||
undef_weak. */
|
||||
undefweak. */
|
||||
if (htab->twiddled_syms)
|
||||
{
|
||||
bfd_link_repair_undef_list (&htab->elf.root);
|
||||
@ -9553,71 +9553,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||||
if (htab == NULL)
|
||||
return FALSE;
|
||||
|
||||
if ((htab->elf.dynamic_sections_created
|
||||
&& h->dynindx != -1
|
||||
&& WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
|
||||
|| h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
struct plt_entry *pent;
|
||||
bfd_boolean doneone = FALSE;
|
||||
for (pent = h->plt.plist; pent != NULL; pent = pent->next)
|
||||
if (pent->plt.refcount > 0)
|
||||
{
|
||||
if (!htab->elf.dynamic_sections_created
|
||||
|| h->dynindx == -1)
|
||||
{
|
||||
s = htab->elf.iplt;
|
||||
pent->plt.offset = s->size;
|
||||
s->size += PLT_ENTRY_SIZE (htab);
|
||||
s = htab->elf.irelplt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If this is the first .plt entry, make room for the special
|
||||
first entry. */
|
||||
s = htab->elf.splt;
|
||||
if (s->size == 0)
|
||||
s->size += PLT_INITIAL_ENTRY_SIZE (htab);
|
||||
|
||||
pent->plt.offset = s->size;
|
||||
|
||||
/* Make room for this entry. */
|
||||
s->size += PLT_ENTRY_SIZE (htab);
|
||||
|
||||
/* Make room for the .glink code. */
|
||||
s = htab->glink;
|
||||
if (s->size == 0)
|
||||
s->size += GLINK_CALL_STUB_SIZE;
|
||||
if (htab->opd_abi)
|
||||
{
|
||||
/* We need bigger stubs past index 32767. */
|
||||
if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
|
||||
s->size += 4;
|
||||
s->size += 2*4;
|
||||
}
|
||||
else
|
||||
s->size += 4;
|
||||
|
||||
/* We also need to make an entry in the .rela.plt section. */
|
||||
s = htab->elf.srelplt;
|
||||
}
|
||||
s->size += sizeof (Elf64_External_Rela);
|
||||
doneone = TRUE;
|
||||
}
|
||||
else
|
||||
pent->plt.offset = (bfd_vma) -1;
|
||||
if (!doneone)
|
||||
{
|
||||
h->plt.plist = NULL;
|
||||
h->needs_plt = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h->plt.plist = NULL;
|
||||
h->needs_plt = 0;
|
||||
}
|
||||
|
||||
eh = (struct ppc_link_hash_entry *) h;
|
||||
/* Run through the TLS GD got entries first if we're changing them
|
||||
to TPREL. */
|
||||
@ -9687,25 +9622,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||||
allocate_got (h, info, gent);
|
||||
}
|
||||
|
||||
if (eh->dyn_relocs == NULL
|
||||
|| (!htab->elf.dynamic_sections_created
|
||||
&& h->type != STT_GNU_IFUNC))
|
||||
return TRUE;
|
||||
|
||||
if (eh->dyn_relocs != NULL
|
||||
&& (htab->elf.dynamic_sections_created
|
||||
|| h->type == STT_GNU_IFUNC))
|
||||
{
|
||||
/* In the shared -Bsymbolic case, discard space allocated for
|
||||
dynamic pc-relative relocs against symbols which turn out to be
|
||||
defined in regular objects. For the normal shared case, discard
|
||||
space for relocs that have become local due to symbol visibility
|
||||
changes. */
|
||||
dynamic pc-relative relocs against symbols which turn out to
|
||||
be defined in regular objects. For the normal shared case,
|
||||
discard space for relocs that have become local due to symbol
|
||||
visibility changes. */
|
||||
|
||||
if (bfd_link_pic (info))
|
||||
{
|
||||
/* Relocs that use pc_count are those that appear on a call insn,
|
||||
or certain REL relocs (see must_be_dyn_reloc) that can be
|
||||
generated via assembly. We want calls to protected symbols to
|
||||
resolve directly to the function rather than going via the plt.
|
||||
If people want function pointer comparisons to work as expected
|
||||
then they should avoid writing weird assembly. */
|
||||
/* Relocs that use pc_count are those that appear on a call
|
||||
insn, or certain REL relocs (see must_be_dyn_reloc) that
|
||||
can be generated via assembly. We want calls to
|
||||
protected symbols to resolve directly to the function
|
||||
rather than going via the plt. If people want function
|
||||
pointer comparisons to work as expected then they should
|
||||
avoid writing weird assembly. */
|
||||
if (SYMBOL_CALLS_LOCAL (info, h))
|
||||
{
|
||||
struct elf_dyn_relocs **pp;
|
||||
@ -9721,8 +9656,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||||
}
|
||||
}
|
||||
|
||||
/* Also discard relocs on undefined weak syms with non-default
|
||||
visibility. */
|
||||
/* Also discard relocs on undefined weak syms with
|
||||
non-default visibility. */
|
||||
if (eh->dyn_relocs != NULL
|
||||
&& h->root.type == bfd_link_hash_undefweak)
|
||||
{
|
||||
@ -9781,6 +9716,72 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||||
sreloc = htab->elf.irelplt;
|
||||
sreloc->size += p->count * sizeof (Elf64_External_Rela);
|
||||
}
|
||||
}
|
||||
|
||||
if ((htab->elf.dynamic_sections_created
|
||||
&& h->dynindx != -1
|
||||
&& WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
|
||||
|| h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
struct plt_entry *pent;
|
||||
bfd_boolean doneone = FALSE;
|
||||
for (pent = h->plt.plist; pent != NULL; pent = pent->next)
|
||||
if (pent->plt.refcount > 0)
|
||||
{
|
||||
if (!htab->elf.dynamic_sections_created
|
||||
|| h->dynindx == -1)
|
||||
{
|
||||
s = htab->elf.iplt;
|
||||
pent->plt.offset = s->size;
|
||||
s->size += PLT_ENTRY_SIZE (htab);
|
||||
s = htab->elf.irelplt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If this is the first .plt entry, make room for the special
|
||||
first entry. */
|
||||
s = htab->elf.splt;
|
||||
if (s->size == 0)
|
||||
s->size += PLT_INITIAL_ENTRY_SIZE (htab);
|
||||
|
||||
pent->plt.offset = s->size;
|
||||
|
||||
/* Make room for this entry. */
|
||||
s->size += PLT_ENTRY_SIZE (htab);
|
||||
|
||||
/* Make room for the .glink code. */
|
||||
s = htab->glink;
|
||||
if (s->size == 0)
|
||||
s->size += GLINK_CALL_STUB_SIZE;
|
||||
if (htab->opd_abi)
|
||||
{
|
||||
/* We need bigger stubs past index 32767. */
|
||||
if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
|
||||
s->size += 4;
|
||||
s->size += 2*4;
|
||||
}
|
||||
else
|
||||
s->size += 4;
|
||||
|
||||
/* We also need to make an entry in the .rela.plt section. */
|
||||
s = htab->elf.srelplt;
|
||||
}
|
||||
s->size += sizeof (Elf64_External_Rela);
|
||||
doneone = TRUE;
|
||||
}
|
||||
else
|
||||
pent->plt.offset = (bfd_vma) -1;
|
||||
if (!doneone)
|
||||
{
|
||||
h->plt.plist = NULL;
|
||||
h->needs_plt = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h->plt.plist = NULL;
|
||||
h->needs_plt = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user