Example #1
0
enum{
    __XYX__CPU_STATE_MAX     = CPU_STATE_MAX,

    __XYX__CPU_STATE_USER    = CPU_STATE_USER  ,
    __XYX__CPU_STATE_SYSTEM  = CPU_STATE_SYSTEM,
    __XYX__CPU_STATE_IDLE    = CPU_STATE_IDLE  ,
    __XYX__CPU_STATE_NICE    = CPU_STATE_NICE  ,



/*
 * Capability bits used in the definition of cpu_type.
 */
    __XYX__CPU_ARCH_MASK  = CPU_ARCH_MASK ,      /* mask for architecture bits */
    __XYX__CPU_ARCH_ABI64 = CPU_ARCH_ABI64,      /* 64 bit ABI */

/*
 *  Machine types known by all.
 */
 
    __XYX__CPU_TYPE_ANY = CPU_TYPE_ANY,

    __XYX__CPU_TYPE_VAX     =  CPU_TYPE_VAX     ,
    __XYX__CPU_TYPE_MC680x0 =  CPU_TYPE_MC680x0 ,
    __XYX__CPU_TYPE_X86     =  CPU_TYPE_X86     ,
    __XYX__CPU_TYPE_I386    =  CPU_TYPE_I386    ,   /* compatibility */
    __XYX__CPU_TYPE_X86_64  =  CPU_TYPE_X86_64  ,

/* skip CPU_TYPE_MIPS       ((cpu_type_t) 8)    */

    __XYX__CPU_TYPE_MC98000 =  CPU_TYPE_MC98000,
    __XYX__CPU_TYPE_HPPA    =  CPU_TYPE_HPPA   ,
    __XYX__CPU_TYPE_ARM     =  CPU_TYPE_ARM    ,
    __XYX__CPU_TYPE_MC88000 =  CPU_TYPE_MC88000,
    __XYX__CPU_TYPE_SPARC   =  CPU_TYPE_SPARC  ,
    __XYX__CPU_TYPE_I860    =  CPU_TYPE_I860   ,

/* skip CPU_TYPE_ALPHA      ((cpu_type_t) 16)   */

    __XYX__CPU_TYPE_POWERPC   = CPU_TYPE_POWERPC   ,
    __XYX__CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC64 ,

/*
 *  Machine subtypes (these are defined here, instead of in a machine
 *  dependent directory, so that any program can get all definitions
 *  regardless of where is it compiled).
 */

/*
 * Capability bits used in the definition of cpu_subtype.
 */
    __XYX__CPU_SUBTYPE_MASK  = CPU_SUBTYPE_MASK ,  /* mask for feature flags */
    __XYX__CPU_SUBTYPE_LIB64 = CPU_SUBTYPE_LIB64,  /* 64 bit libraries */


/*
 *  Object files that are hand-crafted to run on any
 *  implementation of an architecture are tagged with
 *  CPU_SUBTYPE_MULTIPLE.  This functions essentially the same as
 *  the "ALL" subtype of an architecture except that it allows us
 *  to easily find object files that may need to be modified
 *  whenever a new implementation of an architecture comes out.
 *
 *  It is the responsibility of the implementor to make sure the
 *  software handles unsupported implementations elegantly.
 */
    __XYX__CPU_SUBTYPE_MULTIPLE      =  CPU_SUBTYPE_MULTIPLE      ,
    __XYX__CPU_SUBTYPE_LITTLE_ENDIAN =  CPU_SUBTYPE_LITTLE_ENDIAN ,
    __XYX__CPU_SUBTYPE_BIG_ENDIAN    =  CPU_SUBTYPE_BIG_ENDIAN    ,

/*
 *     Machine threadtypes.
 *     This is none - not defined - for most machine types/subtypes.
 */
    __XYX__CPU_THREADTYPE_NONE = CPU_THREADTYPE_NONE,

/*
 *  VAX subtypes (these do *not* necessary conform to the actual cpu
 *  ID assigned by DEC available via the SID register).
 */

