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() || T.getArch() == Triple::aarch64_32); 59 if (T.isArch32Bit()) 60 return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8; 61 if (T.getArchName() == "arm64e") 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 Expected<uint32_t> MachO::getCPUType(const Triple &T) { 72 if (T.isX86() && T.isArch32Bit()) 73 return MachO::CPU_TYPE_X86; 74 if (T.isX86() && T.isArch64Bit()) 75 return MachO::CPU_TYPE_X86_64; 76 if (T.isARM() || T.isThumb()) 77 return MachO::CPU_TYPE_ARM; 78 if (T.isAArch64()) 79 return MachO::CPU_TYPE_ARM64; 80 if (T.getArch() == Triple::aarch64_32) 81 return MachO::CPU_TYPE_ARM64_32; 82 if (T.getArch() == Triple::ppc) 83 return MachO::CPU_TYPE_POWERPC; 84 if (T.getArch() == Triple::ppc64) 85 return MachO::CPU_TYPE_POWERPC64; 86 return createStringError(std::errc::invalid_argument, 87 "Unsupported triple for mach-o cpu type."); 88 } 89 90 Expected<uint32_t> MachO::getCPUSubType(const Triple &T) { 91 if (T.isX86()) 92 return getX86SubType(T); 93 if (T.isARM() || T.isThumb()) 94 return getARMSubType(T); 95 if (T.isAArch64() || T.getArch() == Triple::aarch64_32) 96 return getARM64SubType(T); 97 if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64) 98 return getPowerPCSubType(T); 99 return createStringError(std::errc::invalid_argument, 100 "Unsupported triple for mach-o cpu subtype."); 101 } 102