@@ -100,6 +100,7 @@ typedef uint32_t cpu_subtype_t;
100100#define CPU_TYPE_MC98000 ((cpu_type_t ) 10 )
101101#define CPU_TYPE_HPPA ((cpu_type_t ) 11 )
102102#define CPU_TYPE_ARM ((cpu_type_t ) 12 )
103+ #define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
103104#define CPU_TYPE_MC88000 ((cpu_type_t ) 13 )
104105#define CPU_TYPE_SPARC ((cpu_type_t ) 14 )
105106#define CPU_TYPE_I860 ((cpu_type_t ) 15 )
@@ -189,6 +190,30 @@ typedef uint32_t cpu_subtype_t;
189190#define CPU_SUBTYPE_POWERPC_7450 ((cpu_subtype_t ) 11 )
190191#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t ) 100 )
191192
193+ /*
194+ * ARM subtypes
195+ */
196+ #define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t ) 0 )
197+ #define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t ) 5 )
198+ #define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t ) 6 )
199+ #define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t ) 7 )
200+ #define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t ) 8 )
201+ #define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t ) 9 )
202+ #define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t ) 10 ) /* Cortex A9 */
203+ #define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t ) 11 ) /* Swift */
204+ #define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t ) 12 ) /* Kirkwood40 */
205+ #define CPU_SUBTYPE_ARM_V6M ((cpu_subtype_t ) 14 ) /* Not meant to be run under xnu */
206+ #define CPU_SUBTYPE_ARM_V7M ((cpu_subtype_t ) 15 ) /* Not meant to be run under xnu */
207+ #define CPU_SUBTYPE_ARM_V7EM ((cpu_subtype_t ) 16 ) /* Not meant to be run under xnu */
208+
209+ #define CPU_SUBTYPE_ARM_V8 ((cpu_subtype_t ) 13 )
210+
211+ /*
212+ * ARM64 subtypes
213+ */
214+ #define CPU_SUBTYPE_ARM64_ALL ((cpu_subtype_t ) 0 )
215+ #define CPU_SUBTYPE_ARM64_V8 ((cpu_subtype_t ) 1 )
216+
192217#define FAT_MAGIC 0xcafebabe
193218#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
194219
@@ -862,6 +887,18 @@ struct dyld_info_command
862887 uint32_t export_size;
863888};
864889
890+ /*
891+ * The version_min_command contains the min OS version on which this
892+ * binary was built to run.
893+ */
894+ struct version_min_command {
895+ uint32_t cmd; /* LC_VERSION_MIN_MACOSX or
896+ LC_VERSION_MIN_IPHONEOS */
897+ uint32_t cmdsize; /* sizeof(struct min_version_command) */
898+ uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
899+ uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
900+ };
901+
865902// //////////////////////////////////////////////////////////////////////////////
866903
867904struct mach_32bit
@@ -963,6 +1000,11 @@ static void swap_relocation_info(bool p_to_network, relocation_info& x)
9631000 MCDeployByteSwapRecord (p_to_network, " ll" , &x, sizeof (relocation_info));
9641001}
9651002
1003+ static void swap_version_min_command (bool p_to_network, version_min_command& x)
1004+ {
1005+ MCDeployByteSwapRecord (p_to_network, " llll" , &x, sizeof (version_min_command));
1006+ }
1007+
9661008static void swap_load_command (bool p_to_network, uint32_t p_type, load_command* x)
9671009{
9681010 switch (p_type)
@@ -998,7 +1040,12 @@ static void swap_load_command(bool p_to_network, uint32_t p_type, load_command*
9981040 swap_load_command_hdr (p_to_network, *x);
9991041 break ;
10001042
1001- default :
1043+ case LC_VERSION_MIN_MACOSX:
1044+ case LC_VERSION_MIN_IPHONEOS:
1045+ swap_version_min_command (p_to_network, *(version_min_command *)x);
1046+ break ;
1047+
1048+ default :
10021049 swap_load_command_hdr (p_to_network, *x);
10031050 break ;
10041051 }
@@ -1088,6 +1135,55 @@ static void relocate_function_starts_command(linkedit_data_command *x, int32_t p
10881135
10891136// //////////////////////////////////////////////////////////////////////////////
10901137
1138+ static bool MCDeployToMacOSXFetchMinOSVersion (const MCDeployParameters& p_params, mach_header& p_header, uint32_t & r_version)
1139+ {
1140+ // First work out what DeployArchitecture to look for.
1141+ MCDeployArchitecture t_arch;
1142+ if (p_header . cputype == CPU_TYPE_X86)
1143+ t_arch = kMCDeployArchitecture_I386 ;
1144+ else if (p_header . cputype == CPU_TYPE_X86_64)
1145+ t_arch = kMCDeployArchitecture_X86_64 ;
1146+ else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V6)
1147+ t_arch = kMCDeployArchitecture_ARMV6 ;
1148+ else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V7)
1149+ t_arch = kMCDeployArchitecture_ARMV7 ;
1150+ else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V7S)
1151+ t_arch = kMCDeployArchitecture_ARMV7S ;
1152+ else if (p_header . cputype == CPU_TYPE_ARM64)
1153+ t_arch = kMCDeployArchitecture_ARM64 ;
1154+ else if (p_header . cputype == CPU_TYPE_POWERPC)
1155+ t_arch = kMCDeployArchitecture_PPC ;
1156+ else if (p_header . cputype == CPU_TYPE_POWERPC64)
1157+ t_arch = kMCDeployArchitecture_PPC64 ;
1158+
1159+ // Search for both the architecture in the mach header and for the 'unknown'
1160+ // architecture. If the real arch is found, then we use that version; otherwise
1161+ // if there is an unknown arch then we use that version. If neither are found we
1162+ // return false which means the caller can do nothing.
1163+ int t_unknown_index, t_found_index;
1164+ t_unknown_index = -1 ;
1165+ t_found_index = -1 ;
1166+ for (uindex_t i = 0 ; i < p_params . min_os_version_count; i++)
1167+ if (p_params . min_os_versions[i] . architecture == t_arch &&
1168+ t_found_index == -1 )
1169+ t_found_index = (signed )i;
1170+ else if (p_params . min_os_versions[i] . architecture == kMCDeployArchitecture_Unknown &&
1171+ t_unknown_index == -1 )
1172+ t_unknown_index = -1 ;
1173+
1174+ if (t_found_index == -1 && t_unknown_index == -1 )
1175+ return false ;
1176+
1177+ if (t_found_index == -1 )
1178+ {
1179+ r_version = p_params . min_os_versions[t_unknown_index] . version;
1180+ return true ;
1181+ }
1182+
1183+ r_version = p_params . min_os_versions[t_found_index] . version;
1184+ return true ;
1185+ }
1186+
10911187template <typename T> bool MCDeployToMacOSXMainBody (const MCDeployParameters& p_params, bool p_big_endian, MCDeployFileRef p_engine, uint32_t p_engine_offset, uint32_t t_engine_size, uint32_t & x_offset, MCDeployFileRef p_output, mach_header& t_header, load_command **t_commands, uint32_t t_command_count)
10921188{
10931189 bool t_success;
@@ -1240,7 +1336,7 @@ template<typename T> bool MCDeployToMacOSXMainBody(const MCDeployParameters& p_p
12401336 {
12411337 switch (t_commands[i] -> cmd)
12421338 {
1243- // Relocate the commands we know about that contain file offset
1339+ // Relocate the commands we know about that contain file offset
12441340 case LC_SEGMENT:
12451341 relocate_segment_command<mach_32bit>((segment_command *)t_commands[i], t_file_delta, t_address_delta);
12461342 break ;
@@ -1269,7 +1365,7 @@ template<typename T> bool MCDeployToMacOSXMainBody(const MCDeployParameters& p_p
12691365 relocate_function_starts_command ((linkedit_data_command *)t_commands[i], t_file_delta, t_address_delta);
12701366 break ;
12711367
1272- // These commands have no file offsets
1368+ // These commands have no file offsets
12731369 case LC_UUID:
12741370 case LC_THREAD:
12751371 case LC_UNIXTHREAD:
@@ -1278,14 +1374,25 @@ template<typename T> bool MCDeployToMacOSXMainBody(const MCDeployParameters& p_p
12781374 case LC_LOAD_DYLINKER:
12791375 case LC_ENCRYPTION_INFO:
12801376 case LC_ENCRYPTION_INFO_64:
1281- case LC_VERSION_MIN_MACOSX:
1282- case LC_VERSION_MIN_IPHONEOS:
12831377 case LC_SOURCE_VERSION:
12841378 case LC_MAIN:
12851379 break ;
12861380
1287- // Any others that are present are an error since we don't know
1288- // what to do with them.
1381+ // We rewrite the contents of these commands as appropriate to
1382+ // the 'min_os_versions' list in the params.
1383+ case LC_VERSION_MIN_MACOSX:
1384+ case LC_VERSION_MIN_IPHONEOS:
1385+ {
1386+ // Notice that we leave the SDK version alone - this is tied
1387+ // to linkage and so is probably unwise to adjust.
1388+ uint32_t t_version;
1389+ if (MCDeployToMacOSXFetchMinOSVersion (p_params, t_header, t_version))
1390+ ((version_min_command *)t_commands[i]) -> version = t_version;
1391+ }
1392+ break ;
1393+
1394+ // Any others that are present are an error since we don't know
1395+ // what to do with them.
12891396 default :
12901397 t_success = MCDeployThrow (kMCDeployErrorMacOSXUnknownLoadCommand );
12911398 break ;
0 commit comments