aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/BinaryFormat/MachO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/BinaryFormat/MachO.cpp')
-rw-r--r--llvm/lib/BinaryFormat/MachO.cpp109
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);
+}