Index: sys/arm/arm/elf_machdep.c =================================================================== --- sys/arm/arm/elf_machdep.c +++ sys/arm/arm/elf_machdep.c @@ -47,6 +47,9 @@ #include static boolean_t elf32_arm_abi_supported(struct image_params *); +#ifdef COMPAT_ARM_SOFT_FP +static boolean_t elf32_arm_soft_supported(struct image_params *); +#endif struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, @@ -100,6 +103,26 @@ (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_info); +#ifdef COMPAT_ARM_SOFT_FP +static Elf32_Brandinfo freebsd_brand_info_soft = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_ARM, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/libexec/ld-elf-soft.so.1", + .sysvec = &elf32_freebsd_sysvec, + .interp_newpath = NULL, + .brand_note = &elf32_freebsd_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE, + .header_supported= elf32_arm_soft_supported, +}; + +SYSINIT(elf32soft, SI_SUB_EXEC, SI_ORDER_FIRST, + (sysinit_cfunc_t) elf32_insert_brand_entry, + &freebsd_brand_info_soft); +#endif + + static boolean_t elf32_arm_abi_supported(struct image_params *imgp) { @@ -115,6 +138,13 @@ EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname); return (FALSE); } + /* + * Only support hard-float here. + */ +#ifdef COMPAT_ARM_SOFT_FP + if ((hdr->e_flags & EF_ARM_VFP_FLOAT) == 0) + return (FALSE); +#endif #else /* * When configured for OABI, that's all we do, so reject EABI binaries. @@ -129,6 +159,26 @@ return (TRUE); } +#ifdef COMPAT_ARM_SOFT_FP +static boolean_t +elf32_arm_soft_supported(struct image_params *imgp) +{ + const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; + + /* + * Looking specifically for EABI 4 or 5 soft float programs. + * Note: FreeBSD 10 and earlier didn't set EF_ARM_SOFT_FLOAT + * on these binaries like it should have, so interpret + * that as meaning 'soft float' too. + */ + if (EF_ARM_EABI_VERSION(hdr->e_flags) < EF_ARM_EABI_FREEBSD_MIN || + (hdr->e_flags & EF_ARM_VFP_FLOAT) != 0) + return (FALSE); + + return (TRUE); +} +#endif + void elf32_dump_thread(struct thread *td __unused, void *dst __unused, size_t *off __unused) Index: sys/conf/options.arm =================================================================== --- sys/conf/options.arm +++ sys/conf/options.arm @@ -7,6 +7,7 @@ ARM_NEW_PMAP opt_global.h NKPT2PG opt_pmap.h ARM_WANT_TP_ADDRESS opt_global.h +COMPAT_ARM_SOFT_FLOAT opt_global.h COUNTS_PER_SEC opt_timer.h CPU_ARM9 opt_global.h CPU_ARM9E opt_global.h