Index: head/sys/arm/arm/elf_machdep.c =================================================================== --- head/sys/arm/arm/elf_machdep.c +++ head/sys/arm/arm/elf_machdep.c @@ -46,6 +46,8 @@ #include #include +static boolean_t elf32_arm_abi_supported(struct image_params *); + struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, @@ -90,7 +92,8 @@ .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf32_freebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE, + .header_supported= elf32_arm_abi_supported, }; SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, @@ -106,13 +109,42 @@ .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, .brand_note = &elf32_freebsd_brandnote, - .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE, + .header_supported= elf32_arm_abi_supported, }; SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); +static boolean_t +elf32_arm_abi_supported(struct image_params *imgp) +{ + const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; + +#ifdef __ARM_EABI__ + /* + * When configured for EABI, FreeBSD supports EABI vesions 4 and 5. + */ + if (EF_ARM_EABI_VERSION(hdr->e_flags) < EF_ARM_EABI_FREEBSD_MIN) { + if (bootverbose) + uprintf("Attempting to execute non EABI binary (rev %d) image %s", + EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname); + return (FALSE); + } +#else + /* + * When configured for OABI, that's all we do, so reject EABI binaries. + */ + if (EF_ARM_EABI_VERSION(hdr->e_flags) != EF_ARM_EABI_VERSION_UNKNOWN) { + if (bootverbose) + uprintf("Attempting to execute EABI binary (rev %d) image %s", + EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname); + return (FALSE); + } +#endif + return (TRUE); +} void elf32_dump_thread(struct thread *td __unused, void *dst __unused, Index: head/sys/arm/include/elf.h =================================================================== --- head/sys/arm/include/elf.h +++ head/sys/arm/include/elf.h @@ -103,6 +103,12 @@ #define ELF_TARG_MACH EM_ARM #define ELF_TARG_VER 1 +/* Defines specific for arm headers */ +#define EF_ARM_EABIMASK 0xff000000 +#define EF_ARM_EABI_VERSION(x) (((x) & EF_ARM_EABIMASK) >> 24) +#define EF_ARM_EABI_VERSION_UNKNOWN 0 +#define EF_ARM_EABI_FREEBSD_MIN 4 + /* * Magic number for the elf trampoline, chosen wisely to be an immediate * value. Index: head/sys/kern/imgact_elf.c =================================================================== --- head/sys/kern/imgact_elf.c +++ head/sys/kern/imgact_elf.c @@ -294,6 +294,19 @@ return (bi); } + /* No known brand, see if the header is recognized by any brand */ + for (i = 0; i < MAX_BRANDS; i++) { + bi = elf_brand_list[i]; + if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY || + bi->header_supported == NULL) + continue; + if (hdr->e_machine == bi->machine) { + ret = bi->header_supported(imgp); + if (ret) + return (bi); + } + } + /* Lacking a known brand, search for a recognized interpreter. */ if (interp != NULL) { for (i = 0; i < MAX_BRANDS; i++) { Index: head/sys/sys/imgact_elf.h =================================================================== --- head/sys/sys/imgact_elf.h +++ head/sys/sys/imgact_elf.h @@ -74,6 +74,7 @@ const char *interp_newpath; int flags; Elf_Brandnote *brand_note; + boolean_t (*header_supported)(struct image_params *); #define BI_CAN_EXEC_DYN 0x0001 #define BI_BRAND_NOTE 0x0002 /* May have note.ABI-tag section. */ #define BI_BRAND_NOTE_MANDATORY 0x0004 /* Must have note.ABI-tag section. */