The branch main has been updated by mmel: URL: https://cgit.FreeBSD.org/src/commit/?id=d78cbf483fe73c987573967042f57f15bf590629
commit d78cbf483fe73c987573967042f57f15bf590629 Author: Michal Meloun <[email protected]> AuthorDate: 2026-01-24 10:41:10 +0000 Commit: Michal Meloun <[email protected]> CommitDate: 2026-02-01 08:17:43 +0000 arm: Implement kernel ifunc Add kernel ifunc support on arm. MFC after : 3 weeks Reviewed by: kib (previous version) Differential Revision: https://reviews.freebsd.org/D54970 --- sys/arm/arm/elf_machdep.c | 8 +++++++- sys/arm/arm/machdep.c | 5 ++--- sys/arm/include/ifunc.h | 24 +++++++++++++++++++++--- sys/conf/kern.pre.mk | 5 ++--- sys/kern/link_elf.c | 2 +- sys/sys/elf_common.h | 1 + 6 files changed, 34 insertions(+), 11 deletions(-) diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 881c4fcff475..cf2add0c367c 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -150,7 +150,7 @@ bool elf_is_ifunc_reloc(Elf_Size r_info __unused) { - return (false); + return (ELF_R_TYPE(r_info) == R_ARM_IRELATIVE); } /* @@ -253,6 +253,12 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, case R_ARM_RELATIVE: break; + case R_ARM_IRELATIVE: + addr = relocbase + addend; + addr = ((Elf_Addr (*)(void))addr)(); + if (*where != addr) + *where = addr; + break; default: printf("kldload: unexpected relocation type %d, " "symbol index %d\n", rtype, symidx); diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 0b395d42fc4a..dc2205023820 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -447,6 +447,8 @@ initarm(struct arm_boot_params *abp) set_cpufuncs(); cpuinfo_init(); + sched_instance_select(); + link_elf_ireloc(); /* * Find the dtb passed in by the boot loader. @@ -523,9 +525,6 @@ initarm(struct arm_boot_params *abp) /* Do basic tuning, hz etc */ init_param1(); - sched_instance_select(); - /* link_elf_ireloc(); */ - /* * Allocate a page for the system page mapped to 0xffff0000 * This page will just contain the system vectors and can be diff --git a/sys/arm/include/ifunc.h b/sys/arm/include/ifunc.h index 6b7cf20c720f..98cc354ae6ca 100644 --- a/sys/arm/include/ifunc.h +++ b/sys/arm/include/ifunc.h @@ -1,10 +1,28 @@ -/* - * This file is in the public domain. +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025, Michal Meloun <[email protected]> + * */ #ifndef __ARM_IFUNC_H #define __ARM_IFUNC_H -#define __DO_NOT_HAVE_SYS_IFUNCS 1 +#define DEFINE_IFUNC(qual, ret_type, name, args) \ + static ret_type (*name##_resolver(void))args __used; \ + qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \ + static ret_type (*name##_resolver(void))args + +#ifdef __not_yet__ +#define DEFINE_UIFUNC(qual, ret_type, name, args) \ + static ret_type (*name##_resolver(uint32_t, uint32_t, uint32_t, \ + uint32_t))args __used; \ + qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \ + static ret_type (*name##_resolver( \ + uint32_t elf_hwcap __unused, \ + uint32_t elf_hwcap2 __unused, \ + uint32_t arg3 __unused, \ + uint32_t arg4 __unused))args +#endif #endif diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 440ed2df5644..93e291b45bb6 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -119,11 +119,10 @@ CFLAGS+= ${CONF_CFLAGS} LDFLAGS+= --build-id=sha1 .endif -.if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ - ${MACHINE_CPUARCH} == "i386" || ${MACHINE} == "powerpc") && \ +.if ${MACHINE_CPUARCH} != "riscv" && \ defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" && \ !make(install) -.error amd64/arm64/i386/ppc* kernel requires linker ifunc support +.error amd64/arm/arm64/i386/ppc* kernel requires linker ifunc support .endif .if ${MACHINE_CPUARCH} == "amd64" LDFLAGS+= -z max-page-size=2097152 diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 45edd186e6ce..2a9e2a02709d 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -2041,7 +2041,7 @@ link_elf_propagate_vnets(linker_file_t lf) } #endif -#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) || defined(__powerpc__) +#if !defined(__riscv) /* * Use this lookup routine when performing relocations early during boot. * The generic lookup routine depends on kobj, which is not initialized diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index efda38279848..3782bfc2df9c 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -1122,6 +1122,7 @@ typedef struct { #define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_IRELATIVE 160 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 #define R_ARM_RREL32 252
