1 //===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/BinaryFormat/MachO.h" 10 #include "llvm/ADT/Triple.h" 11 #include "llvm/Support/ARMTargetParser.h" 12 13 using namespace llvm; 14 15 static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) { 16 assert(T.isX86()); 17 if (T.isArch32Bit()) 18 return MachO::CPU_SUBTYPE_I386_ALL; 19 20 assert(T.isArch64Bit()); 21 if (T.getArchName() == "x86_64h") 22 return MachO::CPU_SUBTYPE_X86_64_H; 23 return MachO::CPU_SUBTYPE_X86_64_ALL; 24 } 25 26 static MachO::CPUSubTypeARM getARMSubType(const Triple &T) { 27 assert(T.isARM() || T.isThumb()); 28 StringRef Arch = T.getArchName(); 29 ARM::ArchKind AK = ARM::parseArch(Arch); 30 switch (AK) { 31 default: 32 return MachO::CPU_SUBTYPE_ARM_V7; 33 case ARM::ArchKind::ARMV4T: 34 return MachO::CPU_SUBTYPE_ARM_V4T; 35 case ARM::ArchKind::ARMV5T: 36 case ARM::ArchKind::ARMV5TE: 37 case ARM::ArchKind::ARMV5TEJ: 38 return MachO::CPU_SUBTYPE_ARM_V5; 39 case ARM::ArchKind::ARMV6: 40 case ARM::ArchKind::ARMV6K: 41 return MachO::CPU_SUBTYPE_ARM_V6; 42 case ARM::ArchKind::ARMV7A: 43 return MachO::CPU_SUBTYPE_ARM_V7; 44 case ARM::ArchKind::ARMV7S: 45 return MachO::CPU_SUBTYPE_ARM_V7S; 46 case ARM::ArchKind::ARMV7K: 47 return MachO::CPU_SUBTYPE_ARM_V7K; 48 case ARM::ArchKind::ARMV6M: 49 return MachO::CPU_SUBTYPE_ARM_V6M; 50 case ARM::ArchKind::ARMV7M: 51 return MachO::CPU_SUBTYPE_ARM_V7M; 52 case ARM::ArchKind::ARMV7EM: 53 return MachO::CPU_SUBTYPE_ARM_V7EM; 54 } 55 } 56 57 static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) { 58 assert(T.isAArch64()); 59 if (T.isArch32Bit()) 60 return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8; 61 if (T.isArm64e()) 62 return MachO::CPU_SUBTYPE_ARM64E; 63 64 return MachO::CPU_SUBTYPE_ARM64_ALL; 65 } 66 67 static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) { 68 return MachO::CPU_SUBTYPE_POWERPC_ALL; 69 } 70 71 static Error unsupported(const char *Str, const Triple &T) { 72 return createStringError(std::errc::invalid_argument, 73 "Unsupported triple for mach-o cpu %s: %s", Str, 74 T.str().c_str()); 75 } 76 77 Expected<uint32_t> MachO::getCPUType(const Triple &T) { 78 if (!T.isOSBinFormatMachO()) 79 return unsupported("type", T); 80 if (T.isX86() && T.isArch32Bit()) 81 return MachO::CPU_TYPE_X86; 82 if (T.isX86() && T.isArch64Bit()) 83 return MachO::CPU_TYPE_X86_64; 84 if (T.isARM() || T.isThumb()) 85 return MachO::CPU_TYPE_ARM; 86 if (T.isAArch64()) 87 return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64; 88 if (T.getArch() == Triple::ppc) 89 return MachO::CPU_TYPE_POWERPC; 90 if (T.getArch() == Triple::ppc64) 91 return MachO::CPU_TYPE_POWERPC64; 92 return unsupported("type", T); 93 } 94 95 Expected<uint32_t> MachO::getCPUSubType(const Triple &T) { 96 if (!T.isOSBinFormatMachO()) 97 return unsupported("subtype", T); 98 if (T.isX86()) 99 return getX86SubType(T); 100 if (T.isARM() || T.isThumb()) 101 return getARMSubType(T); 102 if (T.isAArch64() || T.getArch() == Triple::aarch64_32) 103 return getARM64SubType(T); 104 if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64) 105 return getPowerPCSubType(T); 106 return unsupported("subtype", T); 107 } 108