dyld-640.2.tar.gz
[apple/dyld.git] / dyld3 / MachOFile.h
1 /*
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #ifndef MachOFile_h
26 #define MachOFile_h
27
28 #include <mach-o/loader.h>
29 #include <mach-o/fat.h>
30 #include <uuid/uuid.h>
31
32 #include "Diagnostics.h"
33
34 #ifndef EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
35 #define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE 0x02
36 #endif
37
38
39 #ifndef PLATFORM_IOSSIMULATOR
40 #define PLATFORM_IOSSIMULATOR (7)
41 #endif
42
43 #ifndef PLATFORM_TVOSSIMULATOR
44 #define PLATFORM_TVOSSIMULATOR (8)
45 #endif
46
47 #ifndef PLATFORM_WATCHOSSIMULATOR
48 #define PLATFORM_WATCHOSSIMULATOR (9)
49 #endif
50
51
52 namespace dyld3 {
53
54
55
56 /// Returns true if (addLHS + addRHS) > b, or if the add overflowed
57 template<typename T>
58 inline bool greaterThanAddOrOverflow(uint32_t addLHS, uint32_t addRHS, T b) {
59 return (addLHS > b) || (addRHS > (b-addLHS));
60 }
61
62 /// Returns true if (addLHS + addRHS) > b, or if the add overflowed
63 template<typename T>
64 inline bool greaterThanAddOrOverflow(uint64_t addLHS, uint64_t addRHS, T b) {
65 return (addLHS > b) || (addRHS > (b-addLHS));
66 }
67
68
69 // Note, this should match PLATFORM_* values in <mach-o/loader.h>
70 enum class Platform {
71 unknown = 0,
72 macOS = 1, // PLATFORM_MACOS
73 iOS = 2, // PLATFORM_IOS
74 tvOS = 3, // PLATFORM_TVOS
75 watchOS = 4, // PLATFORM_WATCHOS
76 bridgeOS = 5, // PLATFORM_BRIDGEOS
77 iOSMac = 6, // PLATFORM_IOSMAC
78 iOS_simulator = 7, // PLATFORM_IOSSIMULATOR
79 tvOS_simulator = 8, // PLATFORM_TVOSSIMULATOR
80 watchOS_simulator = 9 // PLATFORM_WATCHOSSIMULATOR
81 };
82
83 // A file read/mapped into memory
84 struct VIS_HIDDEN FatFile : fat_header
85 {
86 static const FatFile* isFatFile(const void* fileContent);
87 void forEachSlice(Diagnostics& diag, uint64_t fileLen, void (^callback)(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop)) const;
88 bool isFatFileWithSlice(Diagnostics& diag, uint64_t fileLen, const char* archName, uint64_t& sliceOffset, uint64_t& sliceLen, bool& missingSlice) const;
89 };
90
91
92 // A mach-o file read/mapped into memory
93 // Only info from mach_header or load commands is accessible (no LINKEDIT info)
94 struct VIS_HIDDEN MachOFile : mach_header
95 {
96 static const char* archName(uint32_t cputype, uint32_t cpusubtype);
97 static const char* platformName(Platform platform);
98 static uint32_t cpuTypeFromArchName(const char* archName);
99 static uint32_t cpuSubtypeFromArchName(const char* archName);
100 static void packedVersionToString(uint32_t packedVersion, char versionString[32]);
101 static const char* currentArchName();
102 static Platform currentPlatform();
103 static uint64_t read_uleb128(Diagnostics& diag, const uint8_t*& p, const uint8_t* end);
104 static int64_t read_sleb128(Diagnostics& diag, const uint8_t*& p, const uint8_t* end);
105
106
107 bool hasMachOMagic() const;
108 bool isMachO(Diagnostics& diag, uint64_t fileSize) const;
109 bool isDylib() const;
110 bool isBundle() const;
111 bool isMainExecutable() const;
112 bool isDynamicExecutable() const;
113 bool isPIE() const;
114 bool isArch(const char* archName) const;
115 const char* archName() const;
116 bool is64() const;
117 uint32_t pointerSize() const;
118 bool uses16KPages() const;
119 bool supportsPlatform(Platform) const;
120 bool isSimulatorBinary() const;
121 bool getUuid(uuid_t uuid) const;
122 bool hasWeakDefs() const;
123 bool hasThreadLocalVariables() const;
124 bool getDylibInstallName(const char** installName, uint32_t* compatVersion, uint32_t* currentVersion) const;
125 void forEachSupportedPlatform(void (^callback)(Platform platform, uint32_t minOS, uint32_t sdk)) const;
126 const char* installName() const; // returns nullptr is no install name
127 void forEachDependentDylib(void (^callback)(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop)) const;
128 bool canBePlacedInDyldCache(const char* path, void (^failureReason)(const char*)) const;
129 bool canBeFairPlayEncrypted() const;
130 bool isFairPlayEncrypted(uint32_t& textOffset, uint32_t& size) const;
131 bool hasChainedFixups() const;
132 void forDyldEnv(void (^callback)(const char* envVar, bool& stop)) const;
133 bool enforceCompatVersion() const;
134
135 struct SegmentInfo
136 {
137 uint64_t fileOffset;
138 uint64_t fileSize;
139 uint64_t vmAddr;
140 uint64_t vmSize;
141 uint64_t sizeOfSections;
142 const char* segName;
143 uint32_t protections;
144 uint32_t textRelocs : 1, // segment has text relocs (i386 only)
145 segIndex : 15,
146 p2align : 16;
147 bool readable() const { return protections & VM_PROT_READ; }
148 bool writable() const { return protections & VM_PROT_WRITE; }
149 bool executable() const { return protections & VM_PROT_EXECUTE; }
150 };
151
152 struct SectionInfo
153 {
154 SegmentInfo segInfo;
155 uint64_t sectAddr;
156 uint64_t sectSize;
157 const char* sectName;
158 uint32_t sectFileOffset;
159 uint32_t sectFlags;
160 uint32_t sectAlignP2;
161 uint32_t reserved1;
162 uint32_t reserved2;
163 };
164
165 void forEachSegment(void (^callback)(const SegmentInfo& info, bool& stop)) const;
166 void forEachSection(void (^callback)(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop)) const;
167
168 protected:
169 void forEachLoadCommand(Diagnostics& diag, void (^callback)(const load_command* cmd, bool& stop)) const;
170
171 const encryption_info_command* findFairPlayEncryptionLoadCommand() const;
172
173 struct ArchInfo
174 {
175 const char* name;
176 uint32_t cputype;
177 uint32_t cpusubtype;
178 };
179 static const ArchInfo _s_archInfos[];
180
181 struct PlatformInfo
182 {
183 const char* name;
184 Platform platform;
185 uint32_t loadCommand;
186 };
187 static const PlatformInfo _s_platformInfos[];
188 };
189
190
191 } // namespace dyld3
192
193 #endif /* MachOFile_h */