    __XYX__CPU_SUBTYPE_VAX_ALL = CPU_SUBTYPE_VAX_ALL ,
    __XYX__CPU_SUBTYPE_VAX780  = CPU_SUBTYPE_VAX780  ,
    __XYX__CPU_SUBTYPE_VAX785  = CPU_SUBTYPE_VAX785  ,
    __XYX__CPU_SUBTYPE_VAX750  = CPU_SUBTYPE_VAX750  ,
    __XYX__CPU_SUBTYPE_VAX730  = CPU_SUBTYPE_VAX730  ,
    __XYX__CPU_SUBTYPE_UVAXI   = CPU_SUBTYPE_UVAXI   ,
    __XYX__CPU_SUBTYPE_UVAXII  = CPU_SUBTYPE_UVAXII  ,
    __XYX__CPU_SUBTYPE_VAX8200 = CPU_SUBTYPE_VAX8200 ,
    __XYX__CPU_SUBTYPE_VAX8500 = CPU_SUBTYPE_VAX8500 ,
    __XYX__CPU_SUBTYPE_VAX8600 = CPU_SUBTYPE_VAX8600 ,
    __XYX__CPU_SUBTYPE_VAX8650 = CPU_SUBTYPE_VAX8650 ,
    __XYX__CPU_SUBTYPE_VAX8800 = CPU_SUBTYPE_VAX8800 ,
    __XYX__CPU_SUBTYPE_UVAXIII = CPU_SUBTYPE_UVAXIII ,

/*
 *  680x0 subtypes
 *
 * The subtype definitions here are unusual for historical reasons.
 * NeXT used to consider 68030 code as generic 68000 code.  For
 * backwards compatability:
 * 
 *  CPU_SUBTYPE_MC68030 symbol has been preserved for source code
 *  compatability.
 *
 *  CPU_SUBTYPE_MC680x0_ALL has been defined to be the same
 *  subtype as CPU_SUBTYPE_MC68030 for binary comatability.
 *
 *  CPU_SUBTYPE_MC68030_ONLY has been added to allow new object
 *  files to be tagged as containing 68030-specific instructions.
 */

    __XYX__CPU_SUBTYPE_MC680x0_ALL  = CPU_SUBTYPE_MC680x0_ALL  ,
    __XYX__CPU_SUBTYPE_MC68030      = CPU_SUBTYPE_MC68030      ,/* compat */
    __XYX__CPU_SUBTYPE_MC68040      = CPU_SUBTYPE_MC68040      ,
    __XYX__CPU_SUBTYPE_MC68030_ONLY = CPU_SUBTYPE_MC68030_ONLY ,

/*
 *  I386 subtypes
 */

    __XYX__CPU_SUBTYPE_I386_ALL       = CPU_SUBTYPE_I386_ALL       ,
    __XYX__CPU_SUBTYPE_386            = CPU_SUBTYPE_386            ,
    __XYX__CPU_SUBTYPE_486            = CPU_SUBTYPE_486            ,
    __XYX__CPU_SUBTYPE_486SX          = CPU_SUBTYPE_486SX          ,
    __XYX__CPU_SUBTYPE_586            = CPU_SUBTYPE_586            ,
    __XYX__CPU_SUBTYPE_PENT           = CPU_SUBTYPE_PENT           ,
    __XYX__CPU_SUBTYPE_PENTPRO        = CPU_SUBTYPE_PENTPRO        ,
    __XYX__CPU_SUBTYPE_PENTII_M3      = CPU_SUBTYPE_PENTII_M3      ,
    __XYX__CPU_SUBTYPE_PENTII_M5      = CPU_SUBTYPE_PENTII_M5      ,
    __XYX__CPU_SUBTYPE_CELERON        = CPU_SUBTYPE_CELERON        ,
    __XYX__CPU_SUBTYPE_CELERON_MOBILE = CPU_SUBTYPE_CELERON_MOBILE ,
    __XYX__CPU_SUBTYPE_PENTIUM_3      = CPU_SUBTYPE_PENTIUM_3      ,
    __XYX__CPU_SUBTYPE_PENTIUM_3_M    = CPU_SUBTYPE_PENTIUM_3_M    ,
    __XYX__CPU_SUBTYPE_PENTIUM_3_XEON = CPU_SUBTYPE_PENTIUM_3_XEON ,
    __XYX__CPU_SUBTYPE_PENTIUM_M      = CPU_SUBTYPE_PENTIUM_M      ,
    __XYX__CPU_SUBTYPE_PENTIUM_4      = CPU_SUBTYPE_PENTIUM_4      ,
    __XYX__CPU_SUBTYPE_PENTIUM_4_M    = CPU_SUBTYPE_PENTIUM_4_M    ,
    __XYX__CPU_SUBTYPE_ITANIUM        = CPU_SUBTYPE_ITANIUM        ,
    __XYX__CPU_SUBTYPE_ITANIUM_2      = CPU_SUBTYPE_ITANIUM_2      ,
    __XYX__CPU_SUBTYPE_XEON           = CPU_SUBTYPE_XEON           ,
    __XYX__CPU_SUBTYPE_XEON_MP        = CPU_SUBTYPE_XEON_MP        ,
}

