15ffd83dbSDimitry Andric //===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #include "llvm/BinaryFormat/MachO.h" 105ffd83dbSDimitry Andric #include "llvm/ADT/Triple.h" 115ffd83dbSDimitry Andric #include "llvm/Support/ARMTargetParser.h" 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric using namespace llvm; 145ffd83dbSDimitry Andric 155ffd83dbSDimitry Andric static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) { 165ffd83dbSDimitry Andric assert(T.isX86()); 175ffd83dbSDimitry Andric if (T.isArch32Bit()) 185ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_I386_ALL; 195ffd83dbSDimitry Andric 205ffd83dbSDimitry Andric assert(T.isArch64Bit()); 215ffd83dbSDimitry Andric if (T.getArchName() == "x86_64h") 225ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_X86_64_H; 235ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_X86_64_ALL; 245ffd83dbSDimitry Andric } 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric static MachO::CPUSubTypeARM getARMSubType(const Triple &T) { 275ffd83dbSDimitry Andric assert(T.isARM() || T.isThumb()); 285ffd83dbSDimitry Andric StringRef Arch = T.getArchName(); 295ffd83dbSDimitry Andric ARM::ArchKind AK = ARM::parseArch(Arch); 305ffd83dbSDimitry Andric switch (AK) { 315ffd83dbSDimitry Andric default: 325ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7; 335ffd83dbSDimitry Andric case ARM::ArchKind::ARMV4T: 345ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V4T; 355ffd83dbSDimitry Andric case ARM::ArchKind::ARMV5T: 365ffd83dbSDimitry Andric case ARM::ArchKind::ARMV5TE: 375ffd83dbSDimitry Andric case ARM::ArchKind::ARMV5TEJ: 385ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V5; 395ffd83dbSDimitry Andric case ARM::ArchKind::ARMV6: 405ffd83dbSDimitry Andric case ARM::ArchKind::ARMV6K: 415ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V6; 425ffd83dbSDimitry Andric case ARM::ArchKind::ARMV7A: 435ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7; 445ffd83dbSDimitry Andric case ARM::ArchKind::ARMV7S: 455ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7S; 465ffd83dbSDimitry Andric case ARM::ArchKind::ARMV7K: 475ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7K; 485ffd83dbSDimitry Andric case ARM::ArchKind::ARMV6M: 495ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V6M; 505ffd83dbSDimitry Andric case ARM::ArchKind::ARMV7M: 515ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7M; 525ffd83dbSDimitry Andric case ARM::ArchKind::ARMV7EM: 535ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM_V7EM; 545ffd83dbSDimitry Andric } 555ffd83dbSDimitry Andric } 565ffd83dbSDimitry Andric 575ffd83dbSDimitry Andric static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) { 58*e8d8bef9SDimitry Andric assert(T.isAArch64()); 595ffd83dbSDimitry Andric if (T.isArch32Bit()) 605ffd83dbSDimitry Andric return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8; 61*e8d8bef9SDimitry Andric if (T.isArm64e()) 625ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM64E; 635ffd83dbSDimitry Andric 645ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_ARM64_ALL; 655ffd83dbSDimitry Andric } 665ffd83dbSDimitry Andric 675ffd83dbSDimitry Andric static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) { 685ffd83dbSDimitry Andric return MachO::CPU_SUBTYPE_POWERPC_ALL; 695ffd83dbSDimitry Andric } 705ffd83dbSDimitry Andric 715ffd83dbSDimitry Andric static Error unsupported(const char *Str, const Triple &T) { 725ffd83dbSDimitry Andric return createStringError(std::errc::invalid_argument, 735ffd83dbSDimitry Andric "Unsupported triple for mach-o cpu %s: %s", Str, 745ffd83dbSDimitry Andric T.str().c_str()); 755ffd83dbSDimitry Andric } 765ffd83dbSDimitry Andric 775ffd83dbSDimitry Andric Expected<uint32_t> MachO::getCPUType(const Triple &T) { 785ffd83dbSDimitry Andric if (!T.isOSBinFormatMachO()) 795ffd83dbSDimitry Andric return unsupported("type", T); 805ffd83dbSDimitry Andric if (T.isX86() && T.isArch32Bit()) 815ffd83dbSDimitry Andric return MachO::CPU_TYPE_X86; 825ffd83dbSDimitry Andric if (T.isX86() && T.isArch64Bit()) 835ffd83dbSDimitry Andric return MachO::CPU_TYPE_X86_64; 845ffd83dbSDimitry Andric if (T.isARM() || T.isThumb()) 855ffd83dbSDimitry Andric return MachO::CPU_TYPE_ARM; 865ffd83dbSDimitry Andric if (T.isAArch64()) 87*e8d8bef9SDimitry Andric return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64; 885ffd83dbSDimitry Andric if (T.getArch() == Triple::ppc) 895ffd83dbSDimitry Andric return MachO::CPU_TYPE_POWERPC; 905ffd83dbSDimitry Andric if (T.getArch() == Triple::ppc64) 915ffd83dbSDimitry Andric return MachO::CPU_TYPE_POWERPC64; 925ffd83dbSDimitry Andric return unsupported("type", T); 935ffd83dbSDimitry Andric } 945ffd83dbSDimitry Andric 955ffd83dbSDimitry Andric Expected<uint32_t> MachO::getCPUSubType(const Triple &T) { 965ffd83dbSDimitry Andric if (!T.isOSBinFormatMachO()) 975ffd83dbSDimitry Andric return unsupported("subtype", T); 985ffd83dbSDimitry Andric if (T.isX86()) 995ffd83dbSDimitry Andric return getX86SubType(T); 1005ffd83dbSDimitry Andric if (T.isARM() || T.isThumb()) 1015ffd83dbSDimitry Andric return getARMSubType(T); 1025ffd83dbSDimitry Andric if (T.isAArch64() || T.getArch() == Triple::aarch64_32) 1035ffd83dbSDimitry Andric return getARM64SubType(T); 1045ffd83dbSDimitry Andric if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64) 1055ffd83dbSDimitry Andric return getPowerPCSubType(T); 1065ffd83dbSDimitry Andric return unsupported("subtype", T); 1075ffd83dbSDimitry Andric } 108