108 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/BinaryFormat/MachO.h"
 | |
| #include "llvm/ADT/Triple.h"
 | |
| #include "llvm/Support/ARMTargetParser.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) {
 | |
|   assert(T.isX86());
 | |
|   if (T.isArch32Bit())
 | |
|     return MachO::CPU_SUBTYPE_I386_ALL;
 | |
| 
 | |
|   assert(T.isArch64Bit());
 | |
|   if (T.getArchName() == "x86_64h")
 | |
|     return MachO::CPU_SUBTYPE_X86_64_H;
 | |
|   return MachO::CPU_SUBTYPE_X86_64_ALL;
 | |
| }
 | |
| 
 | |
| static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
 | |
|   assert(T.isARM() || T.isThumb());
 | |
|   StringRef Arch = T.getArchName();
 | |
|   ARM::ArchKind AK = ARM::parseArch(Arch);
 | |
|   switch (AK) {
 | |
|   default:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7;
 | |
|   case ARM::ArchKind::ARMV4T:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V4T;
 | |
|   case ARM::ArchKind::ARMV5T:
 | |
|   case ARM::ArchKind::ARMV5TE:
 | |
|   case ARM::ArchKind::ARMV5TEJ:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V5;
 | |
|   case ARM::ArchKind::ARMV6:
 | |
|   case ARM::ArchKind::ARMV6K:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V6;
 | |
|   case ARM::ArchKind::ARMV7A:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7;
 | |
|   case ARM::ArchKind::ARMV7S:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7S;
 | |
|   case ARM::ArchKind::ARMV7K:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7K;
 | |
|   case ARM::ArchKind::ARMV6M:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V6M;
 | |
|   case ARM::ArchKind::ARMV7M:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7M;
 | |
|   case ARM::ArchKind::ARMV7EM:
 | |
|     return MachO::CPU_SUBTYPE_ARM_V7EM;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
 | |
|   assert(T.isAArch64());
 | |
|   if (T.isArch32Bit())
 | |
|     return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
 | |
|   if (T.isArm64e())
 | |
|     return MachO::CPU_SUBTYPE_ARM64E;
 | |
| 
 | |
|   return MachO::CPU_SUBTYPE_ARM64_ALL;
 | |
| }
 | |
| 
 | |
| static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) {
 | |
|   return MachO::CPU_SUBTYPE_POWERPC_ALL;
 | |
| }
 | |
| 
 | |
| static Error unsupported(const char *Str, const Triple &T) {
 | |
|   return createStringError(std::errc::invalid_argument,
 | |
|                            "Unsupported triple for mach-o cpu %s: %s", Str,
 | |
|                            T.str().c_str());
 | |
| }
 | |
| 
 | |
| Expected<uint32_t> MachO::getCPUType(const Triple &T) {
 | |
|   if (!T.isOSBinFormatMachO())
 | |
|     return unsupported("type", T);
 | |
|   if (T.isX86() && T.isArch32Bit())
 | |
|     return MachO::CPU_TYPE_X86;
 | |
|   if (T.isX86() && T.isArch64Bit())
 | |
|     return MachO::CPU_TYPE_X86_64;
 | |
|   if (T.isARM() || T.isThumb())
 | |
|     return MachO::CPU_TYPE_ARM;
 | |
|   if (T.isAArch64())
 | |
|     return T.isArch32Bit() ? MachO::CPU_TYPE_ARM64_32 : MachO::CPU_TYPE_ARM64;
 | |
|   if (T.getArch() == Triple::ppc)
 | |
|     return MachO::CPU_TYPE_POWERPC;
 | |
|   if (T.getArch() == Triple::ppc64)
 | |
|     return MachO::CPU_TYPE_POWERPC64;
 | |
|   return unsupported("type", T);
 | |
| }
 | |
| 
 | |
| Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
 | |
|   if (!T.isOSBinFormatMachO())
 | |
|     return unsupported("subtype", T);
 | |
|   if (T.isX86())
 | |
|     return getX86SubType(T);
 | |
|   if (T.isARM() || T.isThumb())
 | |
|     return getARMSubType(T);
 | |
|   if (T.isAArch64() || T.getArch() == Triple::aarch64_32)
 | |
|     return getARM64SubType(T);
 | |
|   if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
 | |
|     return getPowerPCSubType(T);
 | |
|   return unsupported("subtype", T);
 | |
| }
 |