1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Copyright (c) 1993 NeXT Computer, Inc. 25 * 26 * Architecture computing functions. 27 * 28 * HISTORY 29 * 30 * 11 April 1997 31 * Update m98k to ppc and removed the never supported architectures (mips, 32 * and vax). Apple Computer, Inc. 33 * 34 * 4 February 1993 Lennart Lovstrand <lennart@next.com> 35 * Redesigned to use NXArchInfo based names and signatures. 36 * 37 * Originally written at NeXT, Inc. 38 * 39 */ 40#ifndef RLD 41#include <stdint.h> 42#include <stdio.h> 43#include <stdlib.h> 44#include <string.h> 45#include <limits.h> 46 47#include "mach/machine.h" 48#include "mach/mach.h" 49#include "stuff/openstep_mach.h" 50#include <mach-o/fat.h> 51#include <mach-o/arch.h> 52 53/* The array of all currently know architecture flags (terminated with an entry 54 * with all zeros). Pointer to this returned with NXGetAllArchInfos(). 55 */ 56static const NXArchInfo ArchInfoTable[] = { 57 /* architecture families */ 58 {"hppa", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_ALL, NX_BigEndian, 59 "HP-PA"}, 60 {"i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL, NX_LittleEndian, 61 "Intel 80x86"}, 62 { "x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, NX_LittleEndian, 63 "Intel x86-64" }, 64 {"i860", CPU_TYPE_I860, CPU_SUBTYPE_I860_ALL, NX_BigEndian, 65 "Intel 860"}, 66 {"m68k", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL, NX_BigEndian, 67 "Motorola 68K"}, 68 {"m88k", CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL, NX_BigEndian, 69 "Motorola 88K"}, 70 {"ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian, 71 "PowerPC"}, 72 {"ppc64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_ALL, NX_BigEndian, 73 "PowerPC 64-bit"}, 74 {"sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL, NX_BigEndian, 75 "SPARC"}, 76 {"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL, NX_LittleEndian, 77 "ARM"}, 78 {"any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE, NX_UnknownByteOrder, 79 "Architecture Independent"}, 80 {"veo", CPU_TYPE_VEO, CPU_SUBTYPE_VEO_ALL, NX_BigEndian, 81 "veo"}, 82 /* specific architecture implementations */ 83 {"hppa7100LC", CPU_TYPE_HPPA, CPU_SUBTYPE_HPPA_7100LC, NX_BigEndian, 84 "HP-PA 7100LC"}, 85 {"m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY, NX_BigEndian, 86 "Motorola 68030"}, 87 {"m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040, NX_BigEndian, 88 "Motorola 68040"}, 89 {"i486", CPU_TYPE_I386, CPU_SUBTYPE_486, NX_LittleEndian, 90 "Intel 80486"}, 91 {"i486SX", CPU_TYPE_I386, CPU_SUBTYPE_486SX, NX_LittleEndian, 92 "Intel 80486SX"}, 93 {"pentium",CPU_TYPE_I386, CPU_SUBTYPE_PENT, NX_LittleEndian, 94 "Intel Pentium"}, /* same as 586 */ 95 {"i586", CPU_TYPE_I386, CPU_SUBTYPE_586, NX_LittleEndian, 96 "Intel 80586"}, 97 {"pentpro", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian, 98 "Intel Pentium Pro"}, /* same as 686 */ 99 {"i686", CPU_TYPE_I386, CPU_SUBTYPE_PENTPRO, NX_LittleEndian, 100 "Intel Pentium Pro"}, 101 {"pentIIm3", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M3, NX_LittleEndian, 102 "Intel Pentium II Model 3" }, 103 {"pentIIm5", CPU_TYPE_I386, CPU_SUBTYPE_PENTII_M5, NX_LittleEndian, 104 "Intel Pentium II Model 5" }, 105 {"pentium4", CPU_TYPE_I386, CPU_SUBTYPE_PENTIUM_4, NX_LittleEndian, 106 "Intel Pentium 4" }, 107 {"ppc601", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_601, NX_BigEndian, 108 "PowerPC 601" }, 109 {"ppc603", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603, NX_BigEndian, 110 "PowerPC 603" }, 111 {"ppc603e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_603e, NX_BigEndian, 112 "PowerPC 603e" }, 113 {"ppc603ev",CPU_TYPE_POWERPC,CPU_SUBTYPE_POWERPC_603ev,NX_BigEndian, 114 "PowerPC 603ev" }, 115 {"ppc604", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604, NX_BigEndian, 116 "PowerPC 604" }, 117 {"ppc604e",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_604e, NX_BigEndian, 118 "PowerPC 604e" }, 119 {"ppc750", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_750, NX_BigEndian, 120 "PowerPC 750" }, 121 {"ppc7400",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7400, NX_BigEndian, 122 "PowerPC 7400" }, 123 {"ppc7450",CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_7450, NX_BigEndian, 124 "PowerPC 7450" }, 125 {"ppc970", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_970, NX_BigEndian, 126 "PowerPC 970" }, 127 {"ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970, NX_BigEndian, 128 "PowerPC 970 64-bit"}, 129 {"armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T, NX_LittleEndian, 130 "arm v4t"}, 131 {"armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ, NX_LittleEndian, 132 "arm v5"}, 133 {"xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE, NX_LittleEndian, 134 "arm xscale"}, 135 {"armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, NX_LittleEndian, 136 "arm v6"}, 137 {"armv6m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6M, NX_LittleEndian, 138 "arm v6m"}, 139 {"armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7, NX_LittleEndian, 140 "arm v7"}, 141 {"armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F, NX_LittleEndian, 142 "arm v7f"}, 143 {"armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S, NX_LittleEndian, 144 "arm v7s"}, 145 {"armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K, NX_LittleEndian, 146 "arm v7k"}, 147 {"armv7m", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7M, NX_LittleEndian, 148 "arm v7m"}, 149 {"armv7em",CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7EM, NX_LittleEndian, 150 "arm v7em"}, 151 {"little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian, 152 "Little Endian"}, 153 {"big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN, NX_BigEndian, 154 "Big Endian"}, 155 {"veo1",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_1, NX_BigEndian, 156 "veo 1" }, 157 {"veo2",CPU_TYPE_VEO, CPU_SUBTYPE_VEO_2, NX_BigEndian, 158 "veo 2" }, 159 {NULL, 0, 0, 0, 160 NULL} 161}; 162 163/* 164 * NXGetAllArchInfos() returns a pointer to an array of all currently know 165 * architecture flags (terminated with an entry with all zeros). 166 */ 167const 168NXArchInfo * 169NXGetAllArchInfos(void) 170{ 171 return(ArchInfoTable); 172} 173 174/* 175 * NXGetLocalArchInfo() returns the NXArchInfo matching the cputype and 176 * cpusubtype of the local host. NULL is returned if there is no matching 177 * entry in the ArchInfoTable. 178 */ 179const 180NXArchInfo * 181NXGetLocalArchInfo(void) 182{ 183 struct host_basic_info hbi; 184 kern_return_t ret; 185 unsigned int count; 186 mach_port_t my_mach_host_self; 187 188 count = HOST_BASIC_INFO_COUNT; 189 my_mach_host_self = mach_host_self(); 190 ret = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)&hbi, 191 &count); 192 mach_port_deallocate(mach_task_self(), my_mach_host_self); 193 if(ret != KERN_SUCCESS) 194 return(NULL); 195 196 /* 197 * There is a "bug" in the kernel for compatiblity that on 198 * an 030 machine host_info() returns cpusubtype 199 * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY. 200 */ 201 if(hbi.cpu_type == CPU_TYPE_MC680x0 && 202 hbi.cpu_subtype == CPU_SUBTYPE_MC680x0_ALL) 203 hbi.cpu_subtype = CPU_SUBTYPE_MC68030_ONLY; 204 205 return(NXGetArchInfoFromCpuType(hbi.cpu_type, hbi.cpu_subtype)); 206} 207 208/* 209 * NXGetArchInfoFromName() is passed an architecture name (like "m68k") 210 * and returns the matching NXArchInfo struct, or NULL if none is found. 211 */ 212const 213NXArchInfo * 214NXGetArchInfoFromName( 215const char *name) 216{ 217 const NXArchInfo *ai; 218 219 for(ai = ArchInfoTable; ai->name != NULL; ai++) 220 if(strcmp(ai->name, name) == 0) 221 return(ai); 222 223 return(NULL); 224} 225 226/* 227 * NXGetArchInfoFromName() is passed a cputype and cpusubtype and returns 228 * the matching NXArchInfo struct, or NULL if none is found. If the 229 * cpusubtype is given as CPU_SUBTYPE_MULTIPLE, the first entry that 230 * matches the given cputype is returned. This is the NXArchInfo struct 231 * describing the CPU "family". 232 */ 233const 234NXArchInfo * 235NXGetArchInfoFromCpuType( 236cpu_type_t cputype, 237cpu_subtype_t cpusubtype) 238{ 239 const NXArchInfo *ai; 240 NXArchInfo *q; 241 242 for(ai = ArchInfoTable; ai->name != NULL; ai++) 243 if(ai->cputype == cputype && 244 (cpusubtype == CPU_SUBTYPE_MULTIPLE || 245 ((ai->cpusubtype & ~CPU_SUBTYPE_MASK) == 246 (cpusubtype & ~CPU_SUBTYPE_MASK)))) 247 return(ai); 248 249 if(cputype == CPU_TYPE_I386){ 250 q = malloc(sizeof(NXArchInfo)); 251 for(ai = ArchInfoTable; ai->name != NULL; ai++){ 252 if(ai->cputype == cputype){ 253 *q = *ai; 254 break; 255 } 256 } 257 q->cpusubtype = cpusubtype; 258 q->description = malloc(sizeof("Intel family model ") + 2 + 8); 259 if(q->description == NULL) 260 return(NULL); 261 sprintf((char *)q->description, "Intel family %u model %u", 262 CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK), 263 CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK)); 264 return((const NXArchInfo *)q); 265 } 266 else if(cputype == CPU_TYPE_POWERPC){ 267 q = malloc(sizeof(NXArchInfo)); 268 for(ai = ArchInfoTable; ai->name != NULL; ai++){ 269 if(ai->cputype == cputype){ 270 *q = *ai; 271 break; 272 } 273 } 274 q->cpusubtype = cpusubtype; 275 q->description = malloc(sizeof("PowerPC cpusubtype ") + 10); 276 if(q->description == NULL) 277 return(NULL); 278 sprintf((char *)q->description, "PowerPC cpusubtype %u", cpusubtype); 279 return((const NXArchInfo *)q); 280 } 281 282 return(NULL); 283} 284 285/* 286 * NXFindBestFatArch() is passed a cputype and cpusubtype and a set of 287 * fat_arch structs and selects the best one that matches (if any) and returns 288 * a pointer to that fat_arch struct (or NULL). The fat_arch structs must be 289 * in the host byte order and correct such that the fat_archs really points to 290 * enough memory for nfat_arch structs. It is possible that this routine could 291 * fail if new cputypes or cpusubtypes are added and an old version of this 292 * routine is used. But if there is an exact match between the cputype and 293 * cpusubtype and one of the fat_arch structs this routine will always succeed. 294 */ 295struct fat_arch * 296NXFindBestFatArch( 297cpu_type_t cputype, 298cpu_subtype_t cpusubtype, 299struct fat_arch *fat_archs, 300uint32_t nfat_archs) 301{ 302 uint32_t i; 303 int32_t lowest_family, lowest_model, lowest_index; 304 305 /* 306 * Look for the first exact match. 307 */ 308 for(i = 0; i < nfat_archs; i++){ 309 if(fat_archs[i].cputype == cputype && 310 (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 311 (cpusubtype & ~CPU_SUBTYPE_MASK)) 312 return(fat_archs + i); 313 } 314 315 /* 316 * An exact match was not found so find the next best match which is 317 * cputype dependent. 318 */ 319 switch(cputype){ 320 case CPU_TYPE_I386: 321 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 322 default: 323 /* 324 * Intel cpusubtypes after the pentium (same as 586) are handled 325 * such that they require an exact match or they can use the 326 * pentium. If that is not found call into the loop for the 327 * earilier subtypes. 328 */ 329 for(i = 0; i < nfat_archs; i++){ 330 if(fat_archs[i].cputype != cputype) 331 continue; 332 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 333 CPU_SUBTYPE_PENT) 334 return(fat_archs + i); 335 } 336 case CPU_SUBTYPE_PENT: 337 case CPU_SUBTYPE_486SX: 338 /* 339 * Since an exact match as not found look for the i486 else 340 * break into the loop to look for the i386_ALL. 341 */ 342 for(i = 0; i < nfat_archs; i++){ 343 if(fat_archs[i].cputype != cputype) 344 continue; 345 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 346 CPU_SUBTYPE_486) 347 return(fat_archs + i); 348 } 349 break; 350 case CPU_SUBTYPE_I386_ALL: 351 /* case CPU_SUBTYPE_I386: same as above */ 352 case CPU_SUBTYPE_486: 353 break; 354 } 355 for(i = 0; i < nfat_archs; i++){ 356 if(fat_archs[i].cputype != cputype) 357 continue; 358 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 359 CPU_SUBTYPE_I386_ALL) 360 return(fat_archs + i); 361 } 362 363 /* 364 * A match failed, promote as little as possible. 365 */ 366 for(i = 0; i < nfat_archs; i++){ 367 if(fat_archs[i].cputype != cputype) 368 continue; 369 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 370 CPU_SUBTYPE_486) 371 return(fat_archs + i); 372 } 373 for(i = 0; i < nfat_archs; i++){ 374 if(fat_archs[i].cputype != cputype) 375 continue; 376 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 377 CPU_SUBTYPE_486SX) 378 return(fat_archs + i); 379 } 380 for(i = 0; i < nfat_archs; i++){ 381 if(fat_archs[i].cputype != cputype) 382 continue; 383 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 384 CPU_SUBTYPE_586) 385 return(fat_archs + i); 386 } 387 /* 388 * Now look for the lowest family and in that the lowest model. 389 */ 390 lowest_family = CPU_SUBTYPE_INTEL_FAMILY_MAX + 1; 391 for(i = 0; i < nfat_archs; i++){ 392 if(fat_archs[i].cputype != cputype) 393 continue; 394 if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype & 395 ~CPU_SUBTYPE_MASK) < lowest_family) 396 lowest_family = CPU_SUBTYPE_INTEL_FAMILY( 397 fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK); 398 } 399 /* if no intel cputypes found return NULL */ 400 if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1) 401 return(NULL); 402 lowest_model = INT_MAX; 403 lowest_index = -1; 404 for(i = 0; i < nfat_archs; i++){ 405 if(fat_archs[i].cputype != cputype) 406 continue; 407 if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype & 408 ~CPU_SUBTYPE_MASK) == lowest_family){ 409 if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype & 410 ~CPU_SUBTYPE_MASK) < lowest_model){ 411 lowest_model = CPU_SUBTYPE_INTEL_MODEL( 412 fat_archs[i].cpusubtype & 413 ~CPU_SUBTYPE_MASK); 414 lowest_index = i; 415 } 416 } 417 } 418 return(fat_archs + lowest_index); 419 case CPU_TYPE_X86_64: 420 for(i = 0; i < nfat_archs; i++){ 421 if(fat_archs[i].cputype != cputype) 422 continue; 423 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 424 CPU_SUBTYPE_X86_64_ALL) 425 return(fat_archs + i); 426 } 427 break; 428 case CPU_TYPE_MC680x0: 429 for(i = 0; i < nfat_archs; i++){ 430 if(fat_archs[i].cputype != cputype) 431 continue; 432 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 433 CPU_SUBTYPE_MC680x0_ALL) 434 return(fat_archs + i); 435 } 436 /* 437 * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and 438 * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY. 439 */ 440 if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){ 441 for(i = 0; i < nfat_archs; i++){ 442 if(fat_archs[i].cputype != cputype) 443 continue; 444 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 445 CPU_SUBTYPE_MC68040) 446 return(fat_archs + i); 447 } 448 for(i = 0; i < nfat_archs; i++){ 449 if(fat_archs[i].cputype != cputype) 450 continue; 451 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 452 CPU_SUBTYPE_MC68030_ONLY) 453 return(fat_archs + i); 454 } 455 } 456 break; 457 case CPU_TYPE_POWERPC: 458 /* 459 * An exact match as not found. So for all the PowerPC subtypes 460 * pick the subtype from the following order starting from a subtype 461 * that will work (contains 64-bit instructions or altivec if 462 * needed): 463 * 970, 7450, 7400, 750, 604e, 604, 603ev, 603e, 603, ALL 464 * Note the 601 is NOT in the list above. It is only picked via 465 * an exact match. For an unknown subtype pick only the ALL type if 466 * it exists. 467 */ 468 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 469 case CPU_SUBTYPE_POWERPC_ALL: 470 /* 471 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development 472 * environment tools when building a generic ALL type binary. 473 * In the case of a non-exact match we pick the most current 474 * processor. 475 */ 476 case CPU_SUBTYPE_POWERPC_970: 477 for(i = 0; i < nfat_archs; i++){ 478 if(fat_archs[i].cputype != cputype) 479 continue; 480 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 481 CPU_SUBTYPE_POWERPC_970) 482 return(fat_archs + i); 483 } 484 case CPU_SUBTYPE_POWERPC_7450: 485 case CPU_SUBTYPE_POWERPC_7400: 486 for(i = 0; i < nfat_archs; i++){ 487 if(fat_archs[i].cputype != cputype) 488 continue; 489 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 490 CPU_SUBTYPE_POWERPC_7450) 491 return(fat_archs + i); 492 } 493 for(i = 0; i < nfat_archs; i++){ 494 if(fat_archs[i].cputype != cputype) 495 continue; 496 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 497 CPU_SUBTYPE_POWERPC_7400) 498 return(fat_archs + i); 499 } 500 case CPU_SUBTYPE_POWERPC_750: 501 case CPU_SUBTYPE_POWERPC_604e: 502 case CPU_SUBTYPE_POWERPC_604: 503 case CPU_SUBTYPE_POWERPC_603ev: 504 case CPU_SUBTYPE_POWERPC_603e: 505 case CPU_SUBTYPE_POWERPC_603: 506 for(i = 0; i < nfat_archs; i++){ 507 if(fat_archs[i].cputype != cputype) 508 continue; 509 if((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) == 510 CPU_SUBTYPE_POWERPC_750) 511 return(fat_archs + i); 512 } 513 for(i = 0; i < nfat_archs; i++){ 514 if(fat_archs[i].cputype != cputype) 515 continue; 516 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 517 CPU_SUBTYPE_POWERPC_604e) 518 return(fat_archs + i); 519 } 520 for(i = 0; i < nfat_archs; i++){ 521 if(fat_archs[i].cputype != cputype) 522 continue; 523 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 524 CPU_SUBTYPE_POWERPC_604) 525 return(fat_archs + i); 526 } 527 for(i = 0; i < nfat_archs; i++){ 528 if((fat_archs[i].cputype & ~CPU_SUBTYPE_MASK) != cputype) 529 continue; 530 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 531 CPU_SUBTYPE_POWERPC_603ev) 532 return(fat_archs + i); 533 } 534 for(i = 0; i < nfat_archs; i++){ 535 if(fat_archs[i].cputype != cputype) 536 continue; 537 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 538 CPU_SUBTYPE_POWERPC_603e) 539 return(fat_archs + i); 540 } 541 for(i = 0; i < nfat_archs; i++){ 542 if(fat_archs[i].cputype != cputype) 543 continue; 544 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 545 CPU_SUBTYPE_POWERPC_603) 546 return(fat_archs + i); 547 } 548 default: 549 for(i = 0; i < nfat_archs; i++){ 550 if(fat_archs[i].cputype != cputype) 551 continue; 552 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 553 CPU_SUBTYPE_POWERPC_ALL) 554 return(fat_archs + i); 555 } 556 } 557 break; 558 case CPU_TYPE_POWERPC64: 559 /* 560 * An exact match as not found. So for all the PowerPC64 subtypes 561 * pick the subtype from the following order starting from a subtype 562 * that will work (contains 64-bit instructions or altivec if 563 * needed): 564 * 970 (currently only the one 64-bit subtype) 565 * For an unknown subtype pick only the ALL type if it exists. 566 */ 567 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 568 case CPU_SUBTYPE_POWERPC_ALL: 569 /* 570 * The CPU_SUBTYPE_POWERPC_ALL is only used by the development 571 * environment tools when building a generic ALL type binary. 572 * In the case of a non-exact match we pick the most current 573 * processor. 574 */ 575 case CPU_SUBTYPE_POWERPC_970: 576 for(i = 0; i < nfat_archs; i++){ 577 if(fat_archs[i].cputype != cputype) 578 continue; 579 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 580 CPU_SUBTYPE_POWERPC_970) 581 return(fat_archs + i); 582 } 583 default: 584 for(i = 0; i < nfat_archs; i++){ 585 if(fat_archs[i].cputype != cputype) 586 continue; 587 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 588 CPU_SUBTYPE_POWERPC_ALL) 589 return(fat_archs + i); 590 } 591 } 592 break; 593 case CPU_TYPE_MC88000: 594 for(i = 0; i < nfat_archs; i++){ 595 if(fat_archs[i].cputype != cputype) 596 continue; 597 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 598 CPU_SUBTYPE_MC88000_ALL) 599 return(fat_archs + i); 600 } 601 break; 602 case CPU_TYPE_I860: 603 for(i = 0; i < nfat_archs; i++){ 604 if(fat_archs[i].cputype != cputype) 605 continue; 606 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 607 CPU_SUBTYPE_I860_ALL) 608 return(fat_archs + i); 609 } 610 break; 611 case CPU_TYPE_HPPA: 612 for(i = 0; i < nfat_archs; i++){ 613 if(fat_archs[i].cputype != cputype) 614 continue; 615 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 616 CPU_SUBTYPE_HPPA_ALL) 617 return(fat_archs + i); 618 } 619 break; 620 case CPU_TYPE_SPARC: 621 for(i = 0; i < nfat_archs; i++){ 622 if(fat_archs[i].cputype != cputype) 623 continue; 624 if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 625 CPU_SUBTYPE_SPARC_ALL) 626 return(fat_archs + i); 627 } 628 break; 629 case CPU_TYPE_ARM: 630 { 631 /* 632 * ARM is straightforward, since each architecture is backward 633 * compatible with previous architectures. So, we just take the 634 * highest that is less than our target. 635 */ 636 int fat_match_found = 0; 637 uint32_t best_fat_arch = 0; 638 for(i = 0; i < nfat_archs; i++){ 639 if(fat_archs[i].cputype != cputype) 640 continue; 641 if(fat_archs[i].cpusubtype > cpusubtype) 642 continue; 643 if(!fat_match_found){ 644 fat_match_found = 1; 645 best_fat_arch = i; 646 continue; 647 } 648 if(fat_archs[i].cpusubtype > 649 fat_archs[best_fat_arch].cpusubtype) 650 best_fat_arch = i; 651 } 652 if(fat_match_found) 653 return fat_archs + best_fat_arch; 654 } 655 break; 656 default: 657 return(NULL); 658 } 659 return(NULL); 660} 661 662/* 663 * NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two 664 * different cpusubtypes for the specified cputype. If the two cpusubtypes 665 * can't be combined (the specific subtypes are mutually exclusive) -1 is 666 * returned indicating it is an error to combine them. This can also fail and 667 * return -1 if new cputypes or cpusubtypes are added and an old version of 668 * this routine is used. But if the cpusubtypes are the same they can always 669 * be combined and this routine will return the cpusubtype pass in. 670 */ 671cpu_subtype_t 672NXCombineCpuSubtypes( 673cpu_type_t cputype, 674cpu_subtype_t cpusubtype1, 675cpu_subtype_t cpusubtype2) 676{ 677 /* 678 * We now combine any i386 or x86-64 subtype to the ALL subtype. 679 */ 680 if(cputype == CPU_TYPE_I386) 681 return(CPU_SUBTYPE_I386_ALL); 682 683 if(cputype == CPU_TYPE_X86_64) 684 return(CPU_SUBTYPE_X86_64_ALL); 685 686 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == 687 (cpusubtype2 & ~CPU_SUBTYPE_MASK)) 688 return(cpusubtype1); 689 690 switch(cputype){ 691 case CPU_TYPE_MC680x0: 692 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL && 693 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY && 694 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040) 695 return((cpu_subtype_t)-1); 696 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL && 697 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY && 698 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040) 699 return((cpu_subtype_t)-1); 700 701 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY && 702 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040) 703 return((cpu_subtype_t)-1); 704 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 && 705 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY) 706 return((cpu_subtype_t)-1); 707 708 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY || 709 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY) 710 return(CPU_SUBTYPE_MC68030_ONLY); 711 712 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 || 713 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040) 714 return(CPU_SUBTYPE_MC68040); 715 break; /* logically can't get here */ 716 717 case CPU_TYPE_POWERPC: 718 /* 719 * Combining with the ALL type becomes the other type. Combining 720 * anything with the 601 becomes 601. All other non exact matches 721 * combine to the higher value subtype. 722 */ 723 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL) 724 return(cpusubtype2); 725 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL) 726 return(cpusubtype1); 727 728 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 || 729 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601) 730 return(CPU_SUBTYPE_POWERPC_601); 731 732 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) > 733 (cpusubtype2 & ~CPU_SUBTYPE_MASK)) 734 return(cpusubtype1); 735 else 736 return(cpusubtype2); 737 break; /* logically can't get here */ 738 739 case CPU_TYPE_MC88000: 740 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL && 741 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110) 742 return((cpu_subtype_t)-1); 743 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL && 744 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110) 745 return((cpu_subtype_t)-1); 746 747 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 || 748 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110) 749 return(CPU_SUBTYPE_MC88110); 750 751 break; /* logically can't get here */ 752 753 case CPU_TYPE_I860: 754 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL && 755 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860) 756 return((cpu_subtype_t)-1); 757 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL && 758 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860) 759 return((cpu_subtype_t)-1); 760 761 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 || 762 (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860) 763 return(CPU_SUBTYPE_I860_860); 764 break; /* logically can't get here */ 765 766 case CPU_TYPE_HPPA: 767 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL && 768 (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC) 769 return((cpu_subtype_t)-1); 770 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL && 771 (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC) 772 return((cpu_subtype_t)-1); 773 774 return(CPU_SUBTYPE_HPPA_7100LC); 775 break; /* logically can't get here */ 776 777 case CPU_TYPE_SPARC: 778 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL) 779 return((cpu_subtype_t)-1); 780 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL) 781 return((cpu_subtype_t)-1); 782 break; /* logically can't get here */ 783 784 case CPU_TYPE_ARM: 785 /* 786 * Combinability matrix for ARM: 787 * V4T V5 XSCALE V6 V7 ALL 788 * ~~~ ~~ ~~~~~~ ~~ ~~ ~~~ 789 * V4T V4T V5 XSCALE V6 V7 ALL 790 * V5 V5 V5 -- V6 V7 ALL 791 * XSCALE XSCALE -- XSCALE -- -- ALL 792 * V6 V6 V6 -- V6 V7 ALL 793 * V7 V7 V7 -- V7 V7 ALL 794 * ALL ALL ALL ALL ALL ALL ALL 795 */ 796 if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL) 797 return(cpusubtype2); 798 if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL) 799 return(cpusubtype1); 800 switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){ 801 case CPU_SUBTYPE_ARM_V7: 802 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ 803 case CPU_SUBTYPE_ARM_XSCALE: 804 return((cpu_subtype_t)-1); 805 default: 806 return(CPU_SUBTYPE_ARM_V7); 807 } 808 case CPU_SUBTYPE_ARM_V6: 809 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ 810 case CPU_SUBTYPE_ARM_XSCALE: 811 return((cpu_subtype_t)-1); 812 default: 813 return(CPU_SUBTYPE_ARM_V6); 814 } 815 case CPU_SUBTYPE_ARM_XSCALE: 816 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ 817 case CPU_SUBTYPE_ARM_V7: 818 case CPU_SUBTYPE_ARM_V6: 819 case CPU_SUBTYPE_ARM_V5TEJ: 820 return((cpu_subtype_t)-1); 821 default: 822 return(CPU_SUBTYPE_ARM_XSCALE); 823 } 824 case CPU_SUBTYPE_ARM_V5TEJ: 825 switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ 826 case CPU_SUBTYPE_ARM_XSCALE: 827 return((cpu_subtype_t)-1); 828 case CPU_SUBTYPE_ARM_V7: 829 return(CPU_SUBTYPE_ARM_V7); 830 case CPU_SUBTYPE_ARM_V6: 831 return(CPU_SUBTYPE_ARM_V6); 832 default: 833 return(CPU_SUBTYPE_ARM_V5TEJ); 834 } 835 case CPU_SUBTYPE_ARM_V4T: 836 return((cpusubtype2 & ~CPU_SUBTYPE_MASK)); 837 default: 838 return((cpu_subtype_t)-1); 839 } 840 841 default: 842 return((cpu_subtype_t)-1); 843 } 844 return((cpu_subtype_t)-1); /* logically can't get here */ 845} 846#endif /* !defined(RLD) */ 847