mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
* elf32-ppc.c (ppc_elf_check_relocs): Always add a plt ref count
for local ifunc symbols in non-pie executables, regardless of reloc type. Don't specially create ifunc dyn relocs. Tidy ifunc code so that it's obvious that we only do anything special for local ifunc syms. (ppc_elf_gc_sweep_hook): Adjust to suit check_relocs changes. (allocate_dynrelocs): Correct comment for syms defined in plt. Don't specially allocate ifunc dyn relocs. (ppc_elf_relax_section): Relax branches to ifunc plt entries too. (ppc_elf_relocate_section): Set "relocation" value for ifunc syms in non-pie executables. No specially allocated dyn relocs for ifunc to write. Allow for local sym on R_PPC_RELAX32_PLT. (ppc_elf_finish_dynamic_symbol): Set value of ifunc symbols in a non-pie executable.
This commit is contained in:
parent
0329406f62
commit
de972ffadd
@ -1,3 +1,20 @@
|
|||||||
|
2009-08-03 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf32-ppc.c (ppc_elf_check_relocs): Always add a plt ref count
|
||||||
|
for local ifunc symbols in non-pie executables, regardless of
|
||||||
|
reloc type. Don't specially create ifunc dyn relocs. Tidy ifunc
|
||||||
|
code so that it's obvious that we only do anything special for
|
||||||
|
local ifunc syms.
|
||||||
|
(ppc_elf_gc_sweep_hook): Adjust to suit check_relocs changes.
|
||||||
|
(allocate_dynrelocs): Correct comment for syms defined in plt.
|
||||||
|
Don't specially allocate ifunc dyn relocs.
|
||||||
|
(ppc_elf_relax_section): Relax branches to ifunc plt entries too.
|
||||||
|
(ppc_elf_relocate_section): Set "relocation" value for ifunc
|
||||||
|
syms in non-pie executables. No specially allocated dyn relocs
|
||||||
|
for ifunc to write. Allow for local sym on R_PPC_RELAX32_PLT.
|
||||||
|
(ppc_elf_finish_dynamic_symbol): Set value of ifunc symbols in
|
||||||
|
a non-pie executable.
|
||||||
|
|
||||||
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
|
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
Jakub Jelinek <jakub@redhat.com>
|
Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
255
bfd/elf32-ppc.c
255
bfd/elf32-ppc.c
@ -3458,15 +3458,13 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
|
|
||||||
tls_type = 0;
|
tls_type = 0;
|
||||||
ifunc = NULL;
|
ifunc = NULL;
|
||||||
|
r_type = ELF32_R_TYPE (rel->r_info);
|
||||||
if (!htab->is_vxworks)
|
if (!htab->is_vxworks)
|
||||||
{
|
{
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
if (h->type == STT_GNU_IFUNC)
|
if (h->type == STT_GNU_IFUNC)
|
||||||
{
|
ifunc = &h->plt.plist;
|
||||||
h->needs_plt = 1;
|
|
||||||
ifunc = &h->plt.plist;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3475,46 +3473,47 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
if (isym == NULL)
|
if (isym == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
|
||||||
|
&& (!info->shared
|
||||||
|
|| is_branch_reloc (r_type)))
|
||||||
{
|
{
|
||||||
|
bfd_vma addend;
|
||||||
|
|
||||||
ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
|
ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
|
||||||
PLT_IFUNC);
|
PLT_IFUNC);
|
||||||
if (ifunc == NULL)
|
if (ifunc == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* STT_GNU_IFUNC symbols must have a PLT entry;
|
||||||
|
In a non-pie executable even when there are
|
||||||
|
no plt calls. */
|
||||||
|
addend = 0;
|
||||||
|
if (r_type == R_PPC_PLTREL24)
|
||||||
|
{
|
||||||
|
ppc_elf_tdata (abfd)->makes_plt_call = 1;
|
||||||
|
addend = rel->r_addend;
|
||||||
|
}
|
||||||
|
if (!update_plt_info (abfd, ifunc,
|
||||||
|
addend < 32768 ? NULL : got2, addend))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r_type = ELF32_R_TYPE (rel->r_info);
|
if (!htab->is_vxworks
|
||||||
if (!htab->is_vxworks && is_branch_reloc (r_type))
|
&& is_branch_reloc (r_type)
|
||||||
|
&& h != NULL
|
||||||
|
&& h == tga)
|
||||||
{
|
{
|
||||||
if (h != NULL && h == tga)
|
if (rel != relocs
|
||||||
{
|
&& (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
|
||||||
if (rel != relocs
|
|| ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
|
||||||
&& (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
|
/* We have a new-style __tls_get_addr call with a marker
|
||||||
|| ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
|
reloc. */
|
||||||
/* We have a new-style __tls_get_addr call with a marker
|
;
|
||||||
reloc. */
|
else
|
||||||
;
|
/* Mark this section as having an old-style call. */
|
||||||
else
|
sec->has_tls_get_addr_call = 1;
|
||||||
/* Mark this section as having an old-style call. */
|
|
||||||
sec->has_tls_get_addr_call = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STT_GNU_IFUNC symbols must have a PLT entry. */
|
|
||||||
if (ifunc != NULL)
|
|
||||||
{
|
|
||||||
bfd_vma addend = 0;
|
|
||||||
|
|
||||||
if (r_type == R_PPC_PLTREL24)
|
|
||||||
{
|
|
||||||
ppc_elf_tdata (abfd)->makes_plt_call = 1;
|
|
||||||
addend = rel->r_addend;
|
|
||||||
}
|
|
||||||
if (!update_plt_info (abfd, ifunc,
|
|
||||||
addend < 32768 ? NULL : got2, addend))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
@ -3690,7 +3689,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC_PLTREL24:
|
case R_PPC_PLTREL24:
|
||||||
if (h == NULL || ifunc != NULL)
|
if (h == NULL)
|
||||||
break;
|
break;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case R_PPC_PLT32:
|
case R_PPC_PLT32:
|
||||||
@ -3903,8 +3902,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
/* We may need a plt entry if the symbol turns out to be
|
/* We may need a plt entry if the symbol turns out to be
|
||||||
a function defined in a dynamic object. */
|
a function defined in a dynamic object. */
|
||||||
h->needs_plt = 1;
|
h->needs_plt = 1;
|
||||||
if (ifunc == NULL
|
if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
|
||||||
&& !update_plt_info (abfd, &h->plt.plist, NULL, 0))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3941,9 +3939,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|||||||
&& !info->shared
|
&& !info->shared
|
||||||
&& h != NULL
|
&& h != NULL
|
||||||
&& (h->root.type == bfd_link_hash_defweak
|
&& (h->root.type == bfd_link_hash_defweak
|
||||||
|| !h->def_regular))
|
|| !h->def_regular)))
|
||||||
|| (!info->shared
|
|
||||||
&& ifunc != NULL))
|
|
||||||
{
|
{
|
||||||
struct ppc_elf_dyn_relocs *p;
|
struct ppc_elf_dyn_relocs *p;
|
||||||
struct ppc_elf_dyn_relocs **head;
|
struct ppc_elf_dyn_relocs **head;
|
||||||
@ -4415,25 +4411,19 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r_type = ELF32_R_TYPE (rel->r_info);
|
r_type = ELF32_R_TYPE (rel->r_info);
|
||||||
if (!htab->is_vxworks && is_branch_reloc (r_type))
|
if (!htab->is_vxworks
|
||||||
|
&& h == NULL
|
||||||
|
&& local_got_refcounts != NULL
|
||||||
|
&& (!info->shared
|
||||||
|
|| is_branch_reloc (r_type)))
|
||||||
{
|
{
|
||||||
struct plt_entry **ifunc = NULL;
|
struct plt_entry **local_plt = (struct plt_entry **)
|
||||||
if (h != NULL)
|
(local_got_refcounts + symtab_hdr->sh_info);
|
||||||
{
|
char *local_got_tls_masks = (char *)
|
||||||
if (h->type == STT_GNU_IFUNC)
|
(local_plt + symtab_hdr->sh_info);
|
||||||
ifunc = &h->plt.plist;
|
if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
|
||||||
}
|
|
||||||
else if (local_got_refcounts != NULL)
|
|
||||||
{
|
|
||||||
struct plt_entry **local_plt = (struct plt_entry **)
|
|
||||||
(local_got_refcounts + symtab_hdr->sh_info);
|
|
||||||
char *local_got_tls_masks = (char *)
|
|
||||||
(local_plt + symtab_hdr->sh_info);
|
|
||||||
if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
|
|
||||||
ifunc = local_plt + r_symndx;
|
|
||||||
}
|
|
||||||
if (ifunc != NULL)
|
|
||||||
{
|
{
|
||||||
|
struct plt_entry **ifunc = local_plt + r_symndx;
|
||||||
bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
|
bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
|
||||||
struct plt_entry *ent = find_plt_ent (ifunc, got2, addend);
|
struct plt_entry *ent = find_plt_ent (ifunc, got2, addend);
|
||||||
if (ent->plt.refcount > 0)
|
if (ent->plt.refcount > 0)
|
||||||
@ -5166,8 +5156,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
|
|
||||||
/* If this symbol is not defined in a regular
|
/* If this symbol is not defined in a regular
|
||||||
file, and we are not generating a shared
|
file, and we are not generating a shared
|
||||||
library, then set the symbol to this location
|
library, then set the symbol to this location
|
||||||
in the .plt. This is required to make
|
in the .plt. This is to avoid text
|
||||||
|
relocations, and is required to make
|
||||||
function pointers compare as equal between
|
function pointers compare as equal between
|
||||||
the normal executable and the shared library. */
|
the normal executable and the shared library. */
|
||||||
if (! info->shared
|
if (! info->shared
|
||||||
@ -5313,8 +5304,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
eh->elf.got.offset = (bfd_vma) -1;
|
eh->elf.got.offset = (bfd_vma) -1;
|
||||||
|
|
||||||
if (eh->dyn_relocs == NULL
|
if (eh->dyn_relocs == NULL
|
||||||
|| (!htab->elf.dynamic_sections_created
|
|| !htab->elf.dynamic_sections_created)
|
||||||
&& h->type != STT_GNU_IFUNC))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* In the shared -Bsymbolic case, discard space allocated for
|
/* In the shared -Bsymbolic case, discard space allocated for
|
||||||
@ -5385,11 +5375,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (h->type == STT_GNU_IFUNC)
|
|
||||||
{
|
|
||||||
if (!h->non_got_ref)
|
|
||||||
eh->dyn_relocs = NULL;
|
|
||||||
}
|
|
||||||
else if (ELIMINATE_COPY_RELOCS)
|
else if (ELIMINATE_COPY_RELOCS)
|
||||||
{
|
{
|
||||||
/* For the non-shared case, discard space for relocs against
|
/* For the non-shared case, discard space for relocs against
|
||||||
@ -5938,6 +5923,7 @@ ppc_elf_relax_section (bfd *abfd,
|
|||||||
bfd_vma max_branch_offset, val;
|
bfd_vma max_branch_offset, val;
|
||||||
bfd_byte *hit_addr;
|
bfd_byte *hit_addr;
|
||||||
unsigned long t0;
|
unsigned long t0;
|
||||||
|
struct elf_link_hash_entry *h;
|
||||||
unsigned char sym_type;
|
unsigned char sym_type;
|
||||||
|
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
@ -5959,6 +5945,7 @@ ppc_elf_relax_section (bfd *abfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value of the symbol referred to by the reloc. */
|
/* Get the value of the symbol referred to by the reloc. */
|
||||||
|
h = NULL;
|
||||||
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
|
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
|
||||||
{
|
{
|
||||||
/* A local symbol. */
|
/* A local symbol. */
|
||||||
@ -5992,7 +5979,6 @@ ppc_elf_relax_section (bfd *abfd,
|
|||||||
{
|
{
|
||||||
/* Global symbol handling. */
|
/* Global symbol handling. */
|
||||||
unsigned long indx;
|
unsigned long indx;
|
||||||
struct elf_link_hash_entry *h;
|
|
||||||
|
|
||||||
indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
|
||||||
h = elf_sym_hashes (abfd)[indx];
|
h = elf_sym_hashes (abfd)[indx];
|
||||||
@ -6003,26 +5989,6 @@ ppc_elf_relax_section (bfd *abfd,
|
|||||||
|
|
||||||
tsec = NULL;
|
tsec = NULL;
|
||||||
toff = 0;
|
toff = 0;
|
||||||
if (r_type == R_PPC_PLTREL24
|
|
||||||
&& htab->plt != NULL)
|
|
||||||
{
|
|
||||||
struct plt_entry *ent = find_plt_ent (&h->plt.plist,
|
|
||||||
got2, irel->r_addend);
|
|
||||||
|
|
||||||
if (ent != NULL)
|
|
||||||
{
|
|
||||||
if (htab->plt_type == PLT_NEW)
|
|
||||||
{
|
|
||||||
tsec = htab->glink;
|
|
||||||
toff = ent->glink_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tsec = htab->plt;
|
|
||||||
toff = ent->plt.offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tsec != NULL)
|
if (tsec != NULL)
|
||||||
;
|
;
|
||||||
else if (h->root.type == bfd_link_hash_defined
|
else if (h->root.type == bfd_link_hash_defined
|
||||||
@ -6043,6 +6009,46 @@ ppc_elf_relax_section (bfd *abfd,
|
|||||||
sym_type = h->type;
|
sym_type = h->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_branch_reloc (r_type))
|
||||||
|
{
|
||||||
|
struct plt_entry **plist = NULL;
|
||||||
|
|
||||||
|
if (h != NULL)
|
||||||
|
plist = &h->plt.plist;
|
||||||
|
else if (sym_type == STT_GNU_IFUNC)
|
||||||
|
{
|
||||||
|
bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
|
||||||
|
struct plt_entry **local_plt = (struct plt_entry **)
|
||||||
|
(local_got_offsets + symtab_hdr->sh_info);
|
||||||
|
plist = local_plt + ELF32_R_SYM (irel->r_info);
|
||||||
|
}
|
||||||
|
if (plist != NULL)
|
||||||
|
{
|
||||||
|
bfd_vma addend = 0;
|
||||||
|
struct plt_entry *ent;
|
||||||
|
|
||||||
|
if (r_type == R_PPC_PLTREL24)
|
||||||
|
addend = irel->r_addend;
|
||||||
|
ent = find_plt_ent (plist, got2, addend);
|
||||||
|
if (ent != NULL)
|
||||||
|
{
|
||||||
|
if (htab->plt_type == PLT_NEW
|
||||||
|
|| h == NULL
|
||||||
|
|| !htab->elf.dynamic_sections_created
|
||||||
|
|| h->dynindx == -1)
|
||||||
|
{
|
||||||
|
tsec = htab->glink;
|
||||||
|
toff = ent->glink_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tsec = htab->plt;
|
||||||
|
toff = ent->plt.offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If the branch and target are in the same section, you have
|
/* If the branch and target are in the same section, you have
|
||||||
no hope of adding stubs. We'll error out later should the
|
no hope of adding stubs. We'll error out later should the
|
||||||
branch overflow. */
|
branch overflow. */
|
||||||
@ -6940,25 +6946,35 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
ifunc = NULL;
|
ifunc = NULL;
|
||||||
if (!htab->is_vxworks)
|
if (!htab->is_vxworks)
|
||||||
{
|
{
|
||||||
|
struct plt_entry *ent;
|
||||||
|
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
if (h->type == STT_GNU_IFUNC)
|
if (h->type == STT_GNU_IFUNC)
|
||||||
ifunc = &h->plt.plist;
|
ifunc = &h->plt.plist;
|
||||||
}
|
}
|
||||||
else if (local_got_offsets != NULL)
|
else if (local_got_offsets != NULL
|
||||||
|
&& ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
|
||||||
{
|
{
|
||||||
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
|
struct plt_entry **local_plt;
|
||||||
{
|
|
||||||
struct plt_entry **local_plt = (struct plt_entry **)
|
|
||||||
(local_got_offsets + symtab_hdr->sh_info);
|
|
||||||
|
|
||||||
ifunc = local_plt + r_symndx;
|
local_plt = (struct plt_entry **) (local_got_offsets
|
||||||
}
|
+ symtab_hdr->sh_info);
|
||||||
|
ifunc = local_plt + r_symndx;
|
||||||
}
|
}
|
||||||
if (ifunc != NULL && is_branch_reloc (r_type))
|
|
||||||
{
|
|
||||||
struct plt_entry *ent = find_plt_ent (ifunc, got2, rel->r_addend);
|
|
||||||
|
|
||||||
|
ent = NULL;
|
||||||
|
if (ifunc != NULL
|
||||||
|
&& (!info->shared
|
||||||
|
|| is_branch_reloc (r_type)))
|
||||||
|
{
|
||||||
|
addend = 0;
|
||||||
|
if (r_type == R_PPC_PLTREL24)
|
||||||
|
addend = rel->r_addend;
|
||||||
|
ent = find_plt_ent (ifunc, got2, addend);
|
||||||
|
}
|
||||||
|
if (ent != NULL)
|
||||||
|
{
|
||||||
if (h == NULL && (ent->plt.offset & 1) == 0)
|
if (h == NULL && (ent->plt.offset & 1) == 0)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela rela;
|
Elf_Internal_Rela rela;
|
||||||
@ -7385,9 +7401,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
&& h != NULL
|
&& h != NULL
|
||||||
&& h->dynindx != -1
|
&& h->dynindx != -1
|
||||||
&& !h->non_got_ref
|
&& !h->non_got_ref
|
||||||
&& !h->def_regular)
|
&& !h->def_regular))
|
||||||
|| (!info->shared
|
|
||||||
&& ifunc != NULL))
|
|
||||||
{
|
{
|
||||||
int skip;
|
int skip;
|
||||||
|
|
||||||
@ -7526,18 +7540,19 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
|
|
||||||
case R_PPC_RELAX32PC_PLT:
|
case R_PPC_RELAX32PC_PLT:
|
||||||
case R_PPC_RELAX32_PLT:
|
case R_PPC_RELAX32_PLT:
|
||||||
{
|
if (h != NULL)
|
||||||
struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend);
|
{
|
||||||
|
struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
|
||||||
if (htab->plt_type == PLT_NEW)
|
addend);
|
||||||
relocation = (htab->glink->output_section->vma
|
if (htab->plt_type == PLT_NEW)
|
||||||
+ htab->glink->output_offset
|
relocation = (htab->glink->output_section->vma
|
||||||
+ ent->glink_offset);
|
+ htab->glink->output_offset
|
||||||
else
|
+ ent->glink_offset);
|
||||||
relocation = (htab->plt->output_section->vma
|
else
|
||||||
+ htab->plt->output_offset
|
relocation = (htab->plt->output_section->vma
|
||||||
+ ent->plt.offset);
|
+ htab->plt->output_offset
|
||||||
}
|
+ ent->plt.offset);
|
||||||
|
}
|
||||||
if (r_type == R_PPC_RELAX32_PLT)
|
if (r_type == R_PPC_RELAX32_PLT)
|
||||||
goto relax32;
|
goto relax32;
|
||||||
/* Fall thru */
|
/* Fall thru */
|
||||||
@ -8164,6 +8179,22 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|||||||
sym->st_value = 0;
|
sym->st_value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (h->type == STT_GNU_IFUNC
|
||||||
|
&& !info->shared)
|
||||||
|
{
|
||||||
|
/* Set the value of ifunc symbols in a non-pie
|
||||||
|
executable to the glink entry. This is to avoid
|
||||||
|
text relocations. We can't do this for ifunc in
|
||||||
|
allocate_dynrelocs, as we do for normal dynamic
|
||||||
|
function symbols with plt entries, because we need
|
||||||
|
to keep the original value around for the ifunc
|
||||||
|
relocation. */
|
||||||
|
sym->st_shndx = (_bfd_elf_section_from_bfd_section
|
||||||
|
(output_bfd, htab->glink->output_section));
|
||||||
|
sym->st_value = (ent->glink_offset +
|
||||||
|
htab->glink->output_offset
|
||||||
|
+ htab->glink->output_section->vma);
|
||||||
|
}
|
||||||
doneone = TRUE;
|
doneone = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user