/* ELF STT_GNU_IFUNC support.
- Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
s = bfd_make_section_with_flags (abfd, rel_sec,
flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s,
- bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
htab->irelifunc = s;
}
for static executables. */
s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ || !bfd_set_section_alignment (s, bed->plt_alignment))
return FALSE;
htab->iplt = s;
? ".rela.iplt" : ".rel.iplt"),
flags | SEC_READONLY);
if (s == NULL
- || ! bfd_set_section_alignment (abfd, s,
- bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
htab->irelplt = s;
else
s = bfd_make_section_with_flags (abfd, ".igot", flags);
if (s == NULL
- || !bfd_set_section_alignment (abfd, s,
- bed->s->log_file_align))
+ || !bfd_set_section_alignment (s, bed->s->log_file_align))
return FALSE;
htab->igotplt = s;
}
_bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
struct elf_link_hash_entry *h,
struct elf_dyn_relocs **head,
- bfd_boolean *readonly_dynrelocs_against_ifunc_p,
unsigned int plt_entry_size,
unsigned int plt_header_size,
unsigned int got_entry_size,
unsigned int sizeof_reloc;
const struct elf_backend_data *bed;
struct elf_link_hash_table *htab;
- bfd_boolean readonly_dynrelocs_against_ifunc;
/* If AVOID_PLT is TRUE, don't use PLT if possible. */
bfd_boolean use_plt = !avoid_plt || h->plt.refcount > 0;
bfd_boolean need_dynreloc = !use_plt || bfd_link_pic (info);
the resolved function may be used. But in non-PIC executable,
the address of its .plt slot may be used. Pointer equality may
not work correctly. PIE or non-PLT reference should be used if
- pointer equality is required here. */
+ pointer equality is required here.
+
+ If STT_GNU_IFUNC symbol is defined in position-dependent executable,
+ backend should change it to the normal function and set its address
+ to its PLT entry which should be resolved by R_*_IRELATIVE at
+ run-time. All external references should be resolved to its PLT in
+ executable. */
if (!need_dynreloc
+ && !(bfd_link_pde (info) && h->def_regular)
&& (h->dynindx != -1
|| info->export_dynamic)
&& h->pointer_equality_needed)
info->callbacks->einfo
/* xgettext:c-format */
(_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
- "equality in `%B' can not be used when making an "
+ "equality in `%pB' can not be used when making an "
"executable; recompile with -fPIE and relink with -pie\n"),
h->root.root.string,
h->root.u.def.section->owner);
return TRUE;
}
-keep:
+ keep:
bed = get_elf_backend_data (info->output_bfd);
if (bed->rela_plts_and_copies_p)
sizeof_reloc = bed->s->sizeof_rela;
if (!need_dynreloc || !h->non_got_ref)
*head = NULL;
- readonly_dynrelocs_against_ifunc = FALSE;
-
/* Finally, allocate space. */
p = *head;
if (p != NULL)
bfd_size_type count = 0;
do
{
- if (!readonly_dynrelocs_against_ifunc)
- {
- asection *s = p->sec->output_section;
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- readonly_dynrelocs_against_ifunc = TRUE;
- }
count += p->count;
p = p->next;
}
while (p != NULL);
+ htab->ifunc_resolvers = count != 0;
+
/* Dynamic relocations are stored in
1. .rel[a].ifunc section in PIC object.
2. .rel[a].got section in dynamic executable.
}
}
- if (readonly_dynrelocs_against_ifunc_p)
- *readonly_dynrelocs_against_ifunc_p = readonly_dynrelocs_against_ifunc;
-
/* For STT_GNU_IFUNC symbol, .got.plt has the real function address
and .got has the PLT entry adddress. We will load the GOT entry
with the PLT entry in finish_dynamic_symbol if it is used. For