Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/elf64_machdep.c
Show First 20 Lines • Show All 276 Lines • ▼ Show 20 Lines | if (dst != NULL) { | ||||
len += elf64_populate_note(NT_PPC_VSX, NULL, NULL, | len += elf64_populate_note(NT_PPC_VSX, NULL, NULL, | ||||
sizeof(vshr), NULL); | sizeof(vshr), NULL); | ||||
} | } | ||||
*off = len; | *off = len; | ||||
} | } | ||||
bool | bool | ||||
elf_is_ifunc_reloc(Elf_Size r_info __unused) | elf_is_ifunc_reloc(Elf_Size r_info) | ||||
{ | { | ||||
return (false); | return (ELF_R_TYPE(r_info) == R_PPC_IRELATIVE); | ||||
} | } | ||||
/* Process one elf relocation with addend. */ | /* Process one elf relocation with addend. */ | ||||
static int | static int | ||||
elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, | elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, | ||||
int type, int local, elf_lookup_fn lookup) | int type, int local, elf_lookup_fn lookup) | ||||
{ | { | ||||
Elf_Addr *where; | Elf_Addr *where; | ||||
Elf_Addr addr; | Elf_Addr addr; | ||||
Elf_Addr addend; | Elf_Addr addend, val; | ||||
Elf_Word rtype, symidx; | Elf_Word rtype, symidx; | ||||
const Elf_Rela *rela; | const Elf_Rela *rela; | ||||
int error; | int error; | ||||
switch (type) { | switch (type) { | ||||
case ELF_RELOC_REL: | case ELF_RELOC_REL: | ||||
panic("PPC only supports RELA relocations"); | panic("PPC only supports RELA relocations"); | ||||
break; | break; | ||||
Show All 28 Lines | elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, | ||||
case R_PPC_JMP_SLOT: /* function descriptor copy */ | case R_PPC_JMP_SLOT: /* function descriptor copy */ | ||||
lookup(lf, symidx, 1, &addr); | lookup(lf, symidx, 1, &addr); | ||||
#if !defined(_CALL_ELF) || _CALL_ELF == 1 | #if !defined(_CALL_ELF) || _CALL_ELF == 1 | ||||
memcpy(where, (Elf_Addr *)addr, 3*sizeof(Elf_Addr)); | memcpy(where, (Elf_Addr *)addr, 3*sizeof(Elf_Addr)); | ||||
#else | #else | ||||
*where = addr; | *where = addr; | ||||
#endif | #endif | ||||
__asm __volatile("dcbst 0,%0; sync" :: "r"(where) : "memory"); | __asm __volatile("dcbst 0,%0; sync" :: "r"(where) : "memory"); | ||||
break; | |||||
case R_PPC_IRELATIVE: | |||||
addr = relocbase + addend; | |||||
val = ((Elf64_Addr (*)(void))addr)(); | |||||
bdragon: Current kernel ABI for ifuncs doesn't utilize parameter passing like the user ifuncs do.
If it… | |||||
if (*where != val) | |||||
*where = val; | |||||
break; | break; | ||||
default: | default: | ||||
printf("kldload: unexpected relocation type %d\n", | printf("kldload: unexpected relocation type %d\n", | ||||
(int) rtype); | (int) rtype); | ||||
return -1; | return -1; | ||||
} | } | ||||
return(0); | return(0); | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |
Current kernel ABI for ifuncs doesn't utilize parameter passing like the user ifuncs do.
If it turns out to be problematic, we should add cpu_features / cpu_features2 as well as info about what mmu is installed.