#ifdef CPU_SUBTYPE_INTEL_FAMILY
uint extractSubtypeIntelFamily(uint x){
    return CPU_SUBTYPE_INTEL_FAMILY(x);
}
/*
 * get_arch_from_host() gets the architecture from the host this is running on
 * and returns zero if the architecture is not known and zero if the
 * architecture is known.  If the parameters family_arch_flag and
 * specific_arch_flag are not NULL they get fill in with the family
 * architecture and specific architecure for the host.  If the architecture
 * is unknown and the parameters are not NULL then all fields are set to zero.
 */
__private_extern__
int
get_arch_from_host(
struct arch_flag *family_arch_flag,
struct arch_flag *specific_arch_flag)
{
    struct host_basic_info host_basic_info;
    natural_t count; /* cctools-port: unsigned int -> natural_t */
    kern_return_t r;
    mach_port_t my_mach_host_self;

	if(family_arch_flag != NULL)
	    memset(family_arch_flag, '\0', sizeof(struct arch_flag));
	if(specific_arch_flag != NULL)
	    memset(specific_arch_flag, '\0', sizeof(struct arch_flag));

	count = HOST_BASIC_INFO_COUNT;
	my_mach_host_self = mach_host_self();
	if((r = host_info(my_mach_host_self, HOST_BASIC_INFO,
			  (host_info_t)(&host_basic_info),
			  &count)) != KERN_SUCCESS){
	    mach_port_deallocate(mach_task_self(), my_mach_host_self);
	    return(0);
	}
	mach_port_deallocate(mach_task_self(), my_mach_host_self);

