Index: sys/arm/arm/elf_machdep.c =================================================================== --- sys/arm/arm/elf_machdep.c +++ sys/arm/arm/elf_machdep.c @@ -48,6 +48,8 @@ static boolean_t elf32_arm_abi_supported(struct image_params *); +u_long elf_hwcap; + struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, @@ -86,6 +88,7 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, + .sv_hwcap = &elf_hwcap, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); Index: sys/arm/arm/vfp.c =================================================================== --- sys/arm/arm/vfp.c +++ sys/arm/arm/vfp.c @@ -33,9 +33,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -115,6 +117,7 @@ vfp_exists = 1; is_d32 = 0; PCPU_SET(vfpsid, fpsid); /* save the fpsid */ + elf_hwcap |= HWCAP_ARM_VFP; vfp_arch = (fpsid & VFPSID_SUBVERSION2_MASK) >> VFPSID_SUBVERSION_OFF; @@ -122,9 +125,13 @@ if (vfp_arch >= VFP_ARCH3) { tmp = fmrx(mvfr0); PCPU_SET(vfpmvfr0, tmp); + elf_hwcap |= HWCAP_ARM_VFPv3; - if ((tmp & VMVFR0_RB_MASK) == 2) + if ((tmp & VMVFR0_RB_MASK) == 2) { + elf_hwcap |= HWCAP_ARM_VFPD32; is_d32 = 1; + } else + elf_hwcap |= HWCAP_ARM_VFPv3D16; tmp = fmrx(mvfr1); PCPU_SET(vfpmvfr1, tmp); Index: sys/arm/include/elf.h =================================================================== --- sys/arm/include/elf.h +++ sys/arm/include/elf.h @@ -85,8 +85,9 @@ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ #define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 25 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ #define R_ARM_COUNT 33 /* Count of defined relocation types. */ @@ -114,4 +115,10 @@ #define ET_DYN_LOAD_ADDR 0x12000 +/* Flags passed in AT_HWCAP. */ +#define HWCAP_ARM_VFP 0x00000040 +#define HWCAP_ARM_VFPv3 0x00000200 +#define HWCAP_ARM_VFPv3D16 0x00000400 +#define HWCAP_ARM_VFPD32 0x00080000 + #endif /* !_MACHINE_ELF_H_ */ Index: sys/arm/include/md_var.h =================================================================== --- sys/arm/include/md_var.h +++ sys/arm/include/md_var.h @@ -38,6 +38,7 @@ extern int szsigcode; extern uint32_t *vm_page_dump; extern int vm_page_dump_size; +extern u_long elf_hwcap; extern int (*_arm_memcpy)(void *, void *, int, int); extern int (*_arm_bzero)(void *, int, int); Index: sys/arm64/include/elf.h =================================================================== --- sys/arm64/include/elf.h +++ sys/arm64/include/elf.h @@ -90,8 +90,10 @@ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #define ELF_TARG_CLASS ELFCLASS64 Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -1110,9 +1110,7 @@ AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); -#ifdef AT_EHDRFLAGS AUXARGS_ENTRY(pos, AT_EHDRFLAGS, args->hdr_eflags); -#endif if (imgp->execpathp != 0) AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp); AUXARGS_ENTRY(pos, AT_OSRELDATE, @@ -1133,6 +1131,8 @@ AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : imgp->sysent->sv_stackprot); + if (imgp->sysent->sv_hwcap != NULL) + AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: sys/mips/include/elf.h =================================================================== --- sys/mips/include/elf.h +++ sys/mips/include/elf.h @@ -144,8 +144,10 @@ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ #define ET_DYN_LOAD_ADDR 0x0120000 Index: sys/powerpc/include/elf.h =================================================================== --- sys/powerpc/include/elf.h +++ sys/powerpc/include/elf.h @@ -107,8 +107,10 @@ #define AT_PAGESIZESLEN 19 /* Number of pagesizes. */ #define AT_STACKPROT 21 /* Initial stack protection. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 23 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ /* * Relocation types. Index: sys/riscv/include/elf.h =================================================================== --- sys/riscv/include/elf.h +++ sys/riscv/include/elf.h @@ -90,8 +90,10 @@ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #define ELF_TARG_CLASS ELFCLASS64 Index: sys/sparc64/include/elf.h =================================================================== --- sys/sparc64/include/elf.h +++ sys/sparc64/include/elf.h @@ -92,8 +92,10 @@ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ /* Define "machine" characteristics */ #if __ELF_WORD_SIZE == 32 Index: sys/sys/sysent.h =================================================================== --- sys/sys/sysent.h +++ sys/sys/sysent.h @@ -129,6 +129,7 @@ void (*sv_schedtail)(struct thread *); void (*sv_thread_detach)(struct thread *); int (*sv_trap)(struct thread *); + u_long *sv_hwcap; /* Value passed in AT_HWCAP. */ }; #define SV_ILP32 0x000100 /* 32-bit executable. */ Index: sys/x86/include/elf.h =================================================================== --- sys/x86/include/elf.h +++ sys/x86/include/elf.h @@ -100,8 +100,10 @@ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ #define AT_TIMEKEEP 22 /* Pointer to timehands. */ #define AT_STACKPROT 23 /* Initial stack protection. */ +#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */ +#define AT_HWCAP 25 /* CPU feature flags. */ -#define AT_COUNT 24 /* Count of defined aux entry types. */ +#define AT_COUNT 26 /* Count of defined aux entry types. */ /* * Relocation types.