link_elf_obj: Process global ifunc relocs after other global relocs

This is needed to ensure that resolvers that reference global symbols
return correct results.

Reviewed by:	kib
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D33120
This commit is contained in:
Mark Johnston 2021-11-25 16:52:17 -05:00
parent 8c12ee5021
commit b11e6fd75b

View File

@ -1321,7 +1321,7 @@ findbase(elf_file_t ef, int sec)
}
static int
relocate_file(elf_file_t ef)
relocate_file1(elf_file_t ef, bool ifuncs)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
@ -1354,6 +1354,9 @@ relocate_file(elf_file_t ef)
/* Local relocs are already done */
if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
continue;
if ((ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC ||
elf_is_ifunc_reloc(rel->r_info)) != ifuncs)
continue;
if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
elf_obj_lookup)) {
symname = symbol_name(ef, rel->r_info);
@ -1386,6 +1389,9 @@ relocate_file(elf_file_t ef)
/* Local relocs are already done */
if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
continue;
if ((ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC ||
elf_is_ifunc_reloc(rela->r_info)) != ifuncs)
continue;
if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
elf_obj_lookup)) {
symname = symbol_name(ef, rela->r_info);
@ -1406,6 +1412,17 @@ relocate_file(elf_file_t ef)
return (0);
}
static int
relocate_file(elf_file_t ef)
{
int error;
error = relocate_file1(ef, false);
if (error == 0)
error = relocate_file1(ef, true);
return (error);
}
static int
link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
{