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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/BinaryFormat/MachO.h" |
10 | #include "llvm/TargetParser/ARMTargetParser.h" |
11 | #include "llvm/TargetParser/Triple.h" |
12 | |
13 | using namespace llvm; |
14 | |
15 | static 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 | |
26 | static 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 | |
57 | static 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 | |
67 | static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) { |
68 | return MachO::CPU_SUBTYPE_POWERPC_ALL; |
69 | } |
70 | |
71 | static Error unsupported(const char *Str, const Triple &T) { |
72 | return createStringError(EC: std::errc::invalid_argument, |
73 | Fmt: "Unsupported triple for mach-o cpu %s: %s", Vals: Str, |
74 | Vals: T.str().c_str()); |
75 | } |
76 | |
77 | Expected<uint32_t> MachO::getCPUType(const Triple &T) { |
78 | if (!T.isOSBinFormatMachO()) |
79 | return unsupported(Str: "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(Str: "type", T); |
93 | } |
94 | |
95 | Expected<uint32_t> MachO::getCPUSubType(const Triple &T) { |
96 | if (!T.isOSBinFormatMachO()) |
97 | return unsupported(Str: "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(Str: "subtype", T); |
107 | } |
108 |