diff options
Diffstat (limited to 'llvm/lib/BinaryFormat/MachO.cpp')
| -rw-r--r-- | llvm/lib/BinaryFormat/MachO.cpp | 109 | 
1 files changed, 109 insertions, 0 deletions
| diff --git a/llvm/lib/BinaryFormat/MachO.cpp b/llvm/lib/BinaryFormat/MachO.cpp new file mode 100644 index 000000000000..2b9eb8025521 --- /dev/null +++ b/llvm/lib/BinaryFormat/MachO.cpp @@ -0,0 +1,109 @@ +//===-- 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() || T.getArch() == Triple::aarch64_32); +  if (T.isArch32Bit()) +    return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8; +  if (T.getArchName() == "arm64e") +    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 MachO::CPU_TYPE_ARM64; +  if (T.getArch() == Triple::aarch64_32) +    return MachO::CPU_TYPE_ARM64_32; +  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); +} | 
