1 | //===- unittest/BinaryFormat/MachOTest.cpp - MachO support tests ----------===// |
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/Triple.h" |
11 | #include "gtest/gtest.h" |
12 | |
13 | using namespace llvm; |
14 | using namespace llvm::MachO; |
15 | |
16 | TEST(MachOTest, UnalignedLC) { |
17 | unsigned char Valid32BitMachO[] = { |
18 | 0xCE, 0xFA, 0xED, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, |
19 | 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, |
20 | 0x85, 0x80, 0x21, 0x01, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, |
21 | 0x5F, 0x5F, 0x50, 0x41, 0x47, 0x45, 0x5A, 0x45, 0x52, 0x4F, 0x00, 0x00, |
22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, |
23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
25 | 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x4C, 0x49, |
26 | 0x4E, 0x4B, 0x45, 0x44, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
27 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, |
28 | 0x8C, 0x0B, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
30 | |
31 | mach_header * = |
32 | reinterpret_cast<mach_header *>(Valid32BitMachO); |
33 | if (!sys::IsLittleEndianHost) |
34 | swapStruct(mh&: *Header); |
35 | ASSERT_EQ(Header->magic, MH_MAGIC); |
36 | unsigned char *Current = Valid32BitMachO + sizeof(mach_header); |
37 | unsigned char *BufferEnd = |
38 | Valid32BitMachO + sizeof(mach_header) + Header->sizeofcmds; |
39 | while (Current < BufferEnd) { |
40 | macho_load_command *LC = |
41 | reinterpret_cast<macho_load_command *>(Current); |
42 | if (!sys::IsLittleEndianHost) |
43 | swapStruct(lc&: LC->load_command_data); |
44 | ASSERT_EQ(LC->load_command_data.cmd, LC_SEGMENT); |
45 | Current += LC->load_command_data.cmdsize; |
46 | } |
47 | } |
48 | |
49 | TEST(MachOTest, CPUType) { |
50 | #define CHECK_CPUTYPE(StrTriple, ExpectedCPUType) \ |
51 | ASSERT_EQ((MachO::CPUType)cantFail(MachO::getCPUType(Triple(StrTriple))), \ |
52 | (ExpectedCPUType)) |
53 | CHECK_CPUTYPE("x86_64-apple-darwin" , MachO::CPU_TYPE_X86_64); |
54 | CHECK_CPUTYPE("x86_64h-apple-darwin" , MachO::CPU_TYPE_X86_64); |
55 | CHECK_CPUTYPE("i386-apple-darwin" , MachO::CPU_TYPE_X86); |
56 | CHECK_CPUTYPE("armv7-apple-darwin" , MachO::CPU_TYPE_ARM); |
57 | CHECK_CPUTYPE("thumbv7-apple-darwin" , MachO::CPU_TYPE_ARM); |
58 | CHECK_CPUTYPE("arm64-apple-darwin" , MachO::CPU_TYPE_ARM64); |
59 | CHECK_CPUTYPE("arm64e-apple-darwin" , MachO::CPU_TYPE_ARM64); |
60 | CHECK_CPUTYPE("arm64_32-apple-darwin" , MachO::CPU_TYPE_ARM64_32); |
61 | |
62 | { |
63 | // Not a mach-o. |
64 | Expected<uint32_t> Type = MachO::getCPUType(T: Triple("x86_64-linux-unknown" )); |
65 | ASSERT_EQ(toString(Type.takeError()), |
66 | "Unsupported triple for mach-o cpu type: x86_64-linux-unknown" ); |
67 | } |
68 | { |
69 | // Not a valid mach-o architecture. |
70 | Expected<uint32_t> Type = MachO::getCPUType(T: Triple("mips-apple-darwin" )); |
71 | ASSERT_EQ(toString(Type.takeError()), |
72 | "Unsupported triple for mach-o cpu type: mips-apple-darwin" ); |
73 | } |
74 | #undef CHECK_CPUTYPE |
75 | } |
76 | |
77 | TEST(MachOTest, CPUSubType) { |
78 | #define CHECK_CPUSUBTYPE(StrTriple, ExpectedCPUSubType) \ |
79 | ASSERT_EQ(cantFail(MachO::getCPUSubType(Triple(StrTriple))), \ |
80 | ((uint32_t)ExpectedCPUSubType)) |
81 | CHECK_CPUSUBTYPE("x86_64-apple-darwin" , MachO::CPU_SUBTYPE_X86_64_ALL); |
82 | CHECK_CPUSUBTYPE("x86_64h-apple-darwin" , MachO::CPU_SUBTYPE_X86_64_H); |
83 | CHECK_CPUSUBTYPE("i386-apple-darwin" , MachO::CPU_SUBTYPE_I386_ALL); |
84 | CHECK_CPUSUBTYPE("arm-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7); // Default |
85 | CHECK_CPUSUBTYPE("armv4t-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V4T); |
86 | CHECK_CPUSUBTYPE("armv5t-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V5); |
87 | CHECK_CPUSUBTYPE("armv5te-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V5); |
88 | CHECK_CPUSUBTYPE("armv5tej-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V5); |
89 | CHECK_CPUSUBTYPE("armv6-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V6); |
90 | CHECK_CPUSUBTYPE("armv6k-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V6); |
91 | CHECK_CPUSUBTYPE("armv7a-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7); |
92 | CHECK_CPUSUBTYPE("armv7s-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7S); |
93 | CHECK_CPUSUBTYPE("armv7k-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7K); |
94 | CHECK_CPUSUBTYPE("armv6m-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V6M); |
95 | CHECK_CPUSUBTYPE("armv7m-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7M); |
96 | CHECK_CPUSUBTYPE("armv7em-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7EM); |
97 | CHECK_CPUSUBTYPE("thumbv7-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V7); |
98 | CHECK_CPUSUBTYPE("thumbv6-apple-darwin" , MachO::CPU_SUBTYPE_ARM_V6); |
99 | CHECK_CPUSUBTYPE("arm64-apple-darwin" , MachO::CPU_SUBTYPE_ARM64_ALL); |
100 | CHECK_CPUSUBTYPE("arm64e-apple-darwin" , MachO::CPU_SUBTYPE_ARM64E); |
101 | CHECK_CPUSUBTYPE("arm64_32-apple-darwin" , MachO::CPU_SUBTYPE_ARM64_32_V8); |
102 | |
103 | { |
104 | // Not a mach-o. |
105 | Expected<uint32_t> Type = |
106 | MachO::getCPUSubType(T: Triple("x86_64-linux-unknown" )); |
107 | ASSERT_EQ( |
108 | toString(Type.takeError()), |
109 | "Unsupported triple for mach-o cpu subtype: x86_64-linux-unknown" ); |
110 | } |
111 | { |
112 | // Not a valid mach-o architecture. |
113 | Expected<uint32_t> Type = MachO::getCPUSubType(T: Triple("mips-apple-darwin" )); |
114 | ASSERT_EQ(toString(Type.takeError()), |
115 | "Unsupported triple for mach-o cpu subtype: mips-apple-darwin" ); |
116 | } |
117 | #undef CHECK_CPUSUBTYPE |
118 | } |
119 | |