#ifndef RLD
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "mach/machine.h"
#include "mach/mach.h"
#include "stuff/openstep_mach.h"
#include <mach-o/fat.h>
#include <mach-o/arch.h>
static const NXArchInfo ArchInfoTable[] = {
{"hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL, NX_BigEndian,
"HP-PA"},
{"i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL, NX_LittleEndian,
"Intel 80x86"},
{ "x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, NX_LittleEndian,
"Intel x86-64" },
{ "x86_64h", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H, NX_LittleEndian,
"Intel x86-64h Haswell" },
{"i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL, NX_BigEndian,
"Intel 860"},
{"m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL, NX_BigEndian,
"Motorola 68K"},
{"m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL, NX_BigEndian,
"Motorola 88K"},
{"ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
"PowerPC"},
{"ppc64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian,
"PowerPC 64-bit"},
{"sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL, NX_BigEndian,
"SPARC"},
{"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL, NX_LittleEndian,
"ARM"},
{"arm64", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL, NX_LittleEndian,
"ARM64"},
{"arm64_32",CPU_TYPE_ARM64_32,CPU_SUBTYPE_ARM64_32_V8, NX_LittleEndian,
"ARM64_32"},
{"arm64e", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64E, NX_LittleEndian,
"ARM64E"},
{"any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE, NX_UnknownByteOrder,
"Architecture Independent"},
{"veo", CPU_TYPE_VEO, CPU_SUBTYPE_VEO_ALL, NX_BigEndian,
"veo"},
{"hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC, NX_BigEndian,
"HP-PA 7100LC"},
{"m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY, NX_BigEndian,
"Motorola 68030"},
{"m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040, NX_BigEndian,
"Motorola 68040"},
{"i486", CPU_TYPE_I386, CPU_SUBTYPE_486, NX_LittleEndian,
"Intel 80486"},
{"i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX, NX_LittleEndian,
"Intel 80486SX"},
{"pentium",CPU_TYPE_I386, CPU_SUBTYPE_PENT, NX_LittleEndian,
"Intel Pentium"},
{"i586", CPU_TYPE_I386, CPU_SUBTYPE_586, NX_LittleEndian,
"Intel 80586"},
{"pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
"Intel Pentium Pro"},
{"i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian,
"Intel Pentium Pro"},
{"pentIIm3", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3, NX_LittleEndian,
"Intel Pentium II Model 3" },
{"pentIIm5", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5, NX_LittleEndian,
"Intel Pentium II Model 5" },
{"pentium4", CPU_TYPE_I386, CPU_SUBTYPE_PENTIUM_4, NX_LittleEndian,
"Intel Pentium 4" },
{ "x86_64h", CPU_TYPE_I386, CPU_SUBTYPE_X86_64_H, NX_LittleEndian,
"Intel x86-64h Haswell" },
{"ppc601", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601, NX_BigEndian,
"PowerPC 601" },
{"ppc603", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603, NX_BigEndian,
"PowerPC 603" },
{"ppc603e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603e, NX_BigEndian,
"PowerPC 603e" },
{"ppc603ev",CPU_TYPE_POWERPC,CPU_SUBTYPE_POWERPC_603ev,NX_BigEndian,
"PowerPC 603ev" },
{"ppc604", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604, NX_BigEndian,
"PowerPC 604" },
{"ppc604e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604e, NX_BigEndian,
"PowerPC 604e" },
{"ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750, NX_BigEndian,
"PowerPC 750" },
{"ppc7400",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400, NX_BigEndian,
"PowerPC 7400" },
{"ppc7450",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450, NX_BigEndian,
"PowerPC 7450" },
{"ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
"PowerPC 970" },
{"ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970, NX_BigEndian,
"PowerPC 970 64-bit"},
{"armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T, NX_LittleEndian,
"arm v4t"},
{"armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ, NX_LittleEndian,
"arm v5"},
{"xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE, NX_LittleEndian,
"arm xscale"},
{"armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, NX_LittleEndian,
"arm v6"},
{"armv6m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6M, NX_LittleEndian,
"arm v6m"},
{"armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7, NX_LittleEndian,
"arm v7"},
{"armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F, NX_LittleEndian,
"arm v7f"},
{"armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S, NX_LittleEndian,
"arm v7s"},
{"armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K, NX_LittleEndian,
"arm v7k"},
{"armv7m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7M, NX_LittleEndian,
"arm v7m"},
{"armv7em",CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7EM, NX_LittleEndian,
"arm v7em"},
{"armv8", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V8, NX_LittleEndian,
"arm v8"},
{"arm64",CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8, NX_LittleEndian,
"arm64 v8"},
{"little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian,
"Little Endian"},
{"big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN, NX_BigEndian,
"Big Endian"},
{"veo1",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_1, NX_BigEndian,
"veo 1" },
{"veo2",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_2, NX_BigEndian,
"veo 2" },
{NULL, 0, 0, 0,
NULL}
};
const
NXArchInfo *
NXGetAllArchInfos(void)
{
return(ArchInfoTable);
}
#ifdef HOST_PREFERRED_USER_ARCH
static
int32_t
internal_NXGetHostUserCPU(
cpu_type_t* out_cputype,
cpu_subtype_t* out_cpusubtype)
{
struct host_preferred_user_arch hi;
kern_return_t ret;
unsigned int count;
mach_port_t my_mach_host_self;
count = HOST_PREFERRED_USER_ARCH_COUNT;
my_mach_host_self = mach_host_self();
ret = host_info(my_mach_host_self, HOST_PREFERRED_USER_ARCH,
(host_info_t)&hi, &count);
mach_port_deallocate(mach_task_self(), my_mach_host_self);
if(ret != KERN_SUCCESS)
return(-1);
if (out_cputype != NULL)
*out_cputype = hi.cpu_type;
if (out_cpusubtype != NULL)
*out_cpusubtype = hi.cpu_subtype;
return(0);
}
#endif
static
kern_return_t
internal_NXGetHostBasicCPU(
cpu_type_t* out_cputype,
cpu_subtype_t* out_cpusubtype)
{
struct host_basic_info hi;
kern_return_t ret;
unsigned int count;
mach_port_t my_mach_host_self;
count = HOST_BASIC_INFO_COUNT;
my_mach_host_self = mach_host_self();
ret = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)&hi,
&count);
mach_port_deallocate(mach_task_self(), my_mach_host_self);
if(ret != KERN_SUCCESS)
return(-1);
if (out_cputype != NULL)
*out_cputype = hi.cpu_type;
if (out_cpusubtype != NULL)
*out_cpusubtype = hi.cpu_subtype;
return(0);
}
const
NXArchInfo *
NXGetLocalArchInfo(void)
{
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
int32_t ret;
ret = -1;
#ifdef HOST_PREFERRED_USER_ARCH
ret = internal_NXGetHostUserCPU(&cputype, &cpusubtype);
#endif
if (ret != 0)
ret = internal_NXGetHostBasicCPU(&cputype, &cpusubtype);
if(ret != 0)
return(NULL);
if(cputype == CPU_TYPE_MC680x0 && cpusubtype == CPU_SUBTYPE_MC680x0_ALL)
cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
return(NXGetArchInfoFromCpuType(cputype, cpusubtype));
}
const
NXArchInfo *
NXGetArchInfoFromName(
const char *name)
{
const NXArchInfo *ai;
for(ai = ArchInfoTable; ai->name != NULL; ai++)
if(strcmp(ai->name, name) == 0)
return(ai);
return(NULL);
}
const
NXArchInfo *
NXGetArchInfoFromCpuType(
cpu_type_t cputype,
cpu_subtype_t cpusubtype)
{
const NXArchInfo *ai;
NXArchInfo *q;
for(ai = ArchInfoTable; ai->name != NULL; ai++)
if(ai->cputype == cputype &&
(cpusubtype == CPU_SUBTYPE_MULTIPLE ||
((ai->cpusubtype & ~CPU_SUBTYPE_MASK) ==
(cpusubtype & ~CPU_SUBTYPE_MASK))))
return(ai);
if(cputype == CPU_TYPE_I386){
q = malloc(sizeof(NXArchInfo));
for(ai = ArchInfoTable; ai->name != NULL; ai++){
if(ai->cputype == cputype){
*q = *ai;
break;
}
}
q->cpusubtype = cpusubtype;
q->description = malloc(sizeof("Intel family model ") + 2 + 8);
if(q->description == NULL){
free(q);
return(NULL);
}
sprintf((char *)q->description, "Intel family %u model %u",
CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK),
CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK));
return((const NXArchInfo *)q);
}
else if(cputype == CPU_TYPE_POWERPC){
q = malloc(sizeof(NXArchInfo));
for(ai = ArchInfoTable; ai->name != NULL; ai++){
if(ai->cputype == cputype){
*q = *ai;
break;
}
}
q->cpusubtype = cpusubtype;
q->description = malloc(sizeof("PowerPC cpusubtype ") + 10);
if(q->description == NULL){
free(q);
return(NULL);
}
sprintf((char *)q->description, "PowerPC cpusubtype %u", cpusubtype);
return((const NXArchInfo *)q);
}
return(NULL);
}
void NXFreeArchInfo(
const NXArchInfo *x)
{
const NXArchInfo *p;
p = NXGetAllArchInfos();
while(p->name != NULL){
if(x == p)
return;
p++;
}
free((char *)x->description);
free((NXArchInfo *)x);
}
static
int32_t
internal_NXFindBestFatArch(
cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch *fat_archs,
struct fat_arch_64 *fat_archs64,
uint32_t nfat_archs)
{
uint32_t i;
int32_t lowest_family, lowest_model, lowest_index;
cpu_type_t fat_cputype;
cpu_subtype_t fat_cpusubtype;
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype == cputype &&
(fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
(cpusubtype & ~CPU_SUBTYPE_MASK))
return(i);
}
switch(cputype){
case CPU_TYPE_I386:
switch(cpusubtype & ~CPU_SUBTYPE_MASK){
default:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_PENT)
return(i);
}
case CPU_SUBTYPE_PENT:
case CPU_SUBTYPE_486SX:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_486)
return(i);
}
break;
case CPU_SUBTYPE_I386_ALL:
case CPU_SUBTYPE_486:
break;
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_I386_ALL)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_486)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_486SX)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_586)
return(i);
}
lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1;
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if(CPU_SUBTYPE_INTEL_FAMILY(fat_cpusubtype &
~CPU_SUBTYPE_MASK) < lowest_family)
lowest_family = CPU_SUBTYPE_INTEL_FAMILY(
fat_cpusubtype & ~CPU_SUBTYPE_MASK);
}
if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1)
return(-1);
lowest_model = INT_MAX;
lowest_index = -1;
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if(CPU_SUBTYPE_INTEL_FAMILY(fat_cpusubtype &
~CPU_SUBTYPE_MASK) == lowest_family){
if(CPU_SUBTYPE_INTEL_MODEL(fat_cpusubtype &
~CPU_SUBTYPE_MASK) < lowest_model){
lowest_model = CPU_SUBTYPE_INTEL_MODEL(
fat_cpusubtype &
~CPU_SUBTYPE_MASK);
lowest_index = i;
}
}
}
return(lowest_index);
case CPU_TYPE_X86_64:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_X86_64_ALL)
return(i);
}
break;
case CPU_TYPE_MC680x0:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_MC680x0_ALL)
return(i);
}
if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_MC68040)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_MC68030_ONLY)
return(i);
}
}
break;
case CPU_TYPE_POWERPC:
switch(cpusubtype & ~CPU_SUBTYPE_MASK){
case CPU_SUBTYPE_POWERPC_ALL:
case CPU_SUBTYPE_POWERPC_970:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_970)
return(i);
}
case CPU_SUBTYPE_POWERPC_7450:
case CPU_SUBTYPE_POWERPC_7400:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_7450)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_7400)
return(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_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_750)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_604e)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_604)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if((fat_cputype & ~CPU_SUBTYPE_MASK) != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_603ev)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_603e)
return(i);
}
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_603)
return(i);
}
default:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_ALL)
return(i);
}
}
break;
case CPU_TYPE_POWERPC64:
switch(cpusubtype & ~CPU_SUBTYPE_MASK){
case CPU_SUBTYPE_POWERPC_ALL:
case CPU_SUBTYPE_POWERPC_970:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_970)
return(i);
}
default:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_POWERPC_ALL)
return(i);
}
}
break;
case CPU_TYPE_MC88000:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_MC88000_ALL)
return(i);
}
break;
case CPU_TYPE_I860:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_I860_ALL)
return(i);
}
break;
case CPU_TYPE_HPPA:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_HPPA_ALL)
return(i);
}
break;
case CPU_TYPE_SPARC:
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if((fat_cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_SPARC_ALL)
return(i);
}
break;
case CPU_TYPE_ARM64_32:
return(-1);
case CPU_TYPE_ARM:
case CPU_TYPE_ARM64:
{
int fat_match_found = 0;
uint32_t best_fat_arch = 0;
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != cputype)
continue;
if(fat_cpusubtype > cpusubtype)
continue;
if(!fat_match_found){
fat_match_found = 1;
best_fat_arch = i;
continue;
}
if(fat_archs64 != NULL){
if(fat_cpusubtype >
fat_archs64[best_fat_arch].cpusubtype)
best_fat_arch = i;
}
else{
if(fat_cpusubtype >
fat_archs[best_fat_arch].cpusubtype)
best_fat_arch = i;
}
}
if(fat_match_found)
return(best_fat_arch);
if(cputype == CPU_TYPE_ARM64){
int fat_match_found = 0;
uint32_t best_fat_arch = 0;
for(i = 0; i < nfat_archs; i++){
if(fat_archs64 != NULL){
fat_cputype = fat_archs64[i].cputype;
fat_cpusubtype = fat_archs64[i].cpusubtype;
}
else{
fat_cputype = fat_archs[i].cputype;
fat_cpusubtype = fat_archs[i].cpusubtype;
}
if(fat_cputype != CPU_TYPE_ARM)
continue;
if(!fat_match_found){
fat_match_found = 1;
best_fat_arch = i;
continue;
}
if(fat_archs64 != NULL){
if(fat_cpusubtype >
fat_archs64[best_fat_arch].cpusubtype)
best_fat_arch = i;
}
else{
if(fat_cpusubtype >
fat_archs[best_fat_arch].cpusubtype)
best_fat_arch = i;
}
}
if(fat_match_found)
return(best_fat_arch);
}
}
break;
default:
return(-1);
}
return(-1);
}
struct fat_arch *
NXFindBestFatArch(
cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch *fat_archs,
uint32_t nfat_archs)
{
int32_t i;
i = internal_NXFindBestFatArch(cputype, cpusubtype, fat_archs, NULL,
nfat_archs);
if(i == -1)
return(NULL);
return(fat_archs + i);
}
struct fat_arch_64 *
NXFindBestFatArch_64(
cpu_type_t cputype,
cpu_subtype_t cpusubtype,
struct fat_arch_64 *fat_archs64,
uint32_t nfat_archs)
{
int32_t i;
i = internal_NXFindBestFatArch(cputype, cpusubtype, NULL,
fat_archs64, nfat_archs);
if(i == -1)
return(NULL);
return(fat_archs64 + i);
}
cpu_subtype_t
NXCombineCpuSubtypes(
cpu_type_t cputype,
cpu_subtype_t cpusubtype1,
cpu_subtype_t cpusubtype2)
{
if(cputype == CPU_TYPE_X86_64 &&
(cpusubtype1 == CPU_SUBTYPE_X86_64_H ||
cpusubtype2 == CPU_SUBTYPE_X86_64_H))
return((cpu_subtype_t)-1);
if(cputype == CPU_TYPE_I386)
return(CPU_SUBTYPE_I386_ALL);
if(cputype == CPU_TYPE_X86_64)
return(CPU_SUBTYPE_X86_64_ALL);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) ==
(cpusubtype2 & ~CPU_SUBTYPE_MASK))
return(cpusubtype1);
switch(cputype){
case CPU_TYPE_MC680x0:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
(cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
(cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
return((cpu_subtype_t)-1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
return((cpu_subtype_t)-1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY ||
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY)
return(CPU_SUBTYPE_MC68030_ONLY);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 ||
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040)
return(CPU_SUBTYPE_MC68040);
break;
case CPU_TYPE_POWERPC:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
return(cpusubtype2);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL)
return(cpusubtype1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 ||
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601)
return(CPU_SUBTYPE_POWERPC_601);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) >
(cpusubtype2 & ~CPU_SUBTYPE_MASK))
return(cpusubtype1);
else
return(cpusubtype2);
break;
case CPU_TYPE_MC88000:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
(cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110)
return((cpu_subtype_t)-1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 ||
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110)
return(CPU_SUBTYPE_MC88110);
break;
case CPU_TYPE_I860:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
(cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860)
return((cpu_subtype_t)-1);
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 ||
(cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860)
return(CPU_SUBTYPE_I860_860);
break;
case CPU_TYPE_HPPA:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
(cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL &&
(cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC)
return((cpu_subtype_t)-1);
return(CPU_SUBTYPE_HPPA_7100LC);
break;
case CPU_TYPE_SPARC:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL)
return((cpu_subtype_t)-1);
break;
case CPU_TYPE_ARM:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
return(cpusubtype2);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL)
return(cpusubtype1);
switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){
case CPU_SUBTYPE_ARM_V7:
switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
case CPU_SUBTYPE_ARM_XSCALE:
return((cpu_subtype_t)-1);
default:
return(CPU_SUBTYPE_ARM_V7);
}
case CPU_SUBTYPE_ARM_V6:
switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
case CPU_SUBTYPE_ARM_XSCALE:
return((cpu_subtype_t)-1);
default:
return(CPU_SUBTYPE_ARM_V6);
}
case CPU_SUBTYPE_ARM_XSCALE:
switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
case CPU_SUBTYPE_ARM_V7:
case CPU_SUBTYPE_ARM_V6:
case CPU_SUBTYPE_ARM_V5TEJ:
return((cpu_subtype_t)-1);
default:
return(CPU_SUBTYPE_ARM_XSCALE);
}
case CPU_SUBTYPE_ARM_V5TEJ:
switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){
case CPU_SUBTYPE_ARM_XSCALE:
return((cpu_subtype_t)-1);
case CPU_SUBTYPE_ARM_V7:
return(CPU_SUBTYPE_ARM_V7);
case CPU_SUBTYPE_ARM_V6:
return(CPU_SUBTYPE_ARM_V6);
default:
return(CPU_SUBTYPE_ARM_V5TEJ);
}
case CPU_SUBTYPE_ARM_V4T:
return((cpusubtype2 & ~CPU_SUBTYPE_MASK));
default:
return((cpu_subtype_t)-1);
}
case CPU_TYPE_ARM64:
if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_ARM64_ALL)
return((cpu_subtype_t)-1);
if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_ARM64_ALL)
return((cpu_subtype_t)-1);
break;
default:
return((cpu_subtype_t)-1);
}
return((cpu_subtype_t)-1);
}
#endif