mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-18 16:53:50 +08:00
* elf32-ppc.c (struct ppc_dyn_relocs): New.
(ppc_elf_check_relocs): Separate dynrel counts for local syms into ifunc and non-ifunc. (allocate_dynrelocs): Always put ifunc relocs into reliplt. (ppc_elf_size_dynamic_sections): Likewise. (ppc_elf_relocate_section): Likewise.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2013-03-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf32-ppc.c (struct ppc_dyn_relocs): New.
|
||||||
|
(ppc_elf_check_relocs): Separate dynrel counts for local syms
|
||||||
|
into ifunc and non-ifunc.
|
||||||
|
(allocate_dynrelocs): Always put ifunc relocs into reliplt.
|
||||||
|
(ppc_elf_size_dynamic_sections): Likewise.
|
||||||
|
(ppc_elf_relocate_section): Likewise.
|
||||||
|
|
||||||
2013-03-28 Alan Modra <amodra@gmail.com>
|
2013-03-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf-bfd.h (enum elf_reloc_type_class): Add reloc_class_ifunc.
|
* elf-bfd.h (enum elf_reloc_type_class): Add reloc_class_ifunc.
|
||||||
|
@ -3083,6 +3083,21 @@ must_be_dyn_reloc (struct bfd_link_info *info,
|
|||||||
shared lib. */
|
shared lib. */
|
||||||
#define ELIMINATE_COPY_RELOCS 1
|
#define ELIMINATE_COPY_RELOCS 1
|
||||||
|
|
||||||
|
/* Used to track dynamic relocations for local symbols. */
|
||||||
|
struct ppc_dyn_relocs
|
||||||
|
{
|
||||||
|
struct ppc_dyn_relocs *next;
|
||||||
|
|
||||||
|
/* The input section of the reloc. */
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
|
/* Total number of relocs copied for the input section. */
|
||||||
|
unsigned int count : 31;
|
||||||
|
|
||||||
|
/* Whether this entry is for STT_GNU_IFUNC symbols. */
|
||||||
|
unsigned int ifunc : 1;
|
||||||
|
};
|
||||||
|
|
||||||
/* PPC ELF linker hash entry. */
|
/* PPC ELF linker hash entry. */
|
||||||
|
|
||||||
struct ppc_elf_link_hash_entry
|
struct ppc_elf_link_hash_entry
|
||||||
@ -4414,9 +4429,6 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
&& (h->root.type == bfd_link_hash_defweak
|
&& (h->root.type == bfd_link_hash_defweak
|
||||||
|| !h->def_regular)))
|
|| !h->def_regular)))
|
||||||
{
|
{
|
||||||
struct elf_dyn_relocs *p;
|
|
||||||
struct elf_dyn_relocs **rel_head;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"ppc_elf_check_relocs needs to "
|
"ppc_elf_check_relocs needs to "
|
||||||
@ -4440,13 +4452,34 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
relocations we need for this symbol. */
|
relocations we need for this symbol. */
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
|
struct elf_dyn_relocs *p;
|
||||||
|
struct elf_dyn_relocs **rel_head;
|
||||||
|
|
||||||
rel_head = &ppc_elf_hash_entry (h)->dyn_relocs;
|
rel_head = &ppc_elf_hash_entry (h)->dyn_relocs;
|
||||||
|
p = *rel_head;
|
||||||
|
if (p == NULL || p->sec != sec)
|
||||||
|
{
|
||||||
|
p = bfd_alloc (htab->elf.dynobj, sizeof *p);
|
||||||
|
if (p == NULL)
|
||||||
|
return FALSE;
|
||||||
|
p->next = *rel_head;
|
||||||
|
*rel_head = p;
|
||||||
|
p->sec = sec;
|
||||||
|
p->count = 0;
|
||||||
|
p->pc_count = 0;
|
||||||
|
}
|
||||||
|
p->count += 1;
|
||||||
|
if (!must_be_dyn_reloc (info, r_type))
|
||||||
|
p->pc_count += 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Track dynamic relocs needed for local syms too.
|
/* Track dynamic relocs needed for local syms too.
|
||||||
We really need local syms available to do this
|
We really need local syms available to do this
|
||||||
easily. Oh well. */
|
easily. Oh well. */
|
||||||
|
struct ppc_dyn_relocs *p;
|
||||||
|
struct ppc_dyn_relocs **rel_head;
|
||||||
|
bfd_boolean is_ifunc;
|
||||||
asection *s;
|
asection *s;
|
||||||
void *vpp;
|
void *vpp;
|
||||||
Elf_Internal_Sym *isym;
|
Elf_Internal_Sym *isym;
|
||||||
@ -4461,25 +4494,24 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
s = sec;
|
s = sec;
|
||||||
|
|
||||||
vpp = &elf_section_data (s)->local_dynrel;
|
vpp = &elf_section_data (s)->local_dynrel;
|
||||||
rel_head = (struct elf_dyn_relocs **) vpp;
|
rel_head = (struct ppc_dyn_relocs **) vpp;
|
||||||
|
is_ifunc = ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC;
|
||||||
|
p = *rel_head;
|
||||||
|
if (p != NULL && p->sec == sec && p->ifunc != is_ifunc)
|
||||||
|
p = p->next;
|
||||||
|
if (p == NULL || p->sec != sec || p->ifunc != is_ifunc)
|
||||||
|
{
|
||||||
|
p = bfd_alloc (htab->elf.dynobj, sizeof *p);
|
||||||
|
if (p == NULL)
|
||||||
|
return FALSE;
|
||||||
|
p->next = *rel_head;
|
||||||
|
*rel_head = p;
|
||||||
|
p->sec = sec;
|
||||||
|
p->ifunc = is_ifunc;
|
||||||
|
p->count = 0;
|
||||||
|
}
|
||||||
|
p->count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = *rel_head;
|
|
||||||
if (p == NULL || p->sec != sec)
|
|
||||||
{
|
|
||||||
p = bfd_alloc (htab->elf.dynobj, sizeof *p);
|
|
||||||
if (p == NULL)
|
|
||||||
return FALSE;
|
|
||||||
p->next = *rel_head;
|
|
||||||
*rel_head = p;
|
|
||||||
p->sec = sec;
|
|
||||||
p->count = 0;
|
|
||||||
p->pc_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->count += 1;
|
|
||||||
if (!must_be_dyn_reloc (info, r_type))
|
|
||||||
p->pc_count += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -6023,7 +6055,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
asection *sreloc = elf_section_data (p->sec)->sreloc;
|
asection *sreloc = elf_section_data (p->sec)->sreloc;
|
||||||
if (!htab->elf.dynamic_sections_created)
|
if (eh->elf.type == STT_GNU_IFUNC)
|
||||||
sreloc = htab->reliplt;
|
sreloc = htab->reliplt;
|
||||||
sreloc->size += p->count * sizeof (Elf32_External_Rela);
|
sreloc->size += p->count * sizeof (Elf32_External_Rela);
|
||||||
}
|
}
|
||||||
@ -6116,9 +6148,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
for (s = ibfd->sections; s != NULL; s = s->next)
|
for (s = ibfd->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
struct elf_dyn_relocs *p;
|
struct ppc_dyn_relocs *p;
|
||||||
|
|
||||||
for (p = ((struct elf_dyn_relocs *)
|
for (p = ((struct ppc_dyn_relocs *)
|
||||||
elf_section_data (s)->local_dynrel);
|
elf_section_data (s)->local_dynrel);
|
||||||
p != NULL;
|
p != NULL;
|
||||||
p = p->next)
|
p = p->next)
|
||||||
@ -6141,7 +6173,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||||||
else if (p->count != 0)
|
else if (p->count != 0)
|
||||||
{
|
{
|
||||||
asection *sreloc = elf_section_data (p->sec)->sreloc;
|
asection *sreloc = elf_section_data (p->sec)->sreloc;
|
||||||
if (!htab->elf.dynamic_sections_created)
|
if (p->ifunc)
|
||||||
sreloc = htab->reliplt;
|
sreloc = htab->reliplt;
|
||||||
sreloc->size += p->count * sizeof (Elf32_External_Rela);
|
sreloc->size += p->count * sizeof (Elf32_External_Rela);
|
||||||
if ((p->sec->output_section->flags
|
if ((p->sec->output_section->flags
|
||||||
@ -7390,7 +7422,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
Elf_Internal_Rela *rel;
|
Elf_Internal_Rela *rel;
|
||||||
Elf_Internal_Rela *relend;
|
Elf_Internal_Rela *relend;
|
||||||
Elf_Internal_Rela outrel;
|
Elf_Internal_Rela outrel;
|
||||||
asection *got2, *sreloc = NULL;
|
asection *got2;
|
||||||
bfd_vma *local_got_offsets;
|
bfd_vma *local_got_offsets;
|
||||||
bfd_boolean ret = TRUE;
|
bfd_boolean ret = TRUE;
|
||||||
bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
|
bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
|
||||||
@ -8244,7 +8276,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
&& !h->def_regular))
|
&& !h->def_regular))
|
||||||
{
|
{
|
||||||
int skip;
|
int skip;
|
||||||
bfd_byte * loc;
|
bfd_byte *loc;
|
||||||
|
asection *sreloc;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf (stderr, "ppc_elf_relocate_section needs to "
|
fprintf (stderr, "ppc_elf_relocate_section needs to "
|
||||||
"create relocation for %s\n",
|
"create relocation for %s\n",
|
||||||
@ -8255,14 +8288,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
/* When generating a shared object, these relocations
|
/* When generating a shared object, these relocations
|
||||||
are copied into the output file to be resolved at run
|
are copied into the output file to be resolved at run
|
||||||
time. */
|
time. */
|
||||||
|
sreloc = elf_section_data (input_section)->sreloc;
|
||||||
|
if (ifunc)
|
||||||
|
sreloc = htab->reliplt;
|
||||||
if (sreloc == NULL)
|
if (sreloc == NULL)
|
||||||
{
|
return FALSE;
|
||||||
sreloc = elf_section_data (input_section)->sreloc;
|
|
||||||
if (!htab->elf.dynamic_sections_created)
|
|
||||||
sreloc = htab->reliplt;
|
|
||||||
if (sreloc == NULL)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
skip = 0;
|
skip = 0;
|
||||||
outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
|
outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
|
||||||
|
Reference in New Issue
Block a user