	if(family_arch_flag != NULL){
	    family_arch_flag->cputype = host_basic_info.cpu_type;
	}
	if(specific_arch_flag != NULL){
	    specific_arch_flag->cputype = host_basic_info.cpu_type;
	    specific_arch_flag->cpusubtype = host_basic_info.cpu_subtype;
	}
	switch(host_basic_info.cpu_type){
	case CPU_TYPE_MC680x0:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_MC680x0_ALL:
	    case CPU_SUBTYPE_MC68030_ONLY:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "m68k";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
		}
		if(specific_arch_flag != NULL){
		    specific_arch_flag->name = "m68030";
		    /* 
		     * There is a "bug" in the kernel for compatiblity that on
		     * an 030 machine host_info() returns cpusubtype
		     * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
		     */
		    specific_arch_flag->cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
		}
		return(1);
	    case CPU_SUBTYPE_MC68040:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "m68k";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "m68040";
		return(1);
	    }
	    break;
	case CPU_TYPE_POWERPC:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_POWERPC_ALL:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc";
		return(1);
	    case CPU_SUBTYPE_POWERPC_601:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc601";
		return(1);
	    case CPU_SUBTYPE_POWERPC_603:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc603";
		return(1);
	    case CPU_SUBTYPE_POWERPC_603e:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc603e";
		return(1);
	    case CPU_SUBTYPE_POWERPC_603ev:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc603ev";
		return(1);
	    case CPU_SUBTYPE_POWERPC_604:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc604";
		return(1);
	    case CPU_SUBTYPE_POWERPC_604e:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc604e";
		return(1);
	    case CPU_SUBTYPE_POWERPC_750:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc750";
		return(1);
	    case CPU_SUBTYPE_POWERPC_7400:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc7400";
		return(1);
	    case CPU_SUBTYPE_POWERPC_7450:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc7450";
		return(1);
	    case CPU_SUBTYPE_POWERPC_970:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "ppc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "ppc970";
		return(1);
	    default:
		if(family_arch_flag != NULL){
                    family_arch_flag->name = "ppc";
                    family_arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL;
                }
                if(specific_arch_flag != NULL){
                    specific_arch_flag->name = 
			savestr("PowerPC cpusubtype 1234567890");
                    if(specific_arch_flag->name != NULL)
			sprintf(specific_arch_flag->name,
				"PowerPC cpusubtype %u", 
				host_basic_info.cpu_subtype);
		}
                return(1);
	    }
	    break;
	case CPU_TYPE_VEO:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_VEO_1:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "veo";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_VEO_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "veo1";
		return(1);
	    case CPU_SUBTYPE_VEO_2:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "veo";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_VEO_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "veo2";
		return(1);
	    case CPU_SUBTYPE_VEO_3:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "veo";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_VEO_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "veo3";
		return(1);
	    case CPU_SUBTYPE_VEO_4:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "veo";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_VEO_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "veo4";
		return(1);
	    default:
		if(family_arch_flag != NULL){
                    family_arch_flag->name = "veo";
                    family_arch_flag->cpusubtype = CPU_SUBTYPE_VEO_ALL;
                }
                if(specific_arch_flag != NULL){
                    specific_arch_flag->name = 
			savestr("VEO cpusubtype 1234567890");
		    sprintf(specific_arch_flag->name,
				"VEO cpusubtype %u", 
				host_basic_info.cpu_subtype);
		}
                return(1);
	    }
	    break;
	case CPU_TYPE_MC88000:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_MC88000_ALL:
	    case CPU_SUBTYPE_MC88110:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "m88k";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_MC88000_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "m88k";
		return(1);
	    }
	    break;
	case CPU_TYPE_I386:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_I386_ALL:
	    /* case CPU_SUBTYPE_386: same value as above */
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "i386";
		return(1);
	    case CPU_SUBTYPE_486:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "i486";
		return(1);
	    case CPU_SUBTYPE_486SX:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "i486SX";
		return(1);
	    case CPU_SUBTYPE_PENT: /* same as CPU_SUBTYPE_586 */
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "pentium";
		return(1);
	    case CPU_SUBTYPE_PENTPRO:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "pentpro";
		return(1);
	    case CPU_SUBTYPE_PENTII_M3:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "pentIIm3";
		return(1);
	    case CPU_SUBTYPE_PENTII_M5:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "pentIIm5";
		return(1);
	    case CPU_SUBTYPE_PENTIUM_4:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "pentium4";
		return(1);
	    default:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i386";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
                }
                if(specific_arch_flag != NULL){
                    specific_arch_flag->name =
			savestr("Intel family 12 model 12345678");
		    if(specific_arch_flag->name != NULL)
			sprintf(specific_arch_flag->name,
			    "Intel family %u model %u", 
			CPU_SUBTYPE_INTEL_FAMILY(host_basic_info.cpu_subtype),
			CPU_SUBTYPE_INTEL_MODEL(host_basic_info.cpu_subtype));
		}
                return(1);
	    }
	    break;
	case CPU_TYPE_I860:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_I860_ALL:
	    case CPU_SUBTYPE_I860_860:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "i860";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_I860_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "i860";
		return(1);
	    }
	    break;
	case CPU_TYPE_HPPA:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_HPPA_ALL:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "hppa";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "hppa";
		return(1);
	    case CPU_SUBTYPE_HPPA_7100LC:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "hppa";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "hppa7100LC";
		return(1);
	      
	    }
	    break;
	case CPU_TYPE_SPARC:
	    switch(host_basic_info.cpu_subtype){
	    case /*CPU_SUBTYPE_SPARC_ALL*/0:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "sparc";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_SPARC_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "sparc";
		return(1);
	    }
	    break;
	case CPU_TYPE_ARM:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_ARM_ALL:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "arm";
		return(1);
	    case CPU_SUBTYPE_ARM_V4T:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv4t";
		return(1);
	    case CPU_SUBTYPE_ARM_V5TEJ:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv5";
		return(1);
	    case CPU_SUBTYPE_ARM_XSCALE:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "xscale";
		return(1);
	    case CPU_SUBTYPE_ARM_V6:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv6";
		return(1);
	    case CPU_SUBTYPE_ARM_V6M:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv6m";
		return(1);
	    case CPU_SUBTYPE_ARM_V7:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7";
		return(1);
	    case CPU_SUBTYPE_ARM_V7F:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7f";
		return(1);
	    case CPU_SUBTYPE_ARM_V7S:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7s";
		return(1);
	    case CPU_SUBTYPE_ARM_V7K:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7k";
		return(1);
	    case CPU_SUBTYPE_ARM_V7M:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7m";
		return(1);
	    case CPU_SUBTYPE_ARM_V7EM:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "armv7em";
		return(1);
	    }
	    break;
	case CPU_TYPE_ARM64:
	    switch(host_basic_info.cpu_subtype){
	    case CPU_SUBTYPE_ARM64_ALL:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm64";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "arm64";
		return(1);
	    case CPU_SUBTYPE_ARM64_V8:
		if(family_arch_flag != NULL){
		    family_arch_flag->name = "arm64";
		    family_arch_flag->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
		}
		if(specific_arch_flag != NULL)
		    specific_arch_flag->name = "arm64v8";
		return(1);
	    }
	    break;
	}
	return(0);
}
Example #3
0
/*
 * NXFindBestFatArch() is passed a cputype and cpusubtype and a set of
 * fat_arch structs and selects the best one that matches (if any) and returns
 * a pointer to that fat_arch struct (or NULL).  The fat_arch structs must be
 * in the host byte order and correct such that the fat_archs really points to
 * enough memory for nfat_arch structs.  It is possible that this routine could
 * fail if new cputypes or cpusubtypes are added and an old version of this
 * routine is used.  But if there is an exact match between the cputype and
 * cpusubtype and one of the fat_arch structs this routine will always succeed.
 */
struct fat_arch *
NXFindBestFatArch(
cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch *fat_archs,
uint32_t nfat_archs)
{
    uint32_t i;
    int32_t lowest_family, lowest_model, lowest_index;

	/*
	 * Look for the first exact match.
	 */
	for(i = 0; i < nfat_archs; i++){
	    if(fat_archs[i].cputype == cputype &&
	       (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		(cpusubtype & ~CPU_SUBTYPE_MASK))
		return(fat_archs + i);
	}

	/*
	 * An exact match was not found so find the next best match which is
	 * cputype dependent.
	 */
	switch(cputype){
	case CPU_TYPE_I386:
	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
	    default:
		/*
		 * Intel cpusubtypes after the pentium (same as 586) are handled
		 * such that they require an exact match or they can use the
		 * pentium.  If that is not found call into the loop for the
		 * earilier subtypes.
		 */
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_PENT)
			return(fat_archs + i);
		}
	    case CPU_SUBTYPE_PENT:
	    case CPU_SUBTYPE_486SX:
		/*
		 * Since an exact match as not found look for the i486 else
		 * break into the loop to look for the i386_ALL.
		 */
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_486)
			return(fat_archs + i);
		}
		break;
	    case CPU_SUBTYPE_I386_ALL:
	    /* case CPU_SUBTYPE_I386: same as above */
	    case CPU_SUBTYPE_486:
		break;
	    }
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		    CPU_SUBTYPE_I386_ALL)
		    return(fat_archs + i);
	    }

	    /*
	     * A match failed, promote as little as possible.
	     */
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_486)
		    return(fat_archs + i);
	    }
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_486SX)
		    return(fat_archs + i);
	    }
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_586)
		    return(fat_archs + i);
	    }
	    /*
	     * Now look for the lowest family and in that the lowest model.
	     */
	    lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
					    ~CPU_SUBTYPE_MASK) < lowest_family)
		    lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
				fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK);
	    }
	    /* if no intel cputypes found return NULL */
	    if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
		return(NULL);
	    lowest_model = INT_MAX;
	    lowest_index = -1;
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype &
			~CPU_SUBTYPE_MASK) == lowest_family){
		    if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype &
			~CPU_SUBTYPE_MASK) < lowest_model){
		        lowest_model = CPU_SUBTYPE_INTEL_MODEL(
					fat_archs[i].cpusubtype &
					~CPU_SUBTYPE_MASK);
			lowest_index = i;
		    }
		}
	    }
	    return(fat_archs + lowest_index);
	case CPU_TYPE_X86_64:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_X86_64_ALL)
		    return(fat_archs + i);
	    }
	    break;
	case CPU_TYPE_MC680x0:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_MC680x0_ALL)
		    return(fat_archs + i);
	    }
	    /*
	     * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and
	     * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY.
	     */
	    if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		       CPU_SUBTYPE_MC68040)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		       CPU_SUBTYPE_MC68030_ONLY)
			return(fat_archs + i);
		}
	    }
	    break;
	case CPU_TYPE_POWERPC:
	    /*
	     * An exact match as not found.  So for all the PowerPC subtypes
	     * pick the subtype from the following order starting from a subtype
	     * that will work (contains 64-bit instructions or altivec if
	     * needed):
	     *	970, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL
	     * Note the 601 is NOT in the list above.  It is only picked via
	     * an exact match.  For an unknown subtype pick only the ALL type if
	     * it exists.
	     */
	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
	    case CPU_SUBTYPE_POWERPC_ALL:
		/*
		 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
		 * environment tools when building a generic ALL type binary.
		 * In the case of a non-exact match we pick the most current
		 * processor.
		 */
	    case CPU_SUBTYPE_POWERPC_970:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_970)
			return(fat_archs + i);
		}
	    case CPU_SUBTYPE_POWERPC_7450:
	    case CPU_SUBTYPE_POWERPC_7400:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_7450)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_7400)
			return(fat_archs + i);
		}
	    case CPU_SUBTYPE_POWERPC_750:
	    case CPU_SUBTYPE_POWERPC_604e:
	    case CPU_SUBTYPE_POWERPC_604:
	    case CPU_SUBTYPE_POWERPC_603ev:
	    case CPU_SUBTYPE_POWERPC_603e:
	    case CPU_SUBTYPE_POWERPC_603:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_750)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_604e)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_604)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if((fat_archs[i].cputype & ~CPU_SUBTYPE_MASK) != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_603ev)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_603e)
			return(fat_archs + i);
		}
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_603)
			return(fat_archs + i);
		}
	    default:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_ALL)
			return(fat_archs + i);
		}
	    }
	    break;
	case CPU_TYPE_POWERPC64:
	    /*
	     * An exact match as not found.  So for all the PowerPC64 subtypes
	     * pick the subtype from the following order starting from a subtype
	     * that will work (contains 64-bit instructions or altivec if
	     * needed):
	     *	970 (currently only the one 64-bit subtype)
	     * For an unknown subtype pick only the ALL type if it exists.
	     */
	    switch(cpusubtype & ~CPU_SUBTYPE_MASK){
	    case CPU_SUBTYPE_POWERPC_ALL:
		/*
		 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development
		 * environment tools when building a generic ALL type binary.
		 * In the case of a non-exact match we pick the most current
		 * processor.
		 */
	    case CPU_SUBTYPE_POWERPC_970:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_970)
			return(fat_archs + i);
		}
	    default:
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
			CPU_SUBTYPE_POWERPC_ALL)
			return(fat_archs + i);
		}
	    }
	    break;
	case CPU_TYPE_MC88000:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_MC88000_ALL)
		    return(fat_archs + i);
	    }
	    break;
	case CPU_TYPE_I860:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_I860_ALL)
		    return(fat_archs + i);
	    }
	    break;
	case CPU_TYPE_HPPA:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_HPPA_ALL)
		    return(fat_archs + i);
	    }
	    break;
	case CPU_TYPE_SPARC:
	    for(i = 0; i < nfat_archs; i++){
		if(fat_archs[i].cputype != cputype)
		    continue;
		if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) ==
		   CPU_SUBTYPE_SPARC_ALL)
		    return(fat_archs + i);
	    }
	    break;
	case CPU_TYPE_ARM:
	    {
		/* 
		 * ARM is straightforward, since each architecture is backward
		 * compatible with previous architectures.  So, we just take the
		 * highest that is less than our target.
		 */
		int fat_match_found = 0;
		uint32_t best_fat_arch = 0;
		for(i = 0; i < nfat_archs; i++){
		    if(fat_archs[i].cputype != cputype)
			continue;
		    if(fat_archs[i].cpusubtype > cpusubtype)
			continue;
		    if(!fat_match_found){
			fat_match_found = 1;
			best_fat_arch = i;
			continue;
		    }
		    if(fat_archs[i].cpusubtype >
		       fat_archs[best_fat_arch].cpusubtype)
			best_fat_arch = i;
		}
		if(fat_match_found)
		  return fat_archs + best_fat_arch;
	    }
	    break;
	default:
	    return(NULL);
	}
	return(NULL);
}