Author: imp
Date: Mon Aug 18 02:44:56 2014
New Revision: 270123
URL: http://svnweb.freebsd.org/changeset/base/270123

Log:
  Expand the elf brandelf infrastructure to give access to the whole ELF
  header (Elf_Ehdr) to determine if a particular interpretor wants to
  accept it or not. Use this mechanism to filter EABI arm on OABI arm
  kernels, and vice versa. This method could also be used to implement
  OABI on EABI arm kernels, if desired, or to allow a single mips kernel
  to run o32, n32 and n64 binaries.
  
  Differential Revision: https://reviews.freebsd.org/D609

Modified:
  head/sys/arm/arm/elf_machdep.c
  head/sys/arm/include/elf.h
  head/sys/kern/imgact_elf.c
  head/sys/sys/imgact_elf.h

Modified: head/sys/arm/arm/elf_machdep.c
==============================================================================
--- head/sys/arm/arm/elf_machdep.c      Mon Aug 18 02:42:23 2014        
(r270122)
+++ head/sys/arm/arm/elf_machdep.c      Mon Aug 18 02:44:56 2014        
(r270123)
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 #include <machine/elf.h>
 #include <machine/md_var.h>
 
+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 @@ static Elf32_Brandinfo freebsd_brand_inf
        .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 @@ static Elf32_Brandinfo freebsd_brand_oin
        .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,

Modified: head/sys/arm/include/elf.h
==============================================================================
--- head/sys/arm/include/elf.h  Mon Aug 18 02:42:23 2014        (r270122)
+++ head/sys/arm/include/elf.h  Mon Aug 18 02:44:56 2014        (r270123)
@@ -103,6 +103,12 @@ __ElfType(Auxinfo);
 #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.

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c  Mon Aug 18 02:42:23 2014        (r270122)
+++ head/sys/kern/imgact_elf.c  Mon Aug 18 02:44:56 2014        (r270123)
@@ -294,6 +294,19 @@ __elfN(get_brandinfo)(struct image_param
                        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++) {

Modified: head/sys/sys/imgact_elf.h
==============================================================================
--- head/sys/sys/imgact_elf.h   Mon Aug 18 02:42:23 2014        (r270122)
+++ head/sys/sys/imgact_elf.h   Mon Aug 18 02:44:56 2014        (r270123)
@@ -74,6 +74,7 @@ typedef struct {
        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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to