1 | //===-- llvm/BinaryFormat/MachO.h - 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 | // This file defines manifest constants for the MachO object file format. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_BINARYFORMAT_MACHO_H |
14 | #define LLVM_BINARYFORMAT_MACHO_H |
15 | |
16 | #include "llvm/Support/Compiler.h" |
17 | #include "llvm/Support/DataTypes.h" |
18 | #include "llvm/Support/Error.h" |
19 | #include "llvm/Support/SwapByteOrder.h" |
20 | |
21 | namespace llvm { |
22 | |
23 | class Triple; |
24 | |
25 | namespace MachO { |
26 | // Enums from <mach-o/loader.h> |
27 | enum : uint32_t { |
28 | // Constants for the "magic" field in llvm::MachO::mach_header and |
29 | // llvm::MachO::mach_header_64 |
30 | MH_MAGIC = 0xFEEDFACEu, |
31 | MH_CIGAM = 0xCEFAEDFEu, |
32 | MH_MAGIC_64 = 0xFEEDFACFu, |
33 | MH_CIGAM_64 = 0xCFFAEDFEu, |
34 | FAT_MAGIC = 0xCAFEBABEu, |
35 | FAT_CIGAM = 0xBEBAFECAu, |
36 | FAT_MAGIC_64 = 0xCAFEBABFu, |
37 | FAT_CIGAM_64 = 0xBFBAFECAu |
38 | }; |
39 | |
40 | enum { |
41 | // Constants for the "filetype" field in llvm::MachO::mach_header and |
42 | // llvm::MachO::mach_header_64 |
43 | MH_OBJECT = 0x1u, |
44 | MH_EXECUTE = 0x2u, |
45 | MH_FVMLIB = 0x3u, |
46 | MH_CORE = 0x4u, |
47 | MH_PRELOAD = 0x5u, |
48 | MH_DYLIB = 0x6u, |
49 | MH_DYLINKER = 0x7u, |
50 | MH_BUNDLE = 0x8u, |
51 | MH_DYLIB_STUB = 0x9u, |
52 | MH_DSYM = 0xAu, |
53 | MH_KEXT_BUNDLE = 0xBu, |
54 | MH_FILESET = 0xCu, |
55 | }; |
56 | |
57 | enum { |
58 | // Constant bits for the "flags" field in llvm::MachO::mach_header and |
59 | // llvm::MachO::mach_header_64 |
60 | MH_NOUNDEFS = 0x00000001u, |
61 | MH_INCRLINK = 0x00000002u, |
62 | MH_DYLDLINK = 0x00000004u, |
63 | MH_BINDATLOAD = 0x00000008u, |
64 | MH_PREBOUND = 0x00000010u, |
65 | MH_SPLIT_SEGS = 0x00000020u, |
66 | MH_LAZY_INIT = 0x00000040u, |
67 | MH_TWOLEVEL = 0x00000080u, |
68 | MH_FORCE_FLAT = 0x00000100u, |
69 | MH_NOMULTIDEFS = 0x00000200u, |
70 | MH_NOFIXPREBINDING = 0x00000400u, |
71 | MH_PREBINDABLE = 0x00000800u, |
72 | MH_ALLMODSBOUND = 0x00001000u, |
73 | MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u, |
74 | MH_CANONICAL = 0x00004000u, |
75 | MH_WEAK_DEFINES = 0x00008000u, |
76 | MH_BINDS_TO_WEAK = 0x00010000u, |
77 | MH_ALLOW_STACK_EXECUTION = 0x00020000u, |
78 | MH_ROOT_SAFE = 0x00040000u, |
79 | MH_SETUID_SAFE = 0x00080000u, |
80 | MH_NO_REEXPORTED_DYLIBS = 0x00100000u, |
81 | MH_PIE = 0x00200000u, |
82 | MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u, |
83 | MH_HAS_TLV_DESCRIPTORS = 0x00800000u, |
84 | MH_NO_HEAP_EXECUTION = 0x01000000u, |
85 | MH_APP_EXTENSION_SAFE = 0x02000000u, |
86 | MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u, |
87 | MH_SIM_SUPPORT = 0x08000000u, |
88 | MH_DYLIB_IN_CACHE = 0x80000000u, |
89 | }; |
90 | |
91 | enum : uint32_t { |
92 | // Flags for the "cmd" field in llvm::MachO::load_command |
93 | LC_REQ_DYLD = 0x80000000u |
94 | }; |
95 | |
96 | #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) LCName = LCValue, |
97 | |
98 | enum LoadCommandType : uint32_t { |
99 | #include "llvm/BinaryFormat/MachO.def" |
100 | }; |
101 | |
102 | #undef HANDLE_LOAD_COMMAND |
103 | |
104 | enum : uint32_t { |
105 | // Constant bits for the "flags" field in llvm::MachO::segment_command |
106 | SG_HIGHVM = 0x1u, |
107 | SG_FVMLIB = 0x2u, |
108 | SG_NORELOC = 0x4u, |
109 | SG_PROTECTED_VERSION_1 = 0x8u, |
110 | SG_READ_ONLY = 0x10u, |
111 | |
112 | // Constant masks for the "flags" field in llvm::MachO::section and |
113 | // llvm::MachO::section_64 |
114 | SECTION_TYPE = 0x000000ffu, // SECTION_TYPE |
115 | SECTION_ATTRIBUTES = 0xffffff00u, // SECTION_ATTRIBUTES |
116 | SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR |
117 | SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS |
118 | }; |
119 | |
120 | /// These are the section type and attributes fields. A MachO section can |
121 | /// have only one Type, but can have any of the attributes specified. |
122 | enum SectionType : uint32_t { |
123 | // Constant masks for the "flags[7:0]" field in llvm::MachO::section and |
124 | // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE) |
125 | |
126 | /// S_REGULAR - Regular section. |
127 | S_REGULAR = 0x00u, |
128 | /// S_ZEROFILL - Zero fill on demand section. |
129 | S_ZEROFILL = 0x01u, |
130 | /// S_CSTRING_LITERALS - Section with literal C strings. |
131 | S_CSTRING_LITERALS = 0x02u, |
132 | /// S_4BYTE_LITERALS - Section with 4 byte literals. |
133 | S_4BYTE_LITERALS = 0x03u, |
134 | /// S_8BYTE_LITERALS - Section with 8 byte literals. |
135 | S_8BYTE_LITERALS = 0x04u, |
136 | /// S_LITERAL_POINTERS - Section with pointers to literals. |
137 | S_LITERAL_POINTERS = 0x05u, |
138 | /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers. |
139 | S_NON_LAZY_SYMBOL_POINTERS = 0x06u, |
140 | /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers. |
141 | S_LAZY_SYMBOL_POINTERS = 0x07u, |
142 | /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in |
143 | /// the Reserved2 field. |
144 | S_SYMBOL_STUBS = 0x08u, |
145 | /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for |
146 | /// initialization. |
147 | S_MOD_INIT_FUNC_POINTERS = 0x09u, |
148 | /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for |
149 | /// termination. |
150 | S_MOD_TERM_FUNC_POINTERS = 0x0au, |
151 | /// S_COALESCED - Section contains symbols that are to be coalesced. |
152 | S_COALESCED = 0x0bu, |
153 | /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 |
154 | /// gigabytes). |
155 | S_GB_ZEROFILL = 0x0cu, |
156 | /// S_INTERPOSING - Section with only pairs of function pointers for |
157 | /// interposing. |
158 | S_INTERPOSING = 0x0du, |
159 | /// S_16BYTE_LITERALS - Section with only 16 byte literals. |
160 | S_16BYTE_LITERALS = 0x0eu, |
161 | /// S_DTRACE_DOF - Section contains DTrace Object Format. |
162 | S_DTRACE_DOF = 0x0fu, |
163 | /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to |
164 | /// lazy loaded dylibs. |
165 | S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u, |
166 | /// S_THREAD_LOCAL_REGULAR - Thread local data section. |
167 | S_THREAD_LOCAL_REGULAR = 0x11u, |
168 | /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section. |
169 | S_THREAD_LOCAL_ZEROFILL = 0x12u, |
170 | /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable |
171 | /// structure data. |
172 | S_THREAD_LOCAL_VARIABLES = 0x13u, |
173 | /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread |
174 | /// local structures. |
175 | S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u, |
176 | /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local |
177 | /// variable initialization pointers to functions. |
178 | S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u, |
179 | /// S_INIT_FUNC_OFFSETS - Section with 32-bit offsets to initializer |
180 | /// functions. |
181 | S_INIT_FUNC_OFFSETS = 0x16u, |
182 | |
183 | LAST_KNOWN_SECTION_TYPE = S_INIT_FUNC_OFFSETS |
184 | }; |
185 | |
186 | enum : uint32_t { |
187 | // Constant masks for the "flags[31:24]" field in llvm::MachO::section and |
188 | // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR) |
189 | |
190 | /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine |
191 | /// instructions. |
192 | S_ATTR_PURE_INSTRUCTIONS = 0x80000000u, |
193 | /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be |
194 | /// in a ranlib table of contents. |
195 | S_ATTR_NO_TOC = 0x40000000u, |
196 | /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section |
197 | /// in files with the MY_DYLDLINK flag. |
198 | S_ATTR_STRIP_STATIC_SYMS = 0x20000000u, |
199 | /// S_ATTR_NO_DEAD_STRIP - No dead stripping. |
200 | S_ATTR_NO_DEAD_STRIP = 0x10000000u, |
201 | /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks. |
202 | S_ATTR_LIVE_SUPPORT = 0x08000000u, |
203 | /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by |
204 | /// dyld. |
205 | S_ATTR_SELF_MODIFYING_CODE = 0x04000000u, |
206 | /// S_ATTR_DEBUG - A debug section. |
207 | S_ATTR_DEBUG = 0x02000000u, |
208 | |
209 | // Constant masks for the "flags[23:8]" field in llvm::MachO::section and |
210 | // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS) |
211 | |
212 | /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions. |
213 | S_ATTR_SOME_INSTRUCTIONS = 0x00000400u, |
214 | /// S_ATTR_EXT_RELOC - Section has external relocation entries. |
215 | S_ATTR_EXT_RELOC = 0x00000200u, |
216 | /// S_ATTR_LOC_RELOC - Section has local relocation entries. |
217 | S_ATTR_LOC_RELOC = 0x00000100u, |
218 | |
219 | // Constant masks for the value of an indirect symbol in an indirect |
220 | // symbol table |
221 | INDIRECT_SYMBOL_LOCAL = 0x80000000u, |
222 | INDIRECT_SYMBOL_ABS = 0x40000000u |
223 | }; |
224 | |
225 | enum DataRegionType { |
226 | // Constants for the "kind" field in a data_in_code_entry structure |
227 | DICE_KIND_DATA = 1u, |
228 | DICE_KIND_JUMP_TABLE8 = 2u, |
229 | DICE_KIND_JUMP_TABLE16 = 3u, |
230 | DICE_KIND_JUMP_TABLE32 = 4u, |
231 | DICE_KIND_ABS_JUMP_TABLE32 = 5u |
232 | }; |
233 | |
234 | enum RebaseType { |
235 | REBASE_TYPE_POINTER = 1u, |
236 | REBASE_TYPE_TEXT_ABSOLUTE32 = 2u, |
237 | REBASE_TYPE_TEXT_PCREL32 = 3u |
238 | }; |
239 | |
240 | enum { REBASE_OPCODE_MASK = 0xF0u, REBASE_IMMEDIATE_MASK = 0x0Fu }; |
241 | |
242 | enum RebaseOpcode { |
243 | REBASE_OPCODE_DONE = 0x00u, |
244 | REBASE_OPCODE_SET_TYPE_IMM = 0x10u, |
245 | REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x20u, |
246 | REBASE_OPCODE_ADD_ADDR_ULEB = 0x30u, |
247 | REBASE_OPCODE_ADD_ADDR_IMM_SCALED = 0x40u, |
248 | REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50u, |
249 | REBASE_OPCODE_DO_REBASE_ULEB_TIMES = 0x60u, |
250 | REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB = 0x70u, |
251 | REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u |
252 | }; |
253 | |
254 | enum BindType { |
255 | BIND_TYPE_POINTER = 1u, |
256 | BIND_TYPE_TEXT_ABSOLUTE32 = 2u, |
257 | BIND_TYPE_TEXT_PCREL32 = 3u |
258 | }; |
259 | |
260 | enum BindSpecialDylib { |
261 | BIND_SPECIAL_DYLIB_SELF = 0, |
262 | BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1, |
263 | BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2, |
264 | BIND_SPECIAL_DYLIB_WEAK_LOOKUP = -3 |
265 | }; |
266 | |
267 | enum { |
268 | BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1u, |
269 | BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u, |
270 | |
271 | BIND_OPCODE_MASK = 0xF0u, |
272 | BIND_IMMEDIATE_MASK = 0x0Fu |
273 | }; |
274 | |
275 | enum BindOpcode { |
276 | BIND_OPCODE_DONE = 0x00u, |
277 | BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10u, |
278 | BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20u, |
279 | BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30u, |
280 | BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u, |
281 | BIND_OPCODE_SET_TYPE_IMM = 0x50u, |
282 | BIND_OPCODE_SET_ADDEND_SLEB = 0x60u, |
283 | BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70u, |
284 | BIND_OPCODE_ADD_ADDR_ULEB = 0x80u, |
285 | BIND_OPCODE_DO_BIND = 0x90u, |
286 | BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0u, |
287 | BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u, |
288 | BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u |
289 | }; |
290 | |
291 | enum { |
292 | EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03u, |
293 | EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04u, |
294 | EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08u, |
295 | EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10u |
296 | }; |
297 | |
298 | enum ExportSymbolKind { |
299 | EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u, |
300 | EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u, |
301 | EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02u |
302 | }; |
303 | |
304 | enum { |
305 | // Constant masks for the "n_type" field in llvm::MachO::nlist and |
306 | // llvm::MachO::nlist_64 |
307 | N_STAB = 0xe0, |
308 | N_PEXT = 0x10, |
309 | N_TYPE = 0x0e, |
310 | N_EXT = 0x01 |
311 | }; |
312 | |
313 | enum NListType : uint8_t { |
314 | // Constants for the "n_type & N_TYPE" llvm::MachO::nlist and |
315 | // llvm::MachO::nlist_64 |
316 | N_UNDF = 0x0u, |
317 | N_ABS = 0x2u, |
318 | N_SECT = 0xeu, |
319 | N_PBUD = 0xcu, |
320 | N_INDR = 0xau |
321 | }; |
322 | |
323 | enum SectionOrdinal { |
324 | // Constants for the "n_sect" field in llvm::MachO::nlist and |
325 | // llvm::MachO::nlist_64 |
326 | NO_SECT = 0u, |
327 | MAX_SECT = 0xffu |
328 | }; |
329 | |
330 | enum { |
331 | // Constant masks for the "n_desc" field in llvm::MachO::nlist and |
332 | // llvm::MachO::nlist_64 |
333 | // The low 3 bits are the for the REFERENCE_TYPE. |
334 | REFERENCE_TYPE = 0x7, |
335 | REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0, |
336 | REFERENCE_FLAG_UNDEFINED_LAZY = 1, |
337 | REFERENCE_FLAG_DEFINED = 2, |
338 | REFERENCE_FLAG_PRIVATE_DEFINED = 3, |
339 | REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4, |
340 | REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5, |
341 | // Flag bits (some overlap with the library ordinal bits). |
342 | N_ARM_THUMB_DEF = 0x0008u, |
343 | REFERENCED_DYNAMICALLY = 0x0010u, |
344 | N_NO_DEAD_STRIP = 0x0020u, |
345 | N_WEAK_REF = 0x0040u, |
346 | N_WEAK_DEF = 0x0080u, |
347 | N_SYMBOL_RESOLVER = 0x0100u, |
348 | N_ALT_ENTRY = 0x0200u, |
349 | N_COLD_FUNC = 0x0400u, |
350 | // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL() |
351 | // as these are in the top 8 bits. |
352 | SELF_LIBRARY_ORDINAL = 0x0, |
353 | MAX_LIBRARY_ORDINAL = 0xfd, |
354 | DYNAMIC_LOOKUP_ORDINAL = 0xfe, |
355 | EXECUTABLE_ORDINAL = 0xff |
356 | }; |
357 | |
358 | enum StabType { |
359 | // Constant values for the "n_type" field in llvm::MachO::nlist and |
360 | // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0" |
361 | N_GSYM = 0x20u, |
362 | N_FNAME = 0x22u, |
363 | N_FUN = 0x24u, |
364 | N_STSYM = 0x26u, |
365 | N_LCSYM = 0x28u, |
366 | N_BNSYM = 0x2Eu, |
367 | N_PC = 0x30u, |
368 | N_AST = 0x32u, |
369 | N_OPT = 0x3Cu, |
370 | N_RSYM = 0x40u, |
371 | N_SLINE = 0x44u, |
372 | N_ENSYM = 0x4Eu, |
373 | N_SSYM = 0x60u, |
374 | N_SO = 0x64u, |
375 | N_OSO = 0x66u, |
376 | N_LIB = 0x68u, |
377 | N_LSYM = 0x80u, |
378 | N_BINCL = 0x82u, |
379 | N_SOL = 0x84u, |
380 | N_PARAMS = 0x86u, |
381 | N_VERSION = 0x88u, |
382 | N_OLEVEL = 0x8Au, |
383 | N_PSYM = 0xA0u, |
384 | N_EINCL = 0xA2u, |
385 | N_ENTRY = 0xA4u, |
386 | N_LBRAC = 0xC0u, |
387 | N_EXCL = 0xC2u, |
388 | N_RBRAC = 0xE0u, |
389 | N_BCOMM = 0xE2u, |
390 | N_ECOMM = 0xE4u, |
391 | N_ECOML = 0xE8u, |
392 | N_LENG = 0xFEu |
393 | }; |
394 | |
395 | enum : uint32_t { |
396 | // Constant values for the r_symbolnum field in an |
397 | // llvm::MachO::relocation_info structure when r_extern is 0. |
398 | R_ABS = 0, |
399 | |
400 | // Constant bits for the r_address field in an |
401 | // llvm::MachO::relocation_info structure. |
402 | R_SCATTERED = 0x80000000 |
403 | }; |
404 | |
405 | enum RelocationInfoType { |
406 | // Constant values for the r_type field in an |
407 | // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info |
408 | // structure. |
409 | GENERIC_RELOC_INVALID = 0xff, |
410 | GENERIC_RELOC_VANILLA = 0, |
411 | GENERIC_RELOC_PAIR = 1, |
412 | GENERIC_RELOC_SECTDIFF = 2, |
413 | GENERIC_RELOC_PB_LA_PTR = 3, |
414 | GENERIC_RELOC_LOCAL_SECTDIFF = 4, |
415 | GENERIC_RELOC_TLV = 5, |
416 | |
417 | // Constant values for the r_type field in a PowerPC architecture |
418 | // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info |
419 | // structure. |
420 | PPC_RELOC_VANILLA = GENERIC_RELOC_VANILLA, |
421 | PPC_RELOC_PAIR = GENERIC_RELOC_PAIR, |
422 | PPC_RELOC_BR14 = 2, |
423 | PPC_RELOC_BR24 = 3, |
424 | PPC_RELOC_HI16 = 4, |
425 | PPC_RELOC_LO16 = 5, |
426 | PPC_RELOC_HA16 = 6, |
427 | PPC_RELOC_LO14 = 7, |
428 | PPC_RELOC_SECTDIFF = 8, |
429 | PPC_RELOC_PB_LA_PTR = 9, |
430 | PPC_RELOC_HI16_SECTDIFF = 10, |
431 | PPC_RELOC_LO16_SECTDIFF = 11, |
432 | PPC_RELOC_HA16_SECTDIFF = 12, |
433 | PPC_RELOC_JBSR = 13, |
434 | PPC_RELOC_LO14_SECTDIFF = 14, |
435 | PPC_RELOC_LOCAL_SECTDIFF = 15, |
436 | |
437 | // Constant values for the r_type field in an ARM architecture |
438 | // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info |
439 | // structure. |
440 | ARM_RELOC_VANILLA = GENERIC_RELOC_VANILLA, |
441 | ARM_RELOC_PAIR = GENERIC_RELOC_PAIR, |
442 | ARM_RELOC_SECTDIFF = GENERIC_RELOC_SECTDIFF, |
443 | ARM_RELOC_LOCAL_SECTDIFF = 3, |
444 | ARM_RELOC_PB_LA_PTR = 4, |
445 | ARM_RELOC_BR24 = 5, |
446 | ARM_THUMB_RELOC_BR22 = 6, |
447 | ARM_THUMB_32BIT_BRANCH = 7, // obsolete |
448 | ARM_RELOC_HALF = 8, |
449 | ARM_RELOC_HALF_SECTDIFF = 9, |
450 | |
451 | // Constant values for the r_type field in an ARM64 architecture |
452 | // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info |
453 | // structure. |
454 | |
455 | // For pointers. |
456 | ARM64_RELOC_UNSIGNED = 0, |
457 | // Must be followed by an ARM64_RELOC_UNSIGNED |
458 | ARM64_RELOC_SUBTRACTOR = 1, |
459 | // A B/BL instruction with 26-bit displacement. |
460 | ARM64_RELOC_BRANCH26 = 2, |
461 | // PC-rel distance to page of target. |
462 | ARM64_RELOC_PAGE21 = 3, |
463 | // Offset within page, scaled by r_length. |
464 | ARM64_RELOC_PAGEOFF12 = 4, |
465 | // PC-rel distance to page of GOT slot. |
466 | ARM64_RELOC_GOT_LOAD_PAGE21 = 5, |
467 | // Offset within page of GOT slot, scaled by r_length. |
468 | ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6, |
469 | // For pointers to GOT slots. |
470 | ARM64_RELOC_POINTER_TO_GOT = 7, |
471 | // PC-rel distance to page of TLVP slot. |
472 | ARM64_RELOC_TLVP_LOAD_PAGE21 = 8, |
473 | // Offset within page of TLVP slot, scaled by r_length. |
474 | ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9, |
475 | // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12. |
476 | ARM64_RELOC_ADDEND = 10, |
477 | // An authenticated pointer. |
478 | ARM64_RELOC_AUTHENTICATED_POINTER = 11, |
479 | |
480 | // Constant values for the r_type field in an x86_64 architecture |
481 | // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info |
482 | // structure |
483 | X86_64_RELOC_UNSIGNED = 0, |
484 | X86_64_RELOC_SIGNED = 1, |
485 | X86_64_RELOC_BRANCH = 2, |
486 | X86_64_RELOC_GOT_LOAD = 3, |
487 | X86_64_RELOC_GOT = 4, |
488 | X86_64_RELOC_SUBTRACTOR = 5, |
489 | X86_64_RELOC_SIGNED_1 = 6, |
490 | X86_64_RELOC_SIGNED_2 = 7, |
491 | X86_64_RELOC_SIGNED_4 = 8, |
492 | X86_64_RELOC_TLV = 9 |
493 | }; |
494 | |
495 | // Values for segment_command.initprot. |
496 | // From <mach/vm_prot.h> |
497 | enum { VM_PROT_READ = 0x1, VM_PROT_WRITE = 0x2, VM_PROT_EXECUTE = 0x4 }; |
498 | |
499 | // Values for platform field in build_version_command. |
500 | enum PlatformType { |
501 | #define PLATFORM(platform, id, name, build_name, target, tapi_target, \ |
502 | marketing) \ |
503 | PLATFORM_##platform = id, |
504 | #include "MachO.def" |
505 | }; |
506 | |
507 | // Values for tools enum in build_tool_version. |
508 | enum { TOOL_CLANG = 1, TOOL_SWIFT = 2, TOOL_LD = 3, TOOL_LLD = 4 }; |
509 | |
510 | // Structs from <mach-o/loader.h> |
511 | |
512 | struct { |
513 | uint32_t ; |
514 | uint32_t ; |
515 | uint32_t ; |
516 | uint32_t ; |
517 | uint32_t ; |
518 | uint32_t ; |
519 | uint32_t ; |
520 | }; |
521 | |
522 | struct { |
523 | uint32_t ; |
524 | uint32_t ; |
525 | uint32_t ; |
526 | uint32_t ; |
527 | uint32_t ; |
528 | uint32_t ; |
529 | uint32_t ; |
530 | uint32_t ; |
531 | }; |
532 | |
533 | struct load_command { |
534 | uint32_t cmd; |
535 | uint32_t cmdsize; |
536 | }; |
537 | |
538 | struct segment_command { |
539 | uint32_t cmd; |
540 | uint32_t cmdsize; |
541 | char segname[16]; |
542 | uint32_t vmaddr; |
543 | uint32_t vmsize; |
544 | uint32_t fileoff; |
545 | uint32_t filesize; |
546 | uint32_t maxprot; |
547 | uint32_t initprot; |
548 | uint32_t nsects; |
549 | uint32_t flags; |
550 | }; |
551 | |
552 | struct segment_command_64 { |
553 | uint32_t cmd; |
554 | uint32_t cmdsize; |
555 | char segname[16]; |
556 | uint64_t vmaddr; |
557 | uint64_t vmsize; |
558 | uint64_t fileoff; |
559 | uint64_t filesize; |
560 | uint32_t maxprot; |
561 | uint32_t initprot; |
562 | uint32_t nsects; |
563 | uint32_t flags; |
564 | }; |
565 | |
566 | struct section { |
567 | char sectname[16]; |
568 | char segname[16]; |
569 | uint32_t addr; |
570 | uint32_t size; |
571 | uint32_t offset; |
572 | uint32_t align; |
573 | uint32_t reloff; |
574 | uint32_t nreloc; |
575 | uint32_t flags; |
576 | uint32_t reserved1; |
577 | uint32_t reserved2; |
578 | }; |
579 | |
580 | struct section_64 { |
581 | char sectname[16]; |
582 | char segname[16]; |
583 | uint64_t addr; |
584 | uint64_t size; |
585 | uint32_t offset; |
586 | uint32_t align; |
587 | uint32_t reloff; |
588 | uint32_t nreloc; |
589 | uint32_t flags; |
590 | uint32_t reserved1; |
591 | uint32_t reserved2; |
592 | uint32_t reserved3; |
593 | }; |
594 | |
595 | inline bool isVirtualSection(uint8_t type) { |
596 | return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL || |
597 | type == MachO::S_THREAD_LOCAL_ZEROFILL); |
598 | } |
599 | |
600 | struct fvmlib { |
601 | uint32_t name; |
602 | uint32_t minor_version; |
603 | uint32_t ; |
604 | }; |
605 | |
606 | // The fvmlib_command is obsolete and no longer supported. |
607 | struct fvmlib_command { |
608 | uint32_t cmd; |
609 | uint32_t cmdsize; |
610 | struct fvmlib fvmlib; |
611 | }; |
612 | |
613 | struct dylib { |
614 | uint32_t name; |
615 | uint32_t timestamp; |
616 | uint32_t current_version; |
617 | uint32_t compatibility_version; |
618 | }; |
619 | |
620 | struct dylib_command { |
621 | uint32_t cmd; |
622 | uint32_t cmdsize; |
623 | struct dylib dylib; |
624 | }; |
625 | |
626 | struct sub_framework_command { |
627 | uint32_t cmd; |
628 | uint32_t cmdsize; |
629 | uint32_t umbrella; |
630 | }; |
631 | |
632 | struct sub_client_command { |
633 | uint32_t cmd; |
634 | uint32_t cmdsize; |
635 | uint32_t client; |
636 | }; |
637 | |
638 | struct sub_umbrella_command { |
639 | uint32_t cmd; |
640 | uint32_t cmdsize; |
641 | uint32_t sub_umbrella; |
642 | }; |
643 | |
644 | struct sub_library_command { |
645 | uint32_t cmd; |
646 | uint32_t cmdsize; |
647 | uint32_t sub_library; |
648 | }; |
649 | |
650 | // The prebound_dylib_command is obsolete and no longer supported. |
651 | struct prebound_dylib_command { |
652 | uint32_t cmd; |
653 | uint32_t cmdsize; |
654 | uint32_t name; |
655 | uint32_t nmodules; |
656 | uint32_t linked_modules; |
657 | }; |
658 | |
659 | struct dylinker_command { |
660 | uint32_t cmd; |
661 | uint32_t cmdsize; |
662 | uint32_t name; |
663 | }; |
664 | |
665 | struct thread_command { |
666 | uint32_t cmd; |
667 | uint32_t cmdsize; |
668 | }; |
669 | |
670 | struct routines_command { |
671 | uint32_t cmd; |
672 | uint32_t cmdsize; |
673 | uint32_t init_address; |
674 | uint32_t init_module; |
675 | uint32_t reserved1; |
676 | uint32_t reserved2; |
677 | uint32_t reserved3; |
678 | uint32_t reserved4; |
679 | uint32_t reserved5; |
680 | uint32_t reserved6; |
681 | }; |
682 | |
683 | struct routines_command_64 { |
684 | uint32_t cmd; |
685 | uint32_t cmdsize; |
686 | uint64_t init_address; |
687 | uint64_t init_module; |
688 | uint64_t reserved1; |
689 | uint64_t reserved2; |
690 | uint64_t reserved3; |
691 | uint64_t reserved4; |
692 | uint64_t reserved5; |
693 | uint64_t reserved6; |
694 | }; |
695 | |
696 | struct symtab_command { |
697 | uint32_t cmd; |
698 | uint32_t cmdsize; |
699 | uint32_t symoff; |
700 | uint32_t nsyms; |
701 | uint32_t stroff; |
702 | uint32_t strsize; |
703 | }; |
704 | |
705 | struct dysymtab_command { |
706 | uint32_t cmd; |
707 | uint32_t cmdsize; |
708 | uint32_t ilocalsym; |
709 | uint32_t nlocalsym; |
710 | uint32_t iextdefsym; |
711 | uint32_t nextdefsym; |
712 | uint32_t iundefsym; |
713 | uint32_t nundefsym; |
714 | uint32_t tocoff; |
715 | uint32_t ntoc; |
716 | uint32_t modtaboff; |
717 | uint32_t nmodtab; |
718 | uint32_t extrefsymoff; |
719 | uint32_t nextrefsyms; |
720 | uint32_t indirectsymoff; |
721 | uint32_t nindirectsyms; |
722 | uint32_t extreloff; |
723 | uint32_t nextrel; |
724 | uint32_t locreloff; |
725 | uint32_t nlocrel; |
726 | }; |
727 | |
728 | struct dylib_table_of_contents { |
729 | uint32_t symbol_index; |
730 | uint32_t module_index; |
731 | }; |
732 | |
733 | struct dylib_module { |
734 | uint32_t module_name; |
735 | uint32_t iextdefsym; |
736 | uint32_t nextdefsym; |
737 | uint32_t irefsym; |
738 | uint32_t nrefsym; |
739 | uint32_t ilocalsym; |
740 | uint32_t nlocalsym; |
741 | uint32_t iextrel; |
742 | uint32_t nextrel; |
743 | uint32_t iinit_iterm; |
744 | uint32_t ninit_nterm; |
745 | uint32_t objc_module_info_addr; |
746 | uint32_t objc_module_info_size; |
747 | }; |
748 | |
749 | struct dylib_module_64 { |
750 | uint32_t module_name; |
751 | uint32_t iextdefsym; |
752 | uint32_t nextdefsym; |
753 | uint32_t irefsym; |
754 | uint32_t nrefsym; |
755 | uint32_t ilocalsym; |
756 | uint32_t nlocalsym; |
757 | uint32_t iextrel; |
758 | uint32_t nextrel; |
759 | uint32_t iinit_iterm; |
760 | uint32_t ninit_nterm; |
761 | uint32_t objc_module_info_size; |
762 | uint64_t objc_module_info_addr; |
763 | }; |
764 | |
765 | struct dylib_reference { |
766 | uint32_t isym : 24, flags : 8; |
767 | }; |
768 | |
769 | // The twolevel_hints_command is obsolete and no longer supported. |
770 | struct twolevel_hints_command { |
771 | uint32_t cmd; |
772 | uint32_t cmdsize; |
773 | uint32_t offset; |
774 | uint32_t nhints; |
775 | }; |
776 | |
777 | // The twolevel_hints_command is obsolete and no longer supported. |
778 | struct twolevel_hint { |
779 | uint32_t isub_image : 8, itoc : 24; |
780 | }; |
781 | |
782 | // The prebind_cksum_command is obsolete and no longer supported. |
783 | struct prebind_cksum_command { |
784 | uint32_t cmd; |
785 | uint32_t cmdsize; |
786 | uint32_t cksum; |
787 | }; |
788 | |
789 | struct uuid_command { |
790 | uint32_t cmd; |
791 | uint32_t cmdsize; |
792 | uint8_t uuid[16]; |
793 | }; |
794 | |
795 | struct rpath_command { |
796 | uint32_t cmd; |
797 | uint32_t cmdsize; |
798 | uint32_t path; |
799 | }; |
800 | |
801 | struct linkedit_data_command { |
802 | uint32_t cmd; |
803 | uint32_t cmdsize; |
804 | uint32_t dataoff; |
805 | uint32_t datasize; |
806 | }; |
807 | |
808 | struct data_in_code_entry { |
809 | uint32_t offset; |
810 | uint16_t length; |
811 | uint16_t kind; |
812 | }; |
813 | |
814 | struct source_version_command { |
815 | uint32_t cmd; |
816 | uint32_t cmdsize; |
817 | uint64_t version; |
818 | }; |
819 | |
820 | struct encryption_info_command { |
821 | uint32_t cmd; |
822 | uint32_t cmdsize; |
823 | uint32_t cryptoff; |
824 | uint32_t cryptsize; |
825 | uint32_t cryptid; |
826 | }; |
827 | |
828 | struct encryption_info_command_64 { |
829 | uint32_t cmd; |
830 | uint32_t cmdsize; |
831 | uint32_t cryptoff; |
832 | uint32_t cryptsize; |
833 | uint32_t cryptid; |
834 | uint32_t pad; |
835 | }; |
836 | |
837 | struct version_min_command { |
838 | uint32_t cmd; // LC_VERSION_MIN_MACOSX or |
839 | // LC_VERSION_MIN_IPHONEOS |
840 | uint32_t cmdsize; // sizeof(struct version_min_command) |
841 | uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz |
842 | uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz |
843 | }; |
844 | |
845 | struct note_command { |
846 | uint32_t cmd; // LC_NOTE |
847 | uint32_t cmdsize; // sizeof(struct note_command) |
848 | char data_owner[16]; // owner name for this LC_NOTE |
849 | uint64_t offset; // file offset of this data |
850 | uint64_t size; // length of data region |
851 | }; |
852 | |
853 | struct build_tool_version { |
854 | uint32_t tool; // enum for the tool |
855 | uint32_t version; // version of the tool |
856 | }; |
857 | |
858 | struct build_version_command { |
859 | uint32_t cmd; // LC_BUILD_VERSION |
860 | uint32_t cmdsize; // sizeof(struct build_version_command) + |
861 | // ntools * sizeof(struct build_tool_version) |
862 | uint32_t platform; // platform |
863 | uint32_t minos; // X.Y.Z is encoded in nibbles xxxx.yy.zz |
864 | uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz |
865 | uint32_t ntools; // number of tool entries following this |
866 | }; |
867 | |
868 | struct dyld_env_command { |
869 | uint32_t cmd; |
870 | uint32_t cmdsize; |
871 | uint32_t name; |
872 | }; |
873 | |
874 | struct dyld_info_command { |
875 | uint32_t cmd; |
876 | uint32_t cmdsize; |
877 | uint32_t rebase_off; |
878 | uint32_t rebase_size; |
879 | uint32_t bind_off; |
880 | uint32_t bind_size; |
881 | uint32_t weak_bind_off; |
882 | uint32_t weak_bind_size; |
883 | uint32_t lazy_bind_off; |
884 | uint32_t lazy_bind_size; |
885 | uint32_t export_off; |
886 | uint32_t export_size; |
887 | }; |
888 | |
889 | struct linker_option_command { |
890 | uint32_t cmd; |
891 | uint32_t cmdsize; |
892 | uint32_t count; |
893 | }; |
894 | |
895 | union lc_str { |
896 | uint32_t offset; |
897 | }; |
898 | |
899 | struct fileset_entry_command { |
900 | uint32_t cmd; |
901 | uint32_t cmdsize; |
902 | uint64_t vmaddr; |
903 | uint64_t fileoff; |
904 | union lc_str entry_id; |
905 | uint32_t reserved; |
906 | }; |
907 | |
908 | // The symseg_command is obsolete and no longer supported. |
909 | struct symseg_command { |
910 | uint32_t cmd; |
911 | uint32_t cmdsize; |
912 | uint32_t offset; |
913 | uint32_t size; |
914 | }; |
915 | |
916 | // The ident_command is obsolete and no longer supported. |
917 | struct ident_command { |
918 | uint32_t cmd; |
919 | uint32_t cmdsize; |
920 | }; |
921 | |
922 | // The fvmfile_command is obsolete and no longer supported. |
923 | struct fvmfile_command { |
924 | uint32_t cmd; |
925 | uint32_t cmdsize; |
926 | uint32_t name; |
927 | uint32_t header_addr; |
928 | }; |
929 | |
930 | struct tlv_descriptor_32 { |
931 | uint32_t thunk; |
932 | uint32_t key; |
933 | uint32_t offset; |
934 | }; |
935 | |
936 | struct tlv_descriptor_64 { |
937 | uint64_t thunk; |
938 | uint64_t key; |
939 | uint64_t offset; |
940 | }; |
941 | |
942 | struct tlv_descriptor { |
943 | uintptr_t thunk; |
944 | uintptr_t key; |
945 | uintptr_t offset; |
946 | }; |
947 | |
948 | struct entry_point_command { |
949 | uint32_t cmd; |
950 | uint32_t cmdsize; |
951 | uint64_t entryoff; |
952 | uint64_t stacksize; |
953 | }; |
954 | |
955 | // Structs from <mach-o/fat.h> |
956 | struct { |
957 | uint32_t ; |
958 | uint32_t ; |
959 | }; |
960 | |
961 | struct fat_arch { |
962 | uint32_t cputype; |
963 | uint32_t cpusubtype; |
964 | uint32_t offset; |
965 | uint32_t size; |
966 | uint32_t align; |
967 | }; |
968 | |
969 | struct fat_arch_64 { |
970 | uint32_t cputype; |
971 | uint32_t cpusubtype; |
972 | uint64_t offset; |
973 | uint64_t size; |
974 | uint32_t align; |
975 | uint32_t reserved; |
976 | }; |
977 | |
978 | // Structs from <mach-o/reloc.h> |
979 | struct relocation_info { |
980 | int32_t r_address; |
981 | uint32_t r_symbolnum : 24, r_pcrel : 1, r_length : 2, r_extern : 1, |
982 | r_type : 4; |
983 | }; |
984 | |
985 | struct scattered_relocation_info { |
986 | #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN) |
987 | uint32_t r_scattered : 1, r_pcrel : 1, r_length : 2, r_type : 4, |
988 | r_address : 24; |
989 | #else |
990 | uint32_t r_address : 24, r_type : 4, r_length : 2, r_pcrel : 1, |
991 | r_scattered : 1; |
992 | #endif |
993 | int32_t r_value; |
994 | }; |
995 | |
996 | // Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier |
997 | struct any_relocation_info { |
998 | uint32_t r_word0, r_word1; |
999 | }; |
1000 | |
1001 | // Structs from <mach-o/nlist.h> |
1002 | struct nlist_base { |
1003 | uint32_t n_strx; |
1004 | uint8_t n_type; |
1005 | uint8_t n_sect; |
1006 | uint16_t n_desc; |
1007 | }; |
1008 | |
1009 | struct nlist { |
1010 | uint32_t n_strx; |
1011 | uint8_t n_type; |
1012 | uint8_t n_sect; |
1013 | int16_t n_desc; |
1014 | uint32_t n_value; |
1015 | }; |
1016 | |
1017 | struct nlist_64 { |
1018 | uint32_t n_strx; |
1019 | uint8_t n_type; |
1020 | uint8_t n_sect; |
1021 | uint16_t n_desc; |
1022 | uint64_t n_value; |
1023 | }; |
1024 | |
1025 | // Values for dyld_chained_fixups_header::imports_format. |
1026 | enum ChainedImportFormat { |
1027 | DYLD_CHAINED_IMPORT = 1, |
1028 | DYLD_CHAINED_IMPORT_ADDEND = 2, |
1029 | DYLD_CHAINED_IMPORT_ADDEND64 = 3, |
1030 | }; |
1031 | |
1032 | // Values for dyld_chained_fixups_header::symbols_format. |
1033 | enum { |
1034 | DYLD_CHAINED_SYMBOL_UNCOMPRESSED = 0, |
1035 | DYLD_CHAINED_SYMBOL_ZLIB = 1, |
1036 | }; |
1037 | |
1038 | // Values for dyld_chained_starts_in_segment::page_start. |
1039 | enum { |
1040 | DYLD_CHAINED_PTR_START_NONE = 0xFFFF, |
1041 | DYLD_CHAINED_PTR_START_MULTI = 0x8000, // page which has multiple starts |
1042 | DYLD_CHAINED_PTR_START_LAST = 0x8000, // last chain_start for a given page |
1043 | }; |
1044 | |
1045 | // Values for dyld_chained_starts_in_segment::pointer_format. |
1046 | enum { |
1047 | DYLD_CHAINED_PTR_ARM64E = 1, |
1048 | DYLD_CHAINED_PTR_64 = 2, |
1049 | DYLD_CHAINED_PTR_32 = 3, |
1050 | DYLD_CHAINED_PTR_32_CACHE = 4, |
1051 | DYLD_CHAINED_PTR_32_FIRMWARE = 5, |
1052 | DYLD_CHAINED_PTR_64_OFFSET = 6, |
1053 | DYLD_CHAINED_PTR_ARM64E_KERNEL = 7, |
1054 | DYLD_CHAINED_PTR_64_KERNEL_CACHE = 8, |
1055 | DYLD_CHAINED_PTR_ARM64E_USERLAND = 9, |
1056 | DYLD_CHAINED_PTR_ARM64E_FIRMWARE = 10, |
1057 | DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE = 11, |
1058 | DYLD_CHAINED_PTR_ARM64E_USERLAND24 = 12, |
1059 | }; |
1060 | |
1061 | /// Structs for dyld chained fixups. |
1062 | /// dyld_chained_fixups_header is the data pointed to by LC_DYLD_CHAINED_FIXUPS |
1063 | /// load command. |
1064 | struct { |
1065 | uint32_t ; ///< 0 |
1066 | uint32_t ; ///< Offset of dyld_chained_starts_in_image. |
1067 | uint32_t ; ///< Offset of imports table in chain_data. |
1068 | uint32_t ; ///< Offset of symbol strings in chain_data. |
1069 | uint32_t ; ///< Number of imported symbol names. |
1070 | uint32_t ; ///< DYLD_CHAINED_IMPORT* |
1071 | uint32_t ; ///< 0 => uncompressed, 1 => zlib compressed |
1072 | }; |
1073 | |
1074 | /// dyld_chained_starts_in_image is embedded in LC_DYLD_CHAINED_FIXUPS payload. |
1075 | /// Each seg_info_offset entry is the offset into this struct for that |
1076 | /// segment followed by pool of dyld_chain_starts_in_segment data. |
1077 | struct dyld_chained_starts_in_image { |
1078 | uint32_t seg_count; |
1079 | uint32_t seg_info_offset[1]; |
1080 | }; |
1081 | |
1082 | struct dyld_chained_starts_in_segment { |
1083 | uint32_t size; ///< Size of this, including chain_starts entries |
1084 | uint16_t page_size; ///< Page size in bytes (0x1000 or 0x4000) |
1085 | uint16_t pointer_format; ///< DYLD_CHAINED_PTR* |
1086 | uint64_t segment_offset; ///< VM offset from the __TEXT segment |
1087 | uint32_t max_valid_pointer; ///< Values beyond this are not pointers on 32-bit |
1088 | uint16_t page_count; ///< Length of the page_start array |
1089 | uint16_t page_start[1]; ///< Page offset of first fixup on each page, or |
1090 | ///< DYLD_CHAINED_PTR_START_NONE if no fixups |
1091 | }; |
1092 | |
1093 | // DYLD_CHAINED_IMPORT |
1094 | struct dyld_chained_import { |
1095 | uint32_t lib_ordinal : 8; |
1096 | uint32_t weak_import : 1; |
1097 | uint32_t name_offset : 23; |
1098 | }; |
1099 | |
1100 | // DYLD_CHAINED_IMPORT_ADDEND |
1101 | struct dyld_chained_import_addend { |
1102 | uint32_t lib_ordinal : 8; |
1103 | uint32_t weak_import : 1; |
1104 | uint32_t name_offset : 23; |
1105 | int32_t addend; |
1106 | }; |
1107 | |
1108 | // DYLD_CHAINED_IMPORT_ADDEND64 |
1109 | struct dyld_chained_import_addend64 { |
1110 | uint64_t lib_ordinal : 16; |
1111 | uint64_t weak_import : 1; |
1112 | uint64_t reserved : 15; |
1113 | uint64_t name_offset : 32; |
1114 | uint64_t addend; |
1115 | }; |
1116 | |
1117 | // The `bind` field (most significant bit) of the encoded fixup determines |
1118 | // whether it is dyld_chained_ptr_64_bind or dyld_chained_ptr_64_rebase. |
1119 | |
1120 | // DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET |
1121 | struct dyld_chained_ptr_64_bind { |
1122 | uint64_t ordinal : 24; |
1123 | uint64_t addend : 8; |
1124 | uint64_t reserved : 19; |
1125 | uint64_t next : 12; |
1126 | uint64_t bind : 1; // set to 1 |
1127 | }; |
1128 | |
1129 | // DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET |
1130 | struct dyld_chained_ptr_64_rebase { |
1131 | uint64_t target : 36; |
1132 | uint64_t high8 : 8; |
1133 | uint64_t reserved : 7; |
1134 | uint64_t next : 12; |
1135 | uint64_t bind : 1; // set to 0 |
1136 | }; |
1137 | |
1138 | // Byte order swapping functions for MachO structs |
1139 | |
1140 | inline void (fat_header &mh) { |
1141 | sys::swapByteOrder(Value&: mh.magic); |
1142 | sys::swapByteOrder(Value&: mh.nfat_arch); |
1143 | } |
1144 | |
1145 | inline void swapStruct(fat_arch &mh) { |
1146 | sys::swapByteOrder(Value&: mh.cputype); |
1147 | sys::swapByteOrder(Value&: mh.cpusubtype); |
1148 | sys::swapByteOrder(Value&: mh.offset); |
1149 | sys::swapByteOrder(Value&: mh.size); |
1150 | sys::swapByteOrder(Value&: mh.align); |
1151 | } |
1152 | |
1153 | inline void swapStruct(fat_arch_64 &mh) { |
1154 | sys::swapByteOrder(Value&: mh.cputype); |
1155 | sys::swapByteOrder(Value&: mh.cpusubtype); |
1156 | sys::swapByteOrder(Value&: mh.offset); |
1157 | sys::swapByteOrder(Value&: mh.size); |
1158 | sys::swapByteOrder(Value&: mh.align); |
1159 | sys::swapByteOrder(Value&: mh.reserved); |
1160 | } |
1161 | |
1162 | inline void (mach_header &mh) { |
1163 | sys::swapByteOrder(Value&: mh.magic); |
1164 | sys::swapByteOrder(Value&: mh.cputype); |
1165 | sys::swapByteOrder(Value&: mh.cpusubtype); |
1166 | sys::swapByteOrder(Value&: mh.filetype); |
1167 | sys::swapByteOrder(Value&: mh.ncmds); |
1168 | sys::swapByteOrder(Value&: mh.sizeofcmds); |
1169 | sys::swapByteOrder(Value&: mh.flags); |
1170 | } |
1171 | |
1172 | inline void (mach_header_64 &H) { |
1173 | sys::swapByteOrder(Value&: H.magic); |
1174 | sys::swapByteOrder(Value&: H.cputype); |
1175 | sys::swapByteOrder(Value&: H.cpusubtype); |
1176 | sys::swapByteOrder(Value&: H.filetype); |
1177 | sys::swapByteOrder(Value&: H.ncmds); |
1178 | sys::swapByteOrder(Value&: H.sizeofcmds); |
1179 | sys::swapByteOrder(Value&: H.flags); |
1180 | sys::swapByteOrder(Value&: H.reserved); |
1181 | } |
1182 | |
1183 | inline void swapStruct(load_command &lc) { |
1184 | sys::swapByteOrder(Value&: lc.cmd); |
1185 | sys::swapByteOrder(Value&: lc.cmdsize); |
1186 | } |
1187 | |
1188 | inline void swapStruct(symtab_command &lc) { |
1189 | sys::swapByteOrder(Value&: lc.cmd); |
1190 | sys::swapByteOrder(Value&: lc.cmdsize); |
1191 | sys::swapByteOrder(Value&: lc.symoff); |
1192 | sys::swapByteOrder(Value&: lc.nsyms); |
1193 | sys::swapByteOrder(Value&: lc.stroff); |
1194 | sys::swapByteOrder(Value&: lc.strsize); |
1195 | } |
1196 | |
1197 | inline void swapStruct(segment_command_64 &seg) { |
1198 | sys::swapByteOrder(Value&: seg.cmd); |
1199 | sys::swapByteOrder(Value&: seg.cmdsize); |
1200 | sys::swapByteOrder(Value&: seg.vmaddr); |
1201 | sys::swapByteOrder(Value&: seg.vmsize); |
1202 | sys::swapByteOrder(Value&: seg.fileoff); |
1203 | sys::swapByteOrder(Value&: seg.filesize); |
1204 | sys::swapByteOrder(Value&: seg.maxprot); |
1205 | sys::swapByteOrder(Value&: seg.initprot); |
1206 | sys::swapByteOrder(Value&: seg.nsects); |
1207 | sys::swapByteOrder(Value&: seg.flags); |
1208 | } |
1209 | |
1210 | inline void swapStruct(segment_command &seg) { |
1211 | sys::swapByteOrder(Value&: seg.cmd); |
1212 | sys::swapByteOrder(Value&: seg.cmdsize); |
1213 | sys::swapByteOrder(Value&: seg.vmaddr); |
1214 | sys::swapByteOrder(Value&: seg.vmsize); |
1215 | sys::swapByteOrder(Value&: seg.fileoff); |
1216 | sys::swapByteOrder(Value&: seg.filesize); |
1217 | sys::swapByteOrder(Value&: seg.maxprot); |
1218 | sys::swapByteOrder(Value&: seg.initprot); |
1219 | sys::swapByteOrder(Value&: seg.nsects); |
1220 | sys::swapByteOrder(Value&: seg.flags); |
1221 | } |
1222 | |
1223 | inline void swapStruct(section_64 §) { |
1224 | sys::swapByteOrder(Value&: sect.addr); |
1225 | sys::swapByteOrder(Value&: sect.size); |
1226 | sys::swapByteOrder(Value&: sect.offset); |
1227 | sys::swapByteOrder(Value&: sect.align); |
1228 | sys::swapByteOrder(Value&: sect.reloff); |
1229 | sys::swapByteOrder(Value&: sect.nreloc); |
1230 | sys::swapByteOrder(Value&: sect.flags); |
1231 | sys::swapByteOrder(Value&: sect.reserved1); |
1232 | sys::swapByteOrder(Value&: sect.reserved2); |
1233 | } |
1234 | |
1235 | inline void swapStruct(section §) { |
1236 | sys::swapByteOrder(Value&: sect.addr); |
1237 | sys::swapByteOrder(Value&: sect.size); |
1238 | sys::swapByteOrder(Value&: sect.offset); |
1239 | sys::swapByteOrder(Value&: sect.align); |
1240 | sys::swapByteOrder(Value&: sect.reloff); |
1241 | sys::swapByteOrder(Value&: sect.nreloc); |
1242 | sys::swapByteOrder(Value&: sect.flags); |
1243 | sys::swapByteOrder(Value&: sect.reserved1); |
1244 | sys::swapByteOrder(Value&: sect.reserved2); |
1245 | } |
1246 | |
1247 | inline void swapStruct(dyld_info_command &info) { |
1248 | sys::swapByteOrder(Value&: info.cmd); |
1249 | sys::swapByteOrder(Value&: info.cmdsize); |
1250 | sys::swapByteOrder(Value&: info.rebase_off); |
1251 | sys::swapByteOrder(Value&: info.rebase_size); |
1252 | sys::swapByteOrder(Value&: info.bind_off); |
1253 | sys::swapByteOrder(Value&: info.bind_size); |
1254 | sys::swapByteOrder(Value&: info.weak_bind_off); |
1255 | sys::swapByteOrder(Value&: info.weak_bind_size); |
1256 | sys::swapByteOrder(Value&: info.lazy_bind_off); |
1257 | sys::swapByteOrder(Value&: info.lazy_bind_size); |
1258 | sys::swapByteOrder(Value&: info.export_off); |
1259 | sys::swapByteOrder(Value&: info.export_size); |
1260 | } |
1261 | |
1262 | inline void swapStruct(dylib_command &d) { |
1263 | sys::swapByteOrder(Value&: d.cmd); |
1264 | sys::swapByteOrder(Value&: d.cmdsize); |
1265 | sys::swapByteOrder(Value&: d.dylib.name); |
1266 | sys::swapByteOrder(Value&: d.dylib.timestamp); |
1267 | sys::swapByteOrder(Value&: d.dylib.current_version); |
1268 | sys::swapByteOrder(Value&: d.dylib.compatibility_version); |
1269 | } |
1270 | |
1271 | inline void swapStruct(sub_framework_command &s) { |
1272 | sys::swapByteOrder(Value&: s.cmd); |
1273 | sys::swapByteOrder(Value&: s.cmdsize); |
1274 | sys::swapByteOrder(Value&: s.umbrella); |
1275 | } |
1276 | |
1277 | inline void swapStruct(sub_umbrella_command &s) { |
1278 | sys::swapByteOrder(Value&: s.cmd); |
1279 | sys::swapByteOrder(Value&: s.cmdsize); |
1280 | sys::swapByteOrder(Value&: s.sub_umbrella); |
1281 | } |
1282 | |
1283 | inline void swapStruct(sub_library_command &s) { |
1284 | sys::swapByteOrder(Value&: s.cmd); |
1285 | sys::swapByteOrder(Value&: s.cmdsize); |
1286 | sys::swapByteOrder(Value&: s.sub_library); |
1287 | } |
1288 | |
1289 | inline void swapStruct(sub_client_command &s) { |
1290 | sys::swapByteOrder(Value&: s.cmd); |
1291 | sys::swapByteOrder(Value&: s.cmdsize); |
1292 | sys::swapByteOrder(Value&: s.client); |
1293 | } |
1294 | |
1295 | inline void swapStruct(routines_command &r) { |
1296 | sys::swapByteOrder(Value&: r.cmd); |
1297 | sys::swapByteOrder(Value&: r.cmdsize); |
1298 | sys::swapByteOrder(Value&: r.init_address); |
1299 | sys::swapByteOrder(Value&: r.init_module); |
1300 | sys::swapByteOrder(Value&: r.reserved1); |
1301 | sys::swapByteOrder(Value&: r.reserved2); |
1302 | sys::swapByteOrder(Value&: r.reserved3); |
1303 | sys::swapByteOrder(Value&: r.reserved4); |
1304 | sys::swapByteOrder(Value&: r.reserved5); |
1305 | sys::swapByteOrder(Value&: r.reserved6); |
1306 | } |
1307 | |
1308 | inline void swapStruct(routines_command_64 &r) { |
1309 | sys::swapByteOrder(Value&: r.cmd); |
1310 | sys::swapByteOrder(Value&: r.cmdsize); |
1311 | sys::swapByteOrder(Value&: r.init_address); |
1312 | sys::swapByteOrder(Value&: r.init_module); |
1313 | sys::swapByteOrder(Value&: r.reserved1); |
1314 | sys::swapByteOrder(Value&: r.reserved2); |
1315 | sys::swapByteOrder(Value&: r.reserved3); |
1316 | sys::swapByteOrder(Value&: r.reserved4); |
1317 | sys::swapByteOrder(Value&: r.reserved5); |
1318 | sys::swapByteOrder(Value&: r.reserved6); |
1319 | } |
1320 | |
1321 | inline void swapStruct(thread_command &t) { |
1322 | sys::swapByteOrder(Value&: t.cmd); |
1323 | sys::swapByteOrder(Value&: t.cmdsize); |
1324 | } |
1325 | |
1326 | inline void swapStruct(dylinker_command &d) { |
1327 | sys::swapByteOrder(Value&: d.cmd); |
1328 | sys::swapByteOrder(Value&: d.cmdsize); |
1329 | sys::swapByteOrder(Value&: d.name); |
1330 | } |
1331 | |
1332 | inline void swapStruct(uuid_command &u) { |
1333 | sys::swapByteOrder(Value&: u.cmd); |
1334 | sys::swapByteOrder(Value&: u.cmdsize); |
1335 | } |
1336 | |
1337 | inline void swapStruct(rpath_command &r) { |
1338 | sys::swapByteOrder(Value&: r.cmd); |
1339 | sys::swapByteOrder(Value&: r.cmdsize); |
1340 | sys::swapByteOrder(Value&: r.path); |
1341 | } |
1342 | |
1343 | inline void swapStruct(source_version_command &s) { |
1344 | sys::swapByteOrder(Value&: s.cmd); |
1345 | sys::swapByteOrder(Value&: s.cmdsize); |
1346 | sys::swapByteOrder(Value&: s.version); |
1347 | } |
1348 | |
1349 | inline void swapStruct(entry_point_command &e) { |
1350 | sys::swapByteOrder(Value&: e.cmd); |
1351 | sys::swapByteOrder(Value&: e.cmdsize); |
1352 | sys::swapByteOrder(Value&: e.entryoff); |
1353 | sys::swapByteOrder(Value&: e.stacksize); |
1354 | } |
1355 | |
1356 | inline void swapStruct(encryption_info_command &e) { |
1357 | sys::swapByteOrder(Value&: e.cmd); |
1358 | sys::swapByteOrder(Value&: e.cmdsize); |
1359 | sys::swapByteOrder(Value&: e.cryptoff); |
1360 | sys::swapByteOrder(Value&: e.cryptsize); |
1361 | sys::swapByteOrder(Value&: e.cryptid); |
1362 | } |
1363 | |
1364 | inline void swapStruct(encryption_info_command_64 &e) { |
1365 | sys::swapByteOrder(Value&: e.cmd); |
1366 | sys::swapByteOrder(Value&: e.cmdsize); |
1367 | sys::swapByteOrder(Value&: e.cryptoff); |
1368 | sys::swapByteOrder(Value&: e.cryptsize); |
1369 | sys::swapByteOrder(Value&: e.cryptid); |
1370 | sys::swapByteOrder(Value&: e.pad); |
1371 | } |
1372 | |
1373 | inline void swapStruct(dysymtab_command &dst) { |
1374 | sys::swapByteOrder(Value&: dst.cmd); |
1375 | sys::swapByteOrder(Value&: dst.cmdsize); |
1376 | sys::swapByteOrder(Value&: dst.ilocalsym); |
1377 | sys::swapByteOrder(Value&: dst.nlocalsym); |
1378 | sys::swapByteOrder(Value&: dst.iextdefsym); |
1379 | sys::swapByteOrder(Value&: dst.nextdefsym); |
1380 | sys::swapByteOrder(Value&: dst.iundefsym); |
1381 | sys::swapByteOrder(Value&: dst.nundefsym); |
1382 | sys::swapByteOrder(Value&: dst.tocoff); |
1383 | sys::swapByteOrder(Value&: dst.ntoc); |
1384 | sys::swapByteOrder(Value&: dst.modtaboff); |
1385 | sys::swapByteOrder(Value&: dst.nmodtab); |
1386 | sys::swapByteOrder(Value&: dst.extrefsymoff); |
1387 | sys::swapByteOrder(Value&: dst.nextrefsyms); |
1388 | sys::swapByteOrder(Value&: dst.indirectsymoff); |
1389 | sys::swapByteOrder(Value&: dst.nindirectsyms); |
1390 | sys::swapByteOrder(Value&: dst.extreloff); |
1391 | sys::swapByteOrder(Value&: dst.nextrel); |
1392 | sys::swapByteOrder(Value&: dst.locreloff); |
1393 | sys::swapByteOrder(Value&: dst.nlocrel); |
1394 | } |
1395 | |
1396 | inline void swapStruct(any_relocation_info &reloc) { |
1397 | sys::swapByteOrder(Value&: reloc.r_word0); |
1398 | sys::swapByteOrder(Value&: reloc.r_word1); |
1399 | } |
1400 | |
1401 | inline void swapStruct(nlist_base &S) { |
1402 | sys::swapByteOrder(Value&: S.n_strx); |
1403 | sys::swapByteOrder(Value&: S.n_desc); |
1404 | } |
1405 | |
1406 | inline void swapStruct(nlist &sym) { |
1407 | sys::swapByteOrder(Value&: sym.n_strx); |
1408 | sys::swapByteOrder(Value&: sym.n_desc); |
1409 | sys::swapByteOrder(Value&: sym.n_value); |
1410 | } |
1411 | |
1412 | inline void swapStruct(nlist_64 &sym) { |
1413 | sys::swapByteOrder(Value&: sym.n_strx); |
1414 | sys::swapByteOrder(Value&: sym.n_desc); |
1415 | sys::swapByteOrder(Value&: sym.n_value); |
1416 | } |
1417 | |
1418 | inline void swapStruct(linkedit_data_command &C) { |
1419 | sys::swapByteOrder(Value&: C.cmd); |
1420 | sys::swapByteOrder(Value&: C.cmdsize); |
1421 | sys::swapByteOrder(Value&: C.dataoff); |
1422 | sys::swapByteOrder(Value&: C.datasize); |
1423 | } |
1424 | |
1425 | inline void swapStruct(linker_option_command &C) { |
1426 | sys::swapByteOrder(Value&: C.cmd); |
1427 | sys::swapByteOrder(Value&: C.cmdsize); |
1428 | sys::swapByteOrder(Value&: C.count); |
1429 | } |
1430 | |
1431 | inline void swapStruct(fileset_entry_command &C) { |
1432 | sys::swapByteOrder(Value&: C.cmd); |
1433 | sys::swapByteOrder(Value&: C.cmdsize); |
1434 | sys::swapByteOrder(Value&: C.vmaddr); |
1435 | sys::swapByteOrder(Value&: C.fileoff); |
1436 | sys::swapByteOrder(Value&: C.entry_id.offset); |
1437 | sys::swapByteOrder(Value&: C.reserved); |
1438 | } |
1439 | |
1440 | inline void swapStruct(version_min_command &C) { |
1441 | sys::swapByteOrder(Value&: C.cmd); |
1442 | sys::swapByteOrder(Value&: C.cmdsize); |
1443 | sys::swapByteOrder(Value&: C.version); |
1444 | sys::swapByteOrder(Value&: C.sdk); |
1445 | } |
1446 | |
1447 | inline void swapStruct(note_command &C) { |
1448 | sys::swapByteOrder(Value&: C.cmd); |
1449 | sys::swapByteOrder(Value&: C.cmdsize); |
1450 | sys::swapByteOrder(Value&: C.offset); |
1451 | sys::swapByteOrder(Value&: C.size); |
1452 | } |
1453 | |
1454 | inline void swapStruct(build_version_command &C) { |
1455 | sys::swapByteOrder(Value&: C.cmd); |
1456 | sys::swapByteOrder(Value&: C.cmdsize); |
1457 | sys::swapByteOrder(Value&: C.platform); |
1458 | sys::swapByteOrder(Value&: C.minos); |
1459 | sys::swapByteOrder(Value&: C.sdk); |
1460 | sys::swapByteOrder(Value&: C.ntools); |
1461 | } |
1462 | |
1463 | inline void swapStruct(build_tool_version &C) { |
1464 | sys::swapByteOrder(Value&: C.tool); |
1465 | sys::swapByteOrder(Value&: C.version); |
1466 | } |
1467 | |
1468 | inline void swapStruct(data_in_code_entry &C) { |
1469 | sys::swapByteOrder(Value&: C.offset); |
1470 | sys::swapByteOrder(Value&: C.length); |
1471 | sys::swapByteOrder(Value&: C.kind); |
1472 | } |
1473 | |
1474 | inline void swapStruct(uint32_t &C) { sys::swapByteOrder(Value&: C); } |
1475 | |
1476 | // The prebind_cksum_command is obsolete and no longer supported. |
1477 | inline void swapStruct(prebind_cksum_command &C) { |
1478 | sys::swapByteOrder(Value&: C.cmd); |
1479 | sys::swapByteOrder(Value&: C.cmdsize); |
1480 | sys::swapByteOrder(Value&: C.cksum); |
1481 | } |
1482 | |
1483 | // The twolevel_hints_command is obsolete and no longer supported. |
1484 | inline void swapStruct(twolevel_hints_command &C) { |
1485 | sys::swapByteOrder(Value&: C.cmd); |
1486 | sys::swapByteOrder(Value&: C.cmdsize); |
1487 | sys::swapByteOrder(Value&: C.offset); |
1488 | sys::swapByteOrder(Value&: C.nhints); |
1489 | } |
1490 | |
1491 | // The prebound_dylib_command is obsolete and no longer supported. |
1492 | inline void swapStruct(prebound_dylib_command &C) { |
1493 | sys::swapByteOrder(Value&: C.cmd); |
1494 | sys::swapByteOrder(Value&: C.cmdsize); |
1495 | sys::swapByteOrder(Value&: C.name); |
1496 | sys::swapByteOrder(Value&: C.nmodules); |
1497 | sys::swapByteOrder(Value&: C.linked_modules); |
1498 | } |
1499 | |
1500 | // The fvmfile_command is obsolete and no longer supported. |
1501 | inline void swapStruct(fvmfile_command &C) { |
1502 | sys::swapByteOrder(Value&: C.cmd); |
1503 | sys::swapByteOrder(Value&: C.cmdsize); |
1504 | sys::swapByteOrder(Value&: C.name); |
1505 | sys::swapByteOrder(Value&: C.header_addr); |
1506 | } |
1507 | |
1508 | // The symseg_command is obsolete and no longer supported. |
1509 | inline void swapStruct(symseg_command &C) { |
1510 | sys::swapByteOrder(Value&: C.cmd); |
1511 | sys::swapByteOrder(Value&: C.cmdsize); |
1512 | sys::swapByteOrder(Value&: C.offset); |
1513 | sys::swapByteOrder(Value&: C.size); |
1514 | } |
1515 | |
1516 | // The ident_command is obsolete and no longer supported. |
1517 | inline void swapStruct(ident_command &C) { |
1518 | sys::swapByteOrder(Value&: C.cmd); |
1519 | sys::swapByteOrder(Value&: C.cmdsize); |
1520 | } |
1521 | |
1522 | inline void swapStruct(fvmlib &C) { |
1523 | sys::swapByteOrder(Value&: C.name); |
1524 | sys::swapByteOrder(Value&: C.minor_version); |
1525 | sys::swapByteOrder(Value&: C.header_addr); |
1526 | } |
1527 | |
1528 | // The fvmlib_command is obsolete and no longer supported. |
1529 | inline void swapStruct(fvmlib_command &C) { |
1530 | sys::swapByteOrder(Value&: C.cmd); |
1531 | sys::swapByteOrder(Value&: C.cmdsize); |
1532 | swapStruct(C&: C.fvmlib); |
1533 | } |
1534 | |
1535 | // Get/Set functions from <mach-o/nlist.h> |
1536 | |
1537 | inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) { |
1538 | return (((n_desc) >> 8u) & 0xffu); |
1539 | } |
1540 | |
1541 | inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) { |
1542 | n_desc = (((n_desc)&0x00ff) | (((ordinal)&0xff) << 8)); |
1543 | } |
1544 | |
1545 | inline uint8_t GET_COMM_ALIGN(uint16_t n_desc) { |
1546 | return (n_desc >> 8u) & 0x0fu; |
1547 | } |
1548 | |
1549 | inline void SET_COMM_ALIGN(uint16_t &n_desc, uint8_t align) { |
1550 | n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u)); |
1551 | } |
1552 | |
1553 | // Enums from <mach/machine.h> |
1554 | enum : uint32_t { |
1555 | // Capability bits used in the definition of cpu_type. |
1556 | CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits |
1557 | CPU_ARCH_ABI64 = 0x01000000, // 64 bit ABI |
1558 | CPU_ARCH_ABI64_32 = 0x02000000, // ILP32 ABI on 64-bit hardware |
1559 | }; |
1560 | |
1561 | // Constants for the cputype field. |
1562 | enum CPUType { |
1563 | CPU_TYPE_ANY = -1, |
1564 | CPU_TYPE_X86 = 7, |
1565 | CPU_TYPE_I386 = CPU_TYPE_X86, |
1566 | CPU_TYPE_X86_64 = CPU_TYPE_X86 | CPU_ARCH_ABI64, |
1567 | /* CPU_TYPE_MIPS = 8, */ |
1568 | CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC |
1569 | CPU_TYPE_ARM = 12, |
1570 | CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64, |
1571 | CPU_TYPE_ARM64_32 = CPU_TYPE_ARM | CPU_ARCH_ABI64_32, |
1572 | CPU_TYPE_SPARC = 14, |
1573 | CPU_TYPE_POWERPC = 18, |
1574 | CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64 |
1575 | }; |
1576 | |
1577 | enum : uint32_t { |
1578 | // Capability bits used in the definition of cpusubtype. |
1579 | CPU_SUBTYPE_MASK = 0xff000000, // Mask for architecture bits |
1580 | CPU_SUBTYPE_LIB64 = 0x80000000, // 64 bit libraries |
1581 | |
1582 | // Special CPU subtype constants. |
1583 | CPU_SUBTYPE_MULTIPLE = ~0u |
1584 | }; |
1585 | |
1586 | // Constants for the cpusubtype field. |
1587 | enum CPUSubTypeX86 { |
1588 | CPU_SUBTYPE_I386_ALL = 3, |
1589 | CPU_SUBTYPE_386 = 3, |
1590 | CPU_SUBTYPE_486 = 4, |
1591 | CPU_SUBTYPE_486SX = 0x84, |
1592 | CPU_SUBTYPE_586 = 5, |
1593 | CPU_SUBTYPE_PENT = CPU_SUBTYPE_586, |
1594 | CPU_SUBTYPE_PENTPRO = 0x16, |
1595 | CPU_SUBTYPE_PENTII_M3 = 0x36, |
1596 | CPU_SUBTYPE_PENTII_M5 = 0x56, |
1597 | CPU_SUBTYPE_CELERON = 0x67, |
1598 | CPU_SUBTYPE_CELERON_MOBILE = 0x77, |
1599 | CPU_SUBTYPE_PENTIUM_3 = 0x08, |
1600 | CPU_SUBTYPE_PENTIUM_3_M = 0x18, |
1601 | CPU_SUBTYPE_PENTIUM_3_XEON = 0x28, |
1602 | CPU_SUBTYPE_PENTIUM_M = 0x09, |
1603 | CPU_SUBTYPE_PENTIUM_4 = 0x0a, |
1604 | CPU_SUBTYPE_PENTIUM_4_M = 0x1a, |
1605 | CPU_SUBTYPE_ITANIUM = 0x0b, |
1606 | CPU_SUBTYPE_ITANIUM_2 = 0x1b, |
1607 | CPU_SUBTYPE_XEON = 0x0c, |
1608 | CPU_SUBTYPE_XEON_MP = 0x1c, |
1609 | |
1610 | CPU_SUBTYPE_X86_ALL = 3, |
1611 | CPU_SUBTYPE_X86_64_ALL = 3, |
1612 | CPU_SUBTYPE_X86_ARCH1 = 4, |
1613 | CPU_SUBTYPE_X86_64_H = 8 |
1614 | }; |
1615 | inline int CPU_SUBTYPE_INTEL(int Family, int Model) { |
1616 | return Family | (Model << 4); |
1617 | } |
1618 | inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) { |
1619 | return ((int)ST) & 0x0f; |
1620 | } |
1621 | inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) { return ((int)ST) >> 4; } |
1622 | enum { CPU_SUBTYPE_INTEL_FAMILY_MAX = 15, CPU_SUBTYPE_INTEL_MODEL_ALL = 0 }; |
1623 | |
1624 | enum CPUSubTypeARM { |
1625 | CPU_SUBTYPE_ARM_ALL = 0, |
1626 | CPU_SUBTYPE_ARM_V4T = 5, |
1627 | CPU_SUBTYPE_ARM_V6 = 6, |
1628 | CPU_SUBTYPE_ARM_V5 = 7, |
1629 | CPU_SUBTYPE_ARM_V5TEJ = 7, |
1630 | CPU_SUBTYPE_ARM_XSCALE = 8, |
1631 | CPU_SUBTYPE_ARM_V7 = 9, |
1632 | // unused ARM_V7F = 10, |
1633 | CPU_SUBTYPE_ARM_V7S = 11, |
1634 | CPU_SUBTYPE_ARM_V7K = 12, |
1635 | CPU_SUBTYPE_ARM_V6M = 14, |
1636 | CPU_SUBTYPE_ARM_V7M = 15, |
1637 | CPU_SUBTYPE_ARM_V7EM = 16 |
1638 | }; |
1639 | |
1640 | enum CPUSubTypeARM64 { |
1641 | CPU_SUBTYPE_ARM64_ALL = 0, |
1642 | CPU_SUBTYPE_ARM64_V8 = 1, |
1643 | CPU_SUBTYPE_ARM64E = 2, |
1644 | }; |
1645 | |
1646 | enum CPUSubTypeARM64_32 { CPU_SUBTYPE_ARM64_32_V8 = 1 }; |
1647 | |
1648 | enum CPUSubTypeSPARC { CPU_SUBTYPE_SPARC_ALL = 0 }; |
1649 | |
1650 | enum CPUSubTypePowerPC { |
1651 | CPU_SUBTYPE_POWERPC_ALL = 0, |
1652 | CPU_SUBTYPE_POWERPC_601 = 1, |
1653 | CPU_SUBTYPE_POWERPC_602 = 2, |
1654 | CPU_SUBTYPE_POWERPC_603 = 3, |
1655 | CPU_SUBTYPE_POWERPC_603e = 4, |
1656 | CPU_SUBTYPE_POWERPC_603ev = 5, |
1657 | CPU_SUBTYPE_POWERPC_604 = 6, |
1658 | CPU_SUBTYPE_POWERPC_604e = 7, |
1659 | CPU_SUBTYPE_POWERPC_620 = 8, |
1660 | CPU_SUBTYPE_POWERPC_750 = 9, |
1661 | CPU_SUBTYPE_POWERPC_7400 = 10, |
1662 | CPU_SUBTYPE_POWERPC_7450 = 11, |
1663 | CPU_SUBTYPE_POWERPC_970 = 100, |
1664 | |
1665 | CPU_SUBTYPE_MC980000_ALL = CPU_SUBTYPE_POWERPC_ALL, |
1666 | CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601 |
1667 | }; |
1668 | |
1669 | Expected<uint32_t> getCPUType(const Triple &T); |
1670 | Expected<uint32_t> getCPUSubType(const Triple &T); |
1671 | |
1672 | struct x86_thread_state32_t { |
1673 | uint32_t eax; |
1674 | uint32_t ebx; |
1675 | uint32_t ecx; |
1676 | uint32_t edx; |
1677 | uint32_t edi; |
1678 | uint32_t esi; |
1679 | uint32_t ebp; |
1680 | uint32_t esp; |
1681 | uint32_t ss; |
1682 | uint32_t eflags; |
1683 | uint32_t eip; |
1684 | uint32_t cs; |
1685 | uint32_t ds; |
1686 | uint32_t es; |
1687 | uint32_t fs; |
1688 | uint32_t gs; |
1689 | }; |
1690 | |
1691 | struct x86_thread_state64_t { |
1692 | uint64_t rax; |
1693 | uint64_t rbx; |
1694 | uint64_t rcx; |
1695 | uint64_t rdx; |
1696 | uint64_t rdi; |
1697 | uint64_t rsi; |
1698 | uint64_t rbp; |
1699 | uint64_t rsp; |
1700 | uint64_t r8; |
1701 | uint64_t r9; |
1702 | uint64_t r10; |
1703 | uint64_t r11; |
1704 | uint64_t r12; |
1705 | uint64_t r13; |
1706 | uint64_t r14; |
1707 | uint64_t r15; |
1708 | uint64_t rip; |
1709 | uint64_t rflags; |
1710 | uint64_t cs; |
1711 | uint64_t fs; |
1712 | uint64_t gs; |
1713 | }; |
1714 | |
1715 | enum x86_fp_control_precis { |
1716 | x86_FP_PREC_24B = 0, |
1717 | x86_FP_PREC_53B = 2, |
1718 | x86_FP_PREC_64B = 3 |
1719 | }; |
1720 | |
1721 | enum x86_fp_control_rc { |
1722 | x86_FP_RND_NEAR = 0, |
1723 | x86_FP_RND_DOWN = 1, |
1724 | x86_FP_RND_UP = 2, |
1725 | x86_FP_CHOP = 3 |
1726 | }; |
1727 | |
1728 | struct fp_control_t { |
1729 | unsigned short invalid : 1, denorm : 1, zdiv : 1, ovrfl : 1, undfl : 1, |
1730 | precis : 1, : 2, pc : 2, rc : 2, : 1, : 3; |
1731 | }; |
1732 | |
1733 | struct fp_status_t { |
1734 | unsigned short invalid : 1, denorm : 1, zdiv : 1, ovrfl : 1, undfl : 1, |
1735 | precis : 1, stkflt : 1, errsumm : 1, c0 : 1, c1 : 1, c2 : 1, tos : 3, |
1736 | c3 : 1, busy : 1; |
1737 | }; |
1738 | |
1739 | struct mmst_reg_t { |
1740 | char mmst_reg[10]; |
1741 | char mmst_rsrv[6]; |
1742 | }; |
1743 | |
1744 | struct xmm_reg_t { |
1745 | char xmm_reg[16]; |
1746 | }; |
1747 | |
1748 | struct x86_float_state64_t { |
1749 | int32_t fpu_reserved[2]; |
1750 | fp_control_t fpu_fcw; |
1751 | fp_status_t fpu_fsw; |
1752 | uint8_t fpu_ftw; |
1753 | uint8_t fpu_rsrv1; |
1754 | uint16_t fpu_fop; |
1755 | uint32_t fpu_ip; |
1756 | uint16_t fpu_cs; |
1757 | uint16_t fpu_rsrv2; |
1758 | uint32_t fpu_dp; |
1759 | uint16_t fpu_ds; |
1760 | uint16_t fpu_rsrv3; |
1761 | uint32_t fpu_mxcsr; |
1762 | uint32_t fpu_mxcsrmask; |
1763 | mmst_reg_t fpu_stmm0; |
1764 | mmst_reg_t fpu_stmm1; |
1765 | mmst_reg_t fpu_stmm2; |
1766 | mmst_reg_t fpu_stmm3; |
1767 | mmst_reg_t fpu_stmm4; |
1768 | mmst_reg_t fpu_stmm5; |
1769 | mmst_reg_t fpu_stmm6; |
1770 | mmst_reg_t fpu_stmm7; |
1771 | xmm_reg_t fpu_xmm0; |
1772 | xmm_reg_t fpu_xmm1; |
1773 | xmm_reg_t fpu_xmm2; |
1774 | xmm_reg_t fpu_xmm3; |
1775 | xmm_reg_t fpu_xmm4; |
1776 | xmm_reg_t fpu_xmm5; |
1777 | xmm_reg_t fpu_xmm6; |
1778 | xmm_reg_t fpu_xmm7; |
1779 | xmm_reg_t fpu_xmm8; |
1780 | xmm_reg_t fpu_xmm9; |
1781 | xmm_reg_t fpu_xmm10; |
1782 | xmm_reg_t fpu_xmm11; |
1783 | xmm_reg_t fpu_xmm12; |
1784 | xmm_reg_t fpu_xmm13; |
1785 | xmm_reg_t fpu_xmm14; |
1786 | xmm_reg_t fpu_xmm15; |
1787 | char fpu_rsrv4[6 * 16]; |
1788 | uint32_t fpu_reserved1; |
1789 | }; |
1790 | |
1791 | struct x86_exception_state64_t { |
1792 | uint16_t trapno; |
1793 | uint16_t cpu; |
1794 | uint32_t err; |
1795 | uint64_t faultvaddr; |
1796 | }; |
1797 | |
1798 | inline void swapStruct(x86_thread_state32_t &x) { |
1799 | sys::swapByteOrder(Value&: x.eax); |
1800 | sys::swapByteOrder(Value&: x.ebx); |
1801 | sys::swapByteOrder(Value&: x.ecx); |
1802 | sys::swapByteOrder(Value&: x.edx); |
1803 | sys::swapByteOrder(Value&: x.edi); |
1804 | sys::swapByteOrder(Value&: x.esi); |
1805 | sys::swapByteOrder(Value&: x.ebp); |
1806 | sys::swapByteOrder(Value&: x.esp); |
1807 | sys::swapByteOrder(Value&: x.ss); |
1808 | sys::swapByteOrder(Value&: x.eflags); |
1809 | sys::swapByteOrder(Value&: x.eip); |
1810 | sys::swapByteOrder(Value&: x.cs); |
1811 | sys::swapByteOrder(Value&: x.ds); |
1812 | sys::swapByteOrder(Value&: x.es); |
1813 | sys::swapByteOrder(Value&: x.fs); |
1814 | sys::swapByteOrder(Value&: x.gs); |
1815 | } |
1816 | |
1817 | inline void swapStruct(x86_thread_state64_t &x) { |
1818 | sys::swapByteOrder(Value&: x.rax); |
1819 | sys::swapByteOrder(Value&: x.rbx); |
1820 | sys::swapByteOrder(Value&: x.rcx); |
1821 | sys::swapByteOrder(Value&: x.rdx); |
1822 | sys::swapByteOrder(Value&: x.rdi); |
1823 | sys::swapByteOrder(Value&: x.rsi); |
1824 | sys::swapByteOrder(Value&: x.rbp); |
1825 | sys::swapByteOrder(Value&: x.rsp); |
1826 | sys::swapByteOrder(Value&: x.r8); |
1827 | sys::swapByteOrder(Value&: x.r9); |
1828 | sys::swapByteOrder(Value&: x.r10); |
1829 | sys::swapByteOrder(Value&: x.r11); |
1830 | sys::swapByteOrder(Value&: x.r12); |
1831 | sys::swapByteOrder(Value&: x.r13); |
1832 | sys::swapByteOrder(Value&: x.r14); |
1833 | sys::swapByteOrder(Value&: x.r15); |
1834 | sys::swapByteOrder(Value&: x.rip); |
1835 | sys::swapByteOrder(Value&: x.rflags); |
1836 | sys::swapByteOrder(Value&: x.cs); |
1837 | sys::swapByteOrder(Value&: x.fs); |
1838 | sys::swapByteOrder(Value&: x.gs); |
1839 | } |
1840 | |
1841 | inline void swapStruct(x86_float_state64_t &x) { |
1842 | sys::swapByteOrder(Value&: x.fpu_reserved[0]); |
1843 | sys::swapByteOrder(Value&: x.fpu_reserved[1]); |
1844 | // TODO swap: fp_control_t fpu_fcw; |
1845 | // TODO swap: fp_status_t fpu_fsw; |
1846 | sys::swapByteOrder(Value&: x.fpu_fop); |
1847 | sys::swapByteOrder(Value&: x.fpu_ip); |
1848 | sys::swapByteOrder(Value&: x.fpu_cs); |
1849 | sys::swapByteOrder(Value&: x.fpu_rsrv2); |
1850 | sys::swapByteOrder(Value&: x.fpu_dp); |
1851 | sys::swapByteOrder(Value&: x.fpu_ds); |
1852 | sys::swapByteOrder(Value&: x.fpu_rsrv3); |
1853 | sys::swapByteOrder(Value&: x.fpu_mxcsr); |
1854 | sys::swapByteOrder(Value&: x.fpu_mxcsrmask); |
1855 | sys::swapByteOrder(Value&: x.fpu_reserved1); |
1856 | } |
1857 | |
1858 | inline void swapStruct(x86_exception_state64_t &x) { |
1859 | sys::swapByteOrder(Value&: x.trapno); |
1860 | sys::swapByteOrder(Value&: x.cpu); |
1861 | sys::swapByteOrder(Value&: x.err); |
1862 | sys::swapByteOrder(Value&: x.faultvaddr); |
1863 | } |
1864 | |
1865 | struct x86_state_hdr_t { |
1866 | uint32_t flavor; |
1867 | uint32_t count; |
1868 | }; |
1869 | |
1870 | struct x86_thread_state_t { |
1871 | x86_state_hdr_t tsh; |
1872 | union { |
1873 | x86_thread_state64_t ts64; |
1874 | x86_thread_state32_t ts32; |
1875 | } uts; |
1876 | }; |
1877 | |
1878 | struct x86_float_state_t { |
1879 | x86_state_hdr_t fsh; |
1880 | union { |
1881 | x86_float_state64_t fs64; |
1882 | } ufs; |
1883 | }; |
1884 | |
1885 | struct x86_exception_state_t { |
1886 | x86_state_hdr_t esh; |
1887 | union { |
1888 | x86_exception_state64_t es64; |
1889 | } ues; |
1890 | }; |
1891 | |
1892 | inline void swapStruct(x86_state_hdr_t &x) { |
1893 | sys::swapByteOrder(Value&: x.flavor); |
1894 | sys::swapByteOrder(Value&: x.count); |
1895 | } |
1896 | |
1897 | enum X86ThreadFlavors { |
1898 | x86_THREAD_STATE32 = 1, |
1899 | x86_FLOAT_STATE32 = 2, |
1900 | x86_EXCEPTION_STATE32 = 3, |
1901 | x86_THREAD_STATE64 = 4, |
1902 | x86_FLOAT_STATE64 = 5, |
1903 | x86_EXCEPTION_STATE64 = 6, |
1904 | x86_THREAD_STATE = 7, |
1905 | x86_FLOAT_STATE = 8, |
1906 | x86_EXCEPTION_STATE = 9, |
1907 | x86_DEBUG_STATE32 = 10, |
1908 | x86_DEBUG_STATE64 = 11, |
1909 | x86_DEBUG_STATE = 12 |
1910 | }; |
1911 | |
1912 | inline void swapStruct(x86_thread_state_t &x) { |
1913 | swapStruct(x&: x.tsh); |
1914 | if (x.tsh.flavor == x86_THREAD_STATE64) |
1915 | swapStruct(x&: x.uts.ts64); |
1916 | } |
1917 | |
1918 | inline void swapStruct(x86_float_state_t &x) { |
1919 | swapStruct(x&: x.fsh); |
1920 | if (x.fsh.flavor == x86_FLOAT_STATE64) |
1921 | swapStruct(x&: x.ufs.fs64); |
1922 | } |
1923 | |
1924 | inline void swapStruct(x86_exception_state_t &x) { |
1925 | swapStruct(x&: x.esh); |
1926 | if (x.esh.flavor == x86_EXCEPTION_STATE64) |
1927 | swapStruct(x&: x.ues.es64); |
1928 | } |
1929 | |
1930 | const uint32_t x86_THREAD_STATE32_COUNT = |
1931 | sizeof(x86_thread_state32_t) / sizeof(uint32_t); |
1932 | |
1933 | const uint32_t x86_THREAD_STATE64_COUNT = |
1934 | sizeof(x86_thread_state64_t) / sizeof(uint32_t); |
1935 | const uint32_t x86_FLOAT_STATE64_COUNT = |
1936 | sizeof(x86_float_state64_t) / sizeof(uint32_t); |
1937 | const uint32_t x86_EXCEPTION_STATE64_COUNT = |
1938 | sizeof(x86_exception_state64_t) / sizeof(uint32_t); |
1939 | |
1940 | const uint32_t x86_THREAD_STATE_COUNT = |
1941 | sizeof(x86_thread_state_t) / sizeof(uint32_t); |
1942 | const uint32_t x86_FLOAT_STATE_COUNT = |
1943 | sizeof(x86_float_state_t) / sizeof(uint32_t); |
1944 | const uint32_t x86_EXCEPTION_STATE_COUNT = |
1945 | sizeof(x86_exception_state_t) / sizeof(uint32_t); |
1946 | |
1947 | struct arm_thread_state32_t { |
1948 | uint32_t r[13]; |
1949 | uint32_t sp; |
1950 | uint32_t lr; |
1951 | uint32_t pc; |
1952 | uint32_t cpsr; |
1953 | }; |
1954 | |
1955 | inline void swapStruct(arm_thread_state32_t &x) { |
1956 | for (int i = 0; i < 13; i++) |
1957 | sys::swapByteOrder(Value&: x.r[i]); |
1958 | sys::swapByteOrder(Value&: x.sp); |
1959 | sys::swapByteOrder(Value&: x.lr); |
1960 | sys::swapByteOrder(Value&: x.pc); |
1961 | sys::swapByteOrder(Value&: x.cpsr); |
1962 | } |
1963 | |
1964 | struct arm_thread_state64_t { |
1965 | uint64_t x[29]; |
1966 | uint64_t fp; |
1967 | uint64_t lr; |
1968 | uint64_t sp; |
1969 | uint64_t pc; |
1970 | uint32_t cpsr; |
1971 | uint32_t pad; |
1972 | }; |
1973 | |
1974 | inline void swapStruct(arm_thread_state64_t &x) { |
1975 | for (int i = 0; i < 29; i++) |
1976 | sys::swapByteOrder(Value&: x.x[i]); |
1977 | sys::swapByteOrder(Value&: x.fp); |
1978 | sys::swapByteOrder(Value&: x.lr); |
1979 | sys::swapByteOrder(Value&: x.sp); |
1980 | sys::swapByteOrder(Value&: x.pc); |
1981 | sys::swapByteOrder(Value&: x.cpsr); |
1982 | } |
1983 | |
1984 | struct arm_state_hdr_t { |
1985 | uint32_t flavor; |
1986 | uint32_t count; |
1987 | }; |
1988 | |
1989 | struct arm_thread_state_t { |
1990 | arm_state_hdr_t tsh; |
1991 | union { |
1992 | arm_thread_state32_t ts32; |
1993 | } uts; |
1994 | }; |
1995 | |
1996 | inline void swapStruct(arm_state_hdr_t &x) { |
1997 | sys::swapByteOrder(Value&: x.flavor); |
1998 | sys::swapByteOrder(Value&: x.count); |
1999 | } |
2000 | |
2001 | enum ARMThreadFlavors { |
2002 | ARM_THREAD_STATE = 1, |
2003 | ARM_VFP_STATE = 2, |
2004 | ARM_EXCEPTION_STATE = 3, |
2005 | ARM_DEBUG_STATE = 4, |
2006 | ARN_THREAD_STATE_NONE = 5, |
2007 | ARM_THREAD_STATE64 = 6, |
2008 | ARM_EXCEPTION_STATE64 = 7 |
2009 | }; |
2010 | |
2011 | inline void swapStruct(arm_thread_state_t &x) { |
2012 | swapStruct(x&: x.tsh); |
2013 | if (x.tsh.flavor == ARM_THREAD_STATE) |
2014 | swapStruct(x&: x.uts.ts32); |
2015 | } |
2016 | |
2017 | const uint32_t ARM_THREAD_STATE_COUNT = |
2018 | sizeof(arm_thread_state32_t) / sizeof(uint32_t); |
2019 | |
2020 | const uint32_t ARM_THREAD_STATE64_COUNT = |
2021 | sizeof(arm_thread_state64_t) / sizeof(uint32_t); |
2022 | |
2023 | struct ppc_thread_state32_t { |
2024 | uint32_t srr0; |
2025 | uint32_t srr1; |
2026 | uint32_t r0; |
2027 | uint32_t r1; |
2028 | uint32_t r2; |
2029 | uint32_t r3; |
2030 | uint32_t r4; |
2031 | uint32_t r5; |
2032 | uint32_t r6; |
2033 | uint32_t r7; |
2034 | uint32_t r8; |
2035 | uint32_t r9; |
2036 | uint32_t r10; |
2037 | uint32_t r11; |
2038 | uint32_t r12; |
2039 | uint32_t r13; |
2040 | uint32_t r14; |
2041 | uint32_t r15; |
2042 | uint32_t r16; |
2043 | uint32_t r17; |
2044 | uint32_t r18; |
2045 | uint32_t r19; |
2046 | uint32_t r20; |
2047 | uint32_t r21; |
2048 | uint32_t r22; |
2049 | uint32_t r23; |
2050 | uint32_t r24; |
2051 | uint32_t r25; |
2052 | uint32_t r26; |
2053 | uint32_t r27; |
2054 | uint32_t r28; |
2055 | uint32_t r29; |
2056 | uint32_t r30; |
2057 | uint32_t r31; |
2058 | uint32_t ct; |
2059 | uint32_t xer; |
2060 | uint32_t lr; |
2061 | uint32_t ctr; |
2062 | uint32_t mq; |
2063 | uint32_t vrsave; |
2064 | }; |
2065 | |
2066 | inline void swapStruct(ppc_thread_state32_t &x) { |
2067 | sys::swapByteOrder(Value&: x.srr0); |
2068 | sys::swapByteOrder(Value&: x.srr1); |
2069 | sys::swapByteOrder(Value&: x.r0); |
2070 | sys::swapByteOrder(Value&: x.r1); |
2071 | sys::swapByteOrder(Value&: x.r2); |
2072 | sys::swapByteOrder(Value&: x.r3); |
2073 | sys::swapByteOrder(Value&: x.r4); |
2074 | sys::swapByteOrder(Value&: x.r5); |
2075 | sys::swapByteOrder(Value&: x.r6); |
2076 | sys::swapByteOrder(Value&: x.r7); |
2077 | sys::swapByteOrder(Value&: x.r8); |
2078 | sys::swapByteOrder(Value&: x.r9); |
2079 | sys::swapByteOrder(Value&: x.r10); |
2080 | sys::swapByteOrder(Value&: x.r11); |
2081 | sys::swapByteOrder(Value&: x.r12); |
2082 | sys::swapByteOrder(Value&: x.r13); |
2083 | sys::swapByteOrder(Value&: x.r14); |
2084 | sys::swapByteOrder(Value&: x.r15); |
2085 | sys::swapByteOrder(Value&: x.r16); |
2086 | sys::swapByteOrder(Value&: x.r17); |
2087 | sys::swapByteOrder(Value&: x.r18); |
2088 | sys::swapByteOrder(Value&: x.r19); |
2089 | sys::swapByteOrder(Value&: x.r20); |
2090 | sys::swapByteOrder(Value&: x.r21); |
2091 | sys::swapByteOrder(Value&: x.r22); |
2092 | sys::swapByteOrder(Value&: x.r23); |
2093 | sys::swapByteOrder(Value&: x.r24); |
2094 | sys::swapByteOrder(Value&: x.r25); |
2095 | sys::swapByteOrder(Value&: x.r26); |
2096 | sys::swapByteOrder(Value&: x.r27); |
2097 | sys::swapByteOrder(Value&: x.r28); |
2098 | sys::swapByteOrder(Value&: x.r29); |
2099 | sys::swapByteOrder(Value&: x.r30); |
2100 | sys::swapByteOrder(Value&: x.r31); |
2101 | sys::swapByteOrder(Value&: x.ct); |
2102 | sys::swapByteOrder(Value&: x.xer); |
2103 | sys::swapByteOrder(Value&: x.lr); |
2104 | sys::swapByteOrder(Value&: x.ctr); |
2105 | sys::swapByteOrder(Value&: x.mq); |
2106 | sys::swapByteOrder(Value&: x.vrsave); |
2107 | } |
2108 | |
2109 | struct ppc_state_hdr_t { |
2110 | uint32_t flavor; |
2111 | uint32_t count; |
2112 | }; |
2113 | |
2114 | struct ppc_thread_state_t { |
2115 | ppc_state_hdr_t tsh; |
2116 | union { |
2117 | ppc_thread_state32_t ts32; |
2118 | } uts; |
2119 | }; |
2120 | |
2121 | inline void swapStruct(ppc_state_hdr_t &x) { |
2122 | sys::swapByteOrder(Value&: x.flavor); |
2123 | sys::swapByteOrder(Value&: x.count); |
2124 | } |
2125 | |
2126 | enum PPCThreadFlavors { |
2127 | PPC_THREAD_STATE = 1, |
2128 | PPC_FLOAT_STATE = 2, |
2129 | PPC_EXCEPTION_STATE = 3, |
2130 | PPC_VECTOR_STATE = 4, |
2131 | PPC_THREAD_STATE64 = 5, |
2132 | PPC_EXCEPTION_STATE64 = 6, |
2133 | PPC_THREAD_STATE_NONE = 7 |
2134 | }; |
2135 | |
2136 | inline void swapStruct(ppc_thread_state_t &x) { |
2137 | swapStruct(x&: x.tsh); |
2138 | if (x.tsh.flavor == PPC_THREAD_STATE) |
2139 | swapStruct(x&: x.uts.ts32); |
2140 | } |
2141 | |
2142 | const uint32_t PPC_THREAD_STATE_COUNT = |
2143 | sizeof(ppc_thread_state32_t) / sizeof(uint32_t); |
2144 | |
2145 | // Define a union of all load command structs |
2146 | #define LOAD_COMMAND_STRUCT(LCStruct) LCStruct LCStruct##_data; |
2147 | |
2148 | LLVM_PACKED_START |
2149 | union alignas(4) macho_load_command { |
2150 | #include "llvm/BinaryFormat/MachO.def" |
2151 | }; |
2152 | LLVM_PACKED_END |
2153 | |
2154 | inline void (dyld_chained_fixups_header &C) { |
2155 | sys::swapByteOrder(Value&: C.fixups_version); |
2156 | sys::swapByteOrder(Value&: C.starts_offset); |
2157 | sys::swapByteOrder(Value&: C.imports_offset); |
2158 | sys::swapByteOrder(Value&: C.symbols_offset); |
2159 | sys::swapByteOrder(Value&: C.imports_count); |
2160 | sys::swapByteOrder(Value&: C.imports_format); |
2161 | sys::swapByteOrder(Value&: C.symbols_format); |
2162 | } |
2163 | |
2164 | inline void swapStruct(dyld_chained_starts_in_image &C) { |
2165 | sys::swapByteOrder(Value&: C.seg_count); |
2166 | // getStructOrErr() cannot copy the variable-length seg_info_offset array. |
2167 | // Its elements must be byte swapped manually. |
2168 | } |
2169 | |
2170 | inline void swapStruct(dyld_chained_starts_in_segment &C) { |
2171 | sys::swapByteOrder(Value&: C.size); |
2172 | sys::swapByteOrder(Value&: C.page_size); |
2173 | sys::swapByteOrder(Value&: C.pointer_format); |
2174 | sys::swapByteOrder(Value&: C.segment_offset); |
2175 | sys::swapByteOrder(Value&: C.max_valid_pointer); |
2176 | sys::swapByteOrder(Value&: C.page_count); |
2177 | // seg_info_offset entries must be byte swapped manually. |
2178 | } |
2179 | |
2180 | /* code signing attributes of a process */ |
2181 | |
2182 | enum CodeSignAttrs { |
2183 | CS_VALID = 0x00000001, /* dynamically valid */ |
2184 | CS_ADHOC = 0x00000002, /* ad hoc signed */ |
2185 | CS_GET_TASK_ALLOW = 0x00000004, /* has get-task-allow entitlement */ |
2186 | CS_INSTALLER = 0x00000008, /* has installer entitlement */ |
2187 | |
2188 | CS_FORCED_LV = |
2189 | 0x00000010, /* Library Validation required by Hardened System Policy */ |
2190 | CS_INVALID_ALLOWED = 0x00000020, /* (macOS Only) Page invalidation allowed by |
2191 | task port policy */ |
2192 | |
2193 | CS_HARD = 0x00000100, /* don't load invalid pages */ |
2194 | CS_KILL = 0x00000200, /* kill process if it becomes invalid */ |
2195 | CS_CHECK_EXPIRATION = 0x00000400, /* force expiration checking */ |
2196 | CS_RESTRICT = 0x00000800, /* tell dyld to treat restricted */ |
2197 | |
2198 | CS_ENFORCEMENT = 0x00001000, /* require enforcement */ |
2199 | CS_REQUIRE_LV = 0x00002000, /* require library validation */ |
2200 | CS_ENTITLEMENTS_VALIDATED = |
2201 | 0x00004000, /* code signature permits restricted entitlements */ |
2202 | CS_NVRAM_UNRESTRICTED = |
2203 | 0x00008000, /* has com.apple.rootless.restricted-nvram-variables.heritable |
2204 | entitlement */ |
2205 | |
2206 | CS_RUNTIME = 0x00010000, /* Apply hardened runtime policies */ |
2207 | CS_LINKER_SIGNED = 0x00020000, /* Automatically signed by the linker */ |
2208 | |
2209 | CS_ALLOWED_MACHO = |
2210 | (CS_ADHOC | CS_HARD | CS_KILL | CS_CHECK_EXPIRATION | CS_RESTRICT | |
2211 | CS_ENFORCEMENT | CS_REQUIRE_LV | CS_RUNTIME | CS_LINKER_SIGNED), |
2212 | |
2213 | CS_EXEC_SET_HARD = 0x00100000, /* set CS_HARD on any exec'ed process */ |
2214 | CS_EXEC_SET_KILL = 0x00200000, /* set CS_KILL on any exec'ed process */ |
2215 | CS_EXEC_SET_ENFORCEMENT = |
2216 | 0x00400000, /* set CS_ENFORCEMENT on any exec'ed process */ |
2217 | CS_EXEC_INHERIT_SIP = |
2218 | 0x00800000, /* set CS_INSTALLER on any exec'ed process */ |
2219 | |
2220 | CS_KILLED = 0x01000000, /* was killed by kernel for invalidity */ |
2221 | CS_DYLD_PLATFORM = |
2222 | 0x02000000, /* dyld used to load this is a platform binary */ |
2223 | CS_PLATFORM_BINARY = 0x04000000, /* this is a platform binary */ |
2224 | CS_PLATFORM_PATH = |
2225 | 0x08000000, /* platform binary by the fact of path (osx only) */ |
2226 | |
2227 | CS_DEBUGGED = 0x10000000, /* process is currently or has previously been |
2228 | debugged and allowed to run with invalid pages */ |
2229 | CS_SIGNED = 0x20000000, /* process has a signature (may have gone invalid) */ |
2230 | CS_DEV_CODE = |
2231 | 0x40000000, /* code is dev signed, cannot be loaded into prod signed code |
2232 | (will go away with rdar://problem/28322552) */ |
2233 | CS_DATAVAULT_CONTROLLER = |
2234 | 0x80000000, /* has Data Vault controller entitlement */ |
2235 | |
2236 | CS_ENTITLEMENT_FLAGS = (CS_GET_TASK_ALLOW | CS_INSTALLER | |
2237 | CS_DATAVAULT_CONTROLLER | CS_NVRAM_UNRESTRICTED), |
2238 | }; |
2239 | |
2240 | /* executable segment flags */ |
2241 | |
2242 | enum CodeSignExecSegFlags { |
2243 | |
2244 | CS_EXECSEG_MAIN_BINARY = 0x1, /* executable segment denotes main binary */ |
2245 | CS_EXECSEG_ALLOW_UNSIGNED = 0x10, /* allow unsigned pages (for debugging) */ |
2246 | CS_EXECSEG_DEBUGGER = 0x20, /* main binary is debugger */ |
2247 | CS_EXECSEG_JIT = 0x40, /* JIT enabled */ |
2248 | CS_EXECSEG_SKIP_LV = 0x80, /* OBSOLETE: skip library validation */ |
2249 | CS_EXECSEG_CAN_LOAD_CDHASH = 0x100, /* can bless cdhash for execution */ |
2250 | CS_EXECSEG_CAN_EXEC_CDHASH = 0x200, /* can execute blessed cdhash */ |
2251 | |
2252 | }; |
2253 | |
2254 | /* Magic numbers used by Code Signing */ |
2255 | |
2256 | enum CodeSignMagic { |
2257 | CSMAGIC_REQUIREMENT = 0xfade0c00, /* single Requirement blob */ |
2258 | CSMAGIC_REQUIREMENTS = |
2259 | 0xfade0c01, /* Requirements vector (internal requirements) */ |
2260 | CSMAGIC_CODEDIRECTORY = 0xfade0c02, /* CodeDirectory blob */ |
2261 | CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0, /* embedded form of signature data */ |
2262 | CSMAGIC_EMBEDDED_SIGNATURE_OLD = 0xfade0b02, /* XXX */ |
2263 | CSMAGIC_EMBEDDED_ENTITLEMENTS = 0xfade7171, /* embedded entitlements */ |
2264 | CSMAGIC_DETACHED_SIGNATURE = |
2265 | 0xfade0cc1, /* multi-arch collection of embedded signatures */ |
2266 | CSMAGIC_BLOBWRAPPER = 0xfade0b01, /* CMS Signature, among other things */ |
2267 | |
2268 | CS_SUPPORTSSCATTER = 0x20100, |
2269 | CS_SUPPORTSTEAMID = 0x20200, |
2270 | CS_SUPPORTSCODELIMIT64 = 0x20300, |
2271 | CS_SUPPORTSEXECSEG = 0x20400, |
2272 | CS_SUPPORTSRUNTIME = 0x20500, |
2273 | CS_SUPPORTSLINKAGE = 0x20600, |
2274 | |
2275 | CSSLOT_CODEDIRECTORY = 0, /* slot index for CodeDirectory */ |
2276 | CSSLOT_INFOSLOT = 1, |
2277 | CSSLOT_REQUIREMENTS = 2, |
2278 | CSSLOT_RESOURCEDIR = 3, |
2279 | CSSLOT_APPLICATION = 4, |
2280 | CSSLOT_ENTITLEMENTS = 5, |
2281 | |
2282 | CSSLOT_ALTERNATE_CODEDIRECTORIES = |
2283 | 0x1000, /* first alternate CodeDirectory, if any */ |
2284 | CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5, /* max number of alternate CD slots */ |
2285 | CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT = |
2286 | CSSLOT_ALTERNATE_CODEDIRECTORIES + |
2287 | CSSLOT_ALTERNATE_CODEDIRECTORY_MAX, /* one past the last */ |
2288 | |
2289 | CSSLOT_SIGNATURESLOT = 0x10000, /* CMS Signature */ |
2290 | CSSLOT_IDENTIFICATIONSLOT = 0x10001, |
2291 | CSSLOT_TICKETSLOT = 0x10002, |
2292 | |
2293 | CSTYPE_INDEX_REQUIREMENTS = 0x00000002, /* compat with amfi */ |
2294 | CSTYPE_INDEX_ENTITLEMENTS = 0x00000005, /* compat with amfi */ |
2295 | |
2296 | CS_HASHTYPE_SHA1 = 1, |
2297 | CS_HASHTYPE_SHA256 = 2, |
2298 | CS_HASHTYPE_SHA256_TRUNCATED = 3, |
2299 | CS_HASHTYPE_SHA384 = 4, |
2300 | |
2301 | CS_SHA1_LEN = 20, |
2302 | CS_SHA256_LEN = 32, |
2303 | CS_SHA256_TRUNCATED_LEN = 20, |
2304 | |
2305 | CS_CDHASH_LEN = 20, /* always - larger hashes are truncated */ |
2306 | CS_HASH_MAX_SIZE = 48, /* max size of the hash we'll support */ |
2307 | |
2308 | /* |
2309 | * Currently only to support Legacy VPN plugins, and Mac App Store |
2310 | * but intended to replace all the various platform code, dev code etc. bits. |
2311 | */ |
2312 | CS_SIGNER_TYPE_UNKNOWN = 0, |
2313 | CS_SIGNER_TYPE_LEGACYVPN = 5, |
2314 | CS_SIGNER_TYPE_MAC_APP_STORE = 6, |
2315 | |
2316 | CS_SUPPL_SIGNER_TYPE_UNKNOWN = 0, |
2317 | CS_SUPPL_SIGNER_TYPE_TRUSTCACHE = 7, |
2318 | CS_SUPPL_SIGNER_TYPE_LOCAL = 8, |
2319 | }; |
2320 | |
2321 | struct CS_CodeDirectory { |
2322 | uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */ |
2323 | uint32_t length; /* total length of CodeDirectory blob */ |
2324 | uint32_t version; /* compatibility version */ |
2325 | uint32_t flags; /* setup and mode flags */ |
2326 | uint32_t hashOffset; /* offset of hash slot element at index zero */ |
2327 | uint32_t identOffset; /* offset of identifier string */ |
2328 | uint32_t nSpecialSlots; /* number of special hash slots */ |
2329 | uint32_t nCodeSlots; /* number of ordinary (code) hash slots */ |
2330 | uint32_t codeLimit; /* limit to main image signature range */ |
2331 | uint8_t hashSize; /* size of each hash in bytes */ |
2332 | uint8_t hashType; /* type of hash (cdHashType* constants) */ |
2333 | uint8_t platform; /* platform identifier; zero if not platform binary */ |
2334 | uint8_t pageSize; /* log2(page size in bytes); 0 => infinite */ |
2335 | uint32_t spare2; /* unused (must be zero) */ |
2336 | |
2337 | /* Version 0x20100 */ |
2338 | uint32_t scatterOffset; /* offset of optional scatter vector */ |
2339 | |
2340 | /* Version 0x20200 */ |
2341 | uint32_t teamOffset; /* offset of optional team identifier */ |
2342 | |
2343 | /* Version 0x20300 */ |
2344 | uint32_t spare3; /* unused (must be zero) */ |
2345 | uint64_t codeLimit64; /* limit to main image signature range, 64 bits */ |
2346 | |
2347 | /* Version 0x20400 */ |
2348 | uint64_t execSegBase; /* offset of executable segment */ |
2349 | uint64_t execSegLimit; /* limit of executable segment */ |
2350 | uint64_t execSegFlags; /* executable segment flags */ |
2351 | }; |
2352 | |
2353 | static_assert(sizeof(CS_CodeDirectory) == 88); |
2354 | |
2355 | struct CS_BlobIndex { |
2356 | uint32_t type; /* type of entry */ |
2357 | uint32_t offset; /* offset of entry */ |
2358 | }; |
2359 | |
2360 | struct CS_SuperBlob { |
2361 | uint32_t magic; /* magic number */ |
2362 | uint32_t length; /* total length of SuperBlob */ |
2363 | uint32_t count; /* number of index entries following */ |
2364 | /* followed by Blobs in no particular order as indicated by index offsets */ |
2365 | }; |
2366 | |
2367 | enum SecCSDigestAlgorithm { |
2368 | kSecCodeSignatureNoHash = 0, /* null value */ |
2369 | kSecCodeSignatureHashSHA1 = 1, /* SHA-1 */ |
2370 | kSecCodeSignatureHashSHA256 = 2, /* SHA-256 */ |
2371 | kSecCodeSignatureHashSHA256Truncated = |
2372 | 3, /* SHA-256 truncated to first 20 bytes */ |
2373 | kSecCodeSignatureHashSHA384 = 4, /* SHA-384 */ |
2374 | kSecCodeSignatureHashSHA512 = 5, /* SHA-512 */ |
2375 | }; |
2376 | |
2377 | enum LinkerOptimizationHintKind { |
2378 | LOH_ARM64_ADRP_ADRP = 1, |
2379 | LOH_ARM64_ADRP_LDR = 2, |
2380 | LOH_ARM64_ADRP_ADD_LDR = 3, |
2381 | LOH_ARM64_ADRP_LDR_GOT_LDR = 4, |
2382 | LOH_ARM64_ADRP_ADD_STR = 5, |
2383 | LOH_ARM64_ADRP_LDR_GOT_STR = 6, |
2384 | LOH_ARM64_ADRP_ADD = 7, |
2385 | LOH_ARM64_ADRP_LDR_GOT = 8, |
2386 | }; |
2387 | |
2388 | } // end namespace MachO |
2389 | } // end namespace llvm |
2390 | |
2391 | #endif |
2392 | |