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/TargetParser/ARMTargetParser.h" 11#include "llvm/TargetParser/Triple.h" 12 13using namespace llvm; 14 15static 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 26static 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 57static 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 67static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) { 68 return MachO::CPU_SUBTYPE_POWERPC_ALL; 69} 70 71static 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 77Expected<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 95Expected<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