brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · f46b9d5 Raw
126 lines · cpp
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-exception6//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 109Expected<uint32_t> MachO::getCPUSubType(const Triple &T,110                                        unsigned PtrAuthABIVersion,111                                        bool PtrAuthKernelABIVersion) {112  Expected<uint32_t> Result = MachO::getCPUSubType(T);113  if (!Result)114    return Result.takeError();115  if (*Result != MachO::CPU_SUBTYPE_ARM64E)116    return createStringError(117        std::errc::invalid_argument,118        "ptrauth ABI version is only supported on arm64e.");119  if (PtrAuthABIVersion > 0xF)120    return createStringError(121        std::errc::invalid_argument,122        "The ptrauth ABI version needs to fit within 4 bits.");123  return CPU_SUBTYPE_ARM64E_WITH_PTRAUTH_VERSION(PtrAuthABIVersion,124                                                 PtrAuthKernelABIVersion);125}126