/rust/registry/src/index.crates.io-1949cf8c6b5b557f/object-0.37.3/src/macho.rs
Line | Count | Source |
1 | | //! Mach-O definitions. |
2 | | //! |
3 | | //! These definitions are independent of read/write support, although we do implement |
4 | | //! some traits useful for those. |
5 | | //! |
6 | | //! This module is based heavily on header files from MacOSX11.1.sdk. |
7 | | |
8 | | #![allow(missing_docs)] |
9 | | |
10 | | use crate::endian::{BigEndian, Endian, U64Bytes, U16, U32, U64}; |
11 | | use crate::pod::Pod; |
12 | | |
13 | | // Definitions from "/usr/include/mach/machine.h". |
14 | | |
15 | | /* |
16 | | * Capability bits used in the definition of cpu_type. |
17 | | */ |
18 | | |
19 | | /// mask for architecture bits |
20 | | pub const CPU_ARCH_MASK: u32 = 0xff00_0000; |
21 | | /// 64 bit ABI |
22 | | pub const CPU_ARCH_ABI64: u32 = 0x0100_0000; |
23 | | /// ABI for 64-bit hardware with 32-bit types; LP32 |
24 | | pub const CPU_ARCH_ABI64_32: u32 = 0x0200_0000; |
25 | | |
26 | | /* |
27 | | * Machine types known by all. |
28 | | */ |
29 | | |
30 | | pub const CPU_TYPE_ANY: u32 = !0; |
31 | | |
32 | | pub const CPU_TYPE_VAX: u32 = 1; |
33 | | pub const CPU_TYPE_MC680X0: u32 = 6; |
34 | | pub const CPU_TYPE_X86: u32 = 7; |
35 | | pub const CPU_TYPE_X86_64: u32 = CPU_TYPE_X86 | CPU_ARCH_ABI64; |
36 | | pub const CPU_TYPE_MIPS: u32 = 8; |
37 | | pub const CPU_TYPE_MC98000: u32 = 10; |
38 | | pub const CPU_TYPE_HPPA: u32 = 11; |
39 | | pub const CPU_TYPE_ARM: u32 = 12; |
40 | | pub const CPU_TYPE_ARM64: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64; |
41 | | pub const CPU_TYPE_ARM64_32: u32 = CPU_TYPE_ARM | CPU_ARCH_ABI64_32; |
42 | | pub const CPU_TYPE_MC88000: u32 = 13; |
43 | | pub const CPU_TYPE_SPARC: u32 = 14; |
44 | | pub const CPU_TYPE_I860: u32 = 15; |
45 | | pub const CPU_TYPE_ALPHA: u32 = 16; |
46 | | pub const CPU_TYPE_POWERPC: u32 = 18; |
47 | | pub const CPU_TYPE_POWERPC64: u32 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64; |
48 | | |
49 | | /* |
50 | | * Capability bits used in the definition of cpu_subtype. |
51 | | */ |
52 | | /// mask for feature flags |
53 | | pub const CPU_SUBTYPE_MASK: u32 = 0xff00_0000; |
54 | | /// 64 bit libraries |
55 | | pub const CPU_SUBTYPE_LIB64: u32 = 0x8000_0000; |
56 | | /// pointer authentication with versioned ABI |
57 | | pub const CPU_SUBTYPE_PTRAUTH_ABI: u32 = 0x8000_0000; |
58 | | |
59 | | /// When selecting a slice, ANY will pick the slice with the best |
60 | | /// grading for the selected cpu_type_t, unlike the "ALL" subtypes, |
61 | | /// which are the slices that can run on any hardware for that cpu type. |
62 | | pub const CPU_SUBTYPE_ANY: u32 = !0; |
63 | | |
64 | | /* |
65 | | * Object files that are hand-crafted to run on any |
66 | | * implementation of an architecture are tagged with |
67 | | * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as |
68 | | * the "ALL" subtype of an architecture except that it allows us |
69 | | * to easily find object files that may need to be modified |
70 | | * whenever a new implementation of an architecture comes out. |
71 | | * |
72 | | * It is the responsibility of the implementor to make sure the |
73 | | * software handles unsupported implementations elegantly. |
74 | | */ |
75 | | pub const CPU_SUBTYPE_MULTIPLE: u32 = !0; |
76 | | pub const CPU_SUBTYPE_LITTLE_ENDIAN: u32 = 0; |
77 | | pub const CPU_SUBTYPE_BIG_ENDIAN: u32 = 1; |
78 | | |
79 | | /* |
80 | | * VAX subtypes (these do *not* necessary conform to the actual cpu |
81 | | * ID assigned by DEC available via the SID register). |
82 | | */ |
83 | | |
84 | | pub const CPU_SUBTYPE_VAX_ALL: u32 = 0; |
85 | | pub const CPU_SUBTYPE_VAX780: u32 = 1; |
86 | | pub const CPU_SUBTYPE_VAX785: u32 = 2; |
87 | | pub const CPU_SUBTYPE_VAX750: u32 = 3; |
88 | | pub const CPU_SUBTYPE_VAX730: u32 = 4; |
89 | | pub const CPU_SUBTYPE_UVAXI: u32 = 5; |
90 | | pub const CPU_SUBTYPE_UVAXII: u32 = 6; |
91 | | pub const CPU_SUBTYPE_VAX8200: u32 = 7; |
92 | | pub const CPU_SUBTYPE_VAX8500: u32 = 8; |
93 | | pub const CPU_SUBTYPE_VAX8600: u32 = 9; |
94 | | pub const CPU_SUBTYPE_VAX8650: u32 = 10; |
95 | | pub const CPU_SUBTYPE_VAX8800: u32 = 11; |
96 | | pub const CPU_SUBTYPE_UVAXIII: u32 = 12; |
97 | | |
98 | | /* |
99 | | * 680x0 subtypes |
100 | | * |
101 | | * The subtype definitions here are unusual for historical reasons. |
102 | | * NeXT used to consider 68030 code as generic 68000 code. For |
103 | | * backwards compatibility: |
104 | | * |
105 | | * CPU_SUBTYPE_MC68030 symbol has been preserved for source code |
106 | | * compatibility. |
107 | | * |
108 | | * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same |
109 | | * subtype as CPU_SUBTYPE_MC68030 for binary comatability. |
110 | | * |
111 | | * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object |
112 | | * files to be tagged as containing 68030-specific instructions. |
113 | | */ |
114 | | |
115 | | pub const CPU_SUBTYPE_MC680X0_ALL: u32 = 1; |
116 | | // compat |
117 | | pub const CPU_SUBTYPE_MC68030: u32 = 1; |
118 | | pub const CPU_SUBTYPE_MC68040: u32 = 2; |
119 | | pub const CPU_SUBTYPE_MC68030_ONLY: u32 = 3; |
120 | | |
121 | | /* |
122 | | * I386 subtypes |
123 | | */ |
124 | | |
125 | | #[inline] |
126 | 0 | pub const fn cpu_subtype_intel(f: u32, m: u32) -> u32 { |
127 | 0 | f + (m << 4) |
128 | 0 | } |
129 | | |
130 | | pub const CPU_SUBTYPE_I386_ALL: u32 = cpu_subtype_intel(3, 0); |
131 | | pub const CPU_SUBTYPE_386: u32 = cpu_subtype_intel(3, 0); |
132 | | pub const CPU_SUBTYPE_486: u32 = cpu_subtype_intel(4, 0); |
133 | | pub const CPU_SUBTYPE_486SX: u32 = cpu_subtype_intel(4, 8); |
134 | | pub const CPU_SUBTYPE_586: u32 = cpu_subtype_intel(5, 0); |
135 | | pub const CPU_SUBTYPE_PENT: u32 = cpu_subtype_intel(5, 0); |
136 | | pub const CPU_SUBTYPE_PENTPRO: u32 = cpu_subtype_intel(6, 1); |
137 | | pub const CPU_SUBTYPE_PENTII_M3: u32 = cpu_subtype_intel(6, 3); |
138 | | pub const CPU_SUBTYPE_PENTII_M5: u32 = cpu_subtype_intel(6, 5); |
139 | | pub const CPU_SUBTYPE_CELERON: u32 = cpu_subtype_intel(7, 6); |
140 | | pub const CPU_SUBTYPE_CELERON_MOBILE: u32 = cpu_subtype_intel(7, 7); |
141 | | pub const CPU_SUBTYPE_PENTIUM_3: u32 = cpu_subtype_intel(8, 0); |
142 | | pub const CPU_SUBTYPE_PENTIUM_3_M: u32 = cpu_subtype_intel(8, 1); |
143 | | pub const CPU_SUBTYPE_PENTIUM_3_XEON: u32 = cpu_subtype_intel(8, 2); |
144 | | pub const CPU_SUBTYPE_PENTIUM_M: u32 = cpu_subtype_intel(9, 0); |
145 | | pub const CPU_SUBTYPE_PENTIUM_4: u32 = cpu_subtype_intel(10, 0); |
146 | | pub const CPU_SUBTYPE_PENTIUM_4_M: u32 = cpu_subtype_intel(10, 1); |
147 | | pub const CPU_SUBTYPE_ITANIUM: u32 = cpu_subtype_intel(11, 0); |
148 | | pub const CPU_SUBTYPE_ITANIUM_2: u32 = cpu_subtype_intel(11, 1); |
149 | | pub const CPU_SUBTYPE_XEON: u32 = cpu_subtype_intel(12, 0); |
150 | | pub const CPU_SUBTYPE_XEON_MP: u32 = cpu_subtype_intel(12, 1); |
151 | | |
152 | | #[inline] |
153 | 0 | pub const fn cpu_subtype_intel_family(x: u32) -> u32 { |
154 | 0 | x & 15 |
155 | 0 | } |
156 | | pub const CPU_SUBTYPE_INTEL_FAMILY_MAX: u32 = 15; |
157 | | |
158 | | #[inline] |
159 | 0 | pub const fn cpu_subtype_intel_model(x: u32) -> u32 { |
160 | 0 | x >> 4 |
161 | 0 | } |
162 | | pub const CPU_SUBTYPE_INTEL_MODEL_ALL: u32 = 0; |
163 | | |
164 | | /* |
165 | | * X86 subtypes. |
166 | | */ |
167 | | |
168 | | pub const CPU_SUBTYPE_X86_ALL: u32 = 3; |
169 | | pub const CPU_SUBTYPE_X86_64_ALL: u32 = 3; |
170 | | pub const CPU_SUBTYPE_X86_ARCH1: u32 = 4; |
171 | | /// Haswell feature subset |
172 | | pub const CPU_SUBTYPE_X86_64_H: u32 = 8; |
173 | | |
174 | | /* |
175 | | * Mips subtypes. |
176 | | */ |
177 | | |
178 | | pub const CPU_SUBTYPE_MIPS_ALL: u32 = 0; |
179 | | pub const CPU_SUBTYPE_MIPS_R2300: u32 = 1; |
180 | | pub const CPU_SUBTYPE_MIPS_R2600: u32 = 2; |
181 | | pub const CPU_SUBTYPE_MIPS_R2800: u32 = 3; |
182 | | /// pmax |
183 | | pub const CPU_SUBTYPE_MIPS_R2000A: u32 = 4; |
184 | | pub const CPU_SUBTYPE_MIPS_R2000: u32 = 5; |
185 | | /// 3max |
186 | | pub const CPU_SUBTYPE_MIPS_R3000A: u32 = 6; |
187 | | pub const CPU_SUBTYPE_MIPS_R3000: u32 = 7; |
188 | | |
189 | | /* |
190 | | * MC98000 (PowerPC) subtypes |
191 | | */ |
192 | | pub const CPU_SUBTYPE_MC98000_ALL: u32 = 0; |
193 | | pub const CPU_SUBTYPE_MC98601: u32 = 1; |
194 | | |
195 | | /* |
196 | | * HPPA subtypes for Hewlett-Packard HP-PA family of |
197 | | * risc processors. Port by NeXT to 700 series. |
198 | | */ |
199 | | |
200 | | pub const CPU_SUBTYPE_HPPA_ALL: u32 = 0; |
201 | | pub const CPU_SUBTYPE_HPPA_7100LC: u32 = 1; |
202 | | |
203 | | /* |
204 | | * MC88000 subtypes. |
205 | | */ |
206 | | pub const CPU_SUBTYPE_MC88000_ALL: u32 = 0; |
207 | | pub const CPU_SUBTYPE_MC88100: u32 = 1; |
208 | | pub const CPU_SUBTYPE_MC88110: u32 = 2; |
209 | | |
210 | | /* |
211 | | * SPARC subtypes |
212 | | */ |
213 | | pub const CPU_SUBTYPE_SPARC_ALL: u32 = 0; |
214 | | |
215 | | /* |
216 | | * I860 subtypes |
217 | | */ |
218 | | pub const CPU_SUBTYPE_I860_ALL: u32 = 0; |
219 | | pub const CPU_SUBTYPE_I860_860: u32 = 1; |
220 | | |
221 | | /* |
222 | | * PowerPC subtypes |
223 | | */ |
224 | | pub const CPU_SUBTYPE_POWERPC_ALL: u32 = 0; |
225 | | pub const CPU_SUBTYPE_POWERPC_601: u32 = 1; |
226 | | pub const CPU_SUBTYPE_POWERPC_602: u32 = 2; |
227 | | pub const CPU_SUBTYPE_POWERPC_603: u32 = 3; |
228 | | pub const CPU_SUBTYPE_POWERPC_603E: u32 = 4; |
229 | | pub const CPU_SUBTYPE_POWERPC_603EV: u32 = 5; |
230 | | pub const CPU_SUBTYPE_POWERPC_604: u32 = 6; |
231 | | pub const CPU_SUBTYPE_POWERPC_604E: u32 = 7; |
232 | | pub const CPU_SUBTYPE_POWERPC_620: u32 = 8; |
233 | | pub const CPU_SUBTYPE_POWERPC_750: u32 = 9; |
234 | | pub const CPU_SUBTYPE_POWERPC_7400: u32 = 10; |
235 | | pub const CPU_SUBTYPE_POWERPC_7450: u32 = 11; |
236 | | pub const CPU_SUBTYPE_POWERPC_970: u32 = 100; |
237 | | |
238 | | /* |
239 | | * ARM subtypes |
240 | | */ |
241 | | pub const CPU_SUBTYPE_ARM_ALL: u32 = 0; |
242 | | pub const CPU_SUBTYPE_ARM_V4T: u32 = 5; |
243 | | pub const CPU_SUBTYPE_ARM_V6: u32 = 6; |
244 | | pub const CPU_SUBTYPE_ARM_V5TEJ: u32 = 7; |
245 | | pub const CPU_SUBTYPE_ARM_XSCALE: u32 = 8; |
246 | | /// ARMv7-A and ARMv7-R |
247 | | pub const CPU_SUBTYPE_ARM_V7: u32 = 9; |
248 | | /// Cortex A9 |
249 | | pub const CPU_SUBTYPE_ARM_V7F: u32 = 10; |
250 | | /// Swift |
251 | | pub const CPU_SUBTYPE_ARM_V7S: u32 = 11; |
252 | | pub const CPU_SUBTYPE_ARM_V7K: u32 = 12; |
253 | | pub const CPU_SUBTYPE_ARM_V8: u32 = 13; |
254 | | /// Not meant to be run under xnu |
255 | | pub const CPU_SUBTYPE_ARM_V6M: u32 = 14; |
256 | | /// Not meant to be run under xnu |
257 | | pub const CPU_SUBTYPE_ARM_V7M: u32 = 15; |
258 | | /// Not meant to be run under xnu |
259 | | pub const CPU_SUBTYPE_ARM_V7EM: u32 = 16; |
260 | | /// Not meant to be run under xnu |
261 | | pub const CPU_SUBTYPE_ARM_V8M: u32 = 17; |
262 | | |
263 | | /* |
264 | | * ARM64 subtypes |
265 | | */ |
266 | | pub const CPU_SUBTYPE_ARM64_ALL: u32 = 0; |
267 | | pub const CPU_SUBTYPE_ARM64_V8: u32 = 1; |
268 | | pub const CPU_SUBTYPE_ARM64E: u32 = 2; |
269 | | |
270 | | /* |
271 | | * ARM64_32 subtypes |
272 | | */ |
273 | | pub const CPU_SUBTYPE_ARM64_32_ALL: u32 = 0; |
274 | | pub const CPU_SUBTYPE_ARM64_32_V8: u32 = 1; |
275 | | |
276 | | // Definitions from "/usr/include/mach/vm_prot.h". |
277 | | |
278 | | /// read permission |
279 | | pub const VM_PROT_READ: u32 = 0x01; |
280 | | /// write permission |
281 | | pub const VM_PROT_WRITE: u32 = 0x02; |
282 | | /// execute permission |
283 | | pub const VM_PROT_EXECUTE: u32 = 0x04; |
284 | | |
285 | | // Definitions from ptrauth.h |
286 | | |
287 | | /// The key used to sign a pointer for authentication. |
288 | | /// |
289 | | /// The variant values correspond to the values used in the |
290 | | /// `ptrauth_key` enum in `ptrauth.h`. |
291 | | #[repr(u8)] |
292 | | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
293 | | pub enum PtrauthKey { |
294 | | /// Instruction key A. |
295 | | IA = 0, |
296 | | /// Instruction key B. |
297 | | IB = 1, |
298 | | /// Data key A. |
299 | | DA = 2, |
300 | | /// Data key B. |
301 | | DB = 3, |
302 | | } |
303 | | |
304 | | // Definitions from https://opensource.apple.com/source/dyld/dyld-210.2.3/launch-cache/dyld_cache_format.h.auto.html |
305 | | |
306 | | /// The dyld cache header. |
307 | | /// Corresponds to struct dyld_cache_header from dyld_cache_format.h. |
308 | | /// This header has grown over time. Only the fields up to and including dyld_base_address |
309 | | /// are guaranteed to be present. For all other fields, check the header size before |
310 | | /// accessing the field. The header size is stored in mapping_offset; the mappings start |
311 | | /// right after the theader. |
312 | | #[derive(Debug, Clone, Copy)] |
313 | | #[repr(C)] |
314 | | pub struct DyldCacheHeader<E: Endian> { |
315 | | /// e.g. "dyld_v0 i386" |
316 | | pub magic: [u8; 16], |
317 | | /// file offset to first dyld_cache_mapping_info |
318 | | pub mapping_offset: U32<E>, |
319 | | /// number of dyld_cache_mapping_info entries |
320 | | pub mapping_count: U32<E>, |
321 | | /// UNUSED: moved to imagesOffset to prevent older dsc_extarctors from crashing |
322 | | pub images_offset_old: U32<E>, |
323 | | /// UNUSED: moved to imagesCount to prevent older dsc_extarctors from crashing |
324 | | pub images_count_old: U32<E>, |
325 | | /// base address of dyld when cache was built |
326 | | pub dyld_base_address: U64<E>, |
327 | | /// file offset of code signature blob |
328 | | pub code_signature_offset: U64<E>, |
329 | | /// size of code signature blob (zero means to end of file) |
330 | | pub code_signature_size: U64<E>, |
331 | | /// unused. Used to be file offset of kernel slid info |
332 | | pub slide_info_offset_unused: U64<E>, |
333 | | /// unused. Used to be size of kernel slid info |
334 | | pub slide_info_size_unused: U64<E>, |
335 | | /// file offset of where local symbols are stored |
336 | | pub local_symbols_offset: U64<E>, |
337 | | /// size of local symbols information |
338 | | pub local_symbols_size: U64<E>, |
339 | | /// unique value for each shared cache file |
340 | | pub uuid: [u8; 16], |
341 | | /// 0 for development, 1 for production, 2 for multi-cache |
342 | | pub cache_type: U64<E>, |
343 | | /// file offset to table of uint64_t pool addresses |
344 | | pub branch_pools_offset: U32<E>, |
345 | | /// number of uint64_t entries |
346 | | pub branch_pools_count: U32<E>, |
347 | | /// (unslid) address of mach_header of dyld in cache |
348 | | pub dyld_in_cache_mh: U64<E>, |
349 | | /// (unslid) address of entry point (_dyld_start) of dyld in cache |
350 | | pub dyld_in_cache_entry: U64<E>, |
351 | | /// file offset to first dyld_cache_image_text_info |
352 | | pub images_text_offset: U64<E>, |
353 | | /// number of dyld_cache_image_text_info entries |
354 | | pub images_text_count: U64<E>, |
355 | | /// (unslid) address of dyld_cache_patch_info |
356 | | pub patch_info_addr: U64<E>, |
357 | | /// Size of all of the patch information pointed to via the dyld_cache_patch_info |
358 | | pub patch_info_size: U64<E>, |
359 | | /// unused |
360 | | pub other_image_group_addr_unused: U64<E>, |
361 | | /// unused |
362 | | pub other_image_group_size_unused: U64<E>, |
363 | | /// (unslid) address of list of program launch closures |
364 | | pub prog_closures_addr: U64<E>, |
365 | | /// size of list of program launch closures |
366 | | pub prog_closures_size: U64<E>, |
367 | | /// (unslid) address of trie of indexes into program launch closures |
368 | | pub prog_closures_trie_addr: U64<E>, |
369 | | /// size of trie of indexes into program launch closures |
370 | | pub prog_closures_trie_size: U64<E>, |
371 | | /// platform number (macOS=1, etc) |
372 | | pub platform: U32<E>, |
373 | | // bitfield of values |
374 | | pub flags: U32<E>, |
375 | | /// base load address of cache if not slid |
376 | | pub shared_region_start: U64<E>, |
377 | | /// overall size required to map the cache and all subCaches, if any |
378 | | pub shared_region_size: U64<E>, |
379 | | /// runtime slide of cache can be between zero and this value |
380 | | pub max_slide: U64<E>, |
381 | | /// (unslid) address of ImageArray for dylibs in this cache |
382 | | pub dylibs_image_array_addr: U64<E>, |
383 | | /// size of ImageArray for dylibs in this cache |
384 | | pub dylibs_image_array_size: U64<E>, |
385 | | /// (unslid) address of trie of indexes of all cached dylibs |
386 | | pub dylibs_trie_addr: U64<E>, |
387 | | /// size of trie of cached dylib paths |
388 | | pub dylibs_trie_size: U64<E>, |
389 | | /// (unslid) address of ImageArray for dylibs and bundles with dlopen closures |
390 | | pub other_image_array_addr: U64<E>, |
391 | | /// size of ImageArray for dylibs and bundles with dlopen closures |
392 | | pub other_image_array_size: U64<E>, |
393 | | /// (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures |
394 | | pub other_trie_addr: U64<E>, |
395 | | /// size of trie of dylibs and bundles with dlopen closures |
396 | | pub other_trie_size: U64<E>, |
397 | | /// file offset to first dyld_cache_mapping_and_slide_info |
398 | | pub mapping_with_slide_offset: U32<E>, |
399 | | /// number of dyld_cache_mapping_and_slide_info entries |
400 | | pub mapping_with_slide_count: U32<E>, |
401 | | /// unused |
402 | | pub dylibs_pbl_state_array_addr_unused: U64<E>, |
403 | | /// (unslid) address of PrebuiltLoaderSet of all cached dylibs |
404 | | pub dylibs_pbl_set_addr: U64<E>, |
405 | | /// (unslid) address of pool of PrebuiltLoaderSet for each program |
406 | | pub programs_pbl_set_pool_addr: U64<E>, |
407 | | /// size of pool of PrebuiltLoaderSet for each program |
408 | | pub programs_pbl_set_pool_size: U64<E>, |
409 | | /// (unslid) address of trie mapping program path to PrebuiltLoaderSet |
410 | | pub program_trie_addr: U64<E>, |
411 | | /// OS Version of dylibs in this cache for the main platform |
412 | | pub os_version: U32<E>, |
413 | | /// e.g. iOSMac on macOS |
414 | | pub alt_platform: U32<E>, |
415 | | /// e.g. 14.0 for iOSMac |
416 | | pub alt_os_version: U32<E>, |
417 | | reserved1: [u8; 4], |
418 | | /// VM offset from cache_header* to Swift optimizations header |
419 | | pub swift_opts_offset: U64<E>, |
420 | | /// size of Swift optimizations header |
421 | | pub swift_opts_size: U64<E>, |
422 | | /// file offset to first dyld_subcache_entry |
423 | | pub sub_cache_array_offset: U32<E>, |
424 | | /// number of subCache entries |
425 | | pub sub_cache_array_count: U32<E>, |
426 | | /// unique value for the shared cache file containing unmapped local symbols |
427 | | pub symbol_file_uuid: [u8; 16], |
428 | | /// (unslid) address of the start of where Rosetta can add read-only/executable data |
429 | | pub rosetta_read_only_addr: U64<E>, |
430 | | /// maximum size of the Rosetta read-only/executable region |
431 | | pub rosetta_read_only_size: U64<E>, |
432 | | /// (unslid) address of the start of where Rosetta can add read-write data |
433 | | pub rosetta_read_write_addr: U64<E>, |
434 | | /// maximum size of the Rosetta read-write region |
435 | | pub rosetta_read_write_size: U64<E>, |
436 | | /// file offset to first dyld_cache_image_info |
437 | | pub images_offset: U32<E>, |
438 | | /// number of dyld_cache_image_info entries |
439 | | pub images_count: U32<E>, |
440 | | /// 0 for development, 1 for production, when cacheType is multi-cache(2) |
441 | | pub cache_sub_type: U32<E>, |
442 | | /// VM offset from cache_header* to ObjC optimizations header |
443 | | pub objc_opts_offset: U64<E>, |
444 | | /// size of ObjC optimizations header |
445 | | pub objc_opts_size: U64<E>, |
446 | | /// VM offset from cache_header* to embedded cache atlas for process introspection |
447 | | pub cache_atlas_offset: U64<E>, |
448 | | /// size of embedded cache atlas |
449 | | pub cache_atlas_size: U64<E>, |
450 | | /// VM offset from cache_header* to the location of dyld_cache_dynamic_data_header |
451 | | pub dynamic_data_offset: U64<E>, |
452 | | /// maximum size of space reserved from dynamic data |
453 | | pub dynamic_data_max_size: U64<E>, |
454 | | } |
455 | | |
456 | | /// Corresponds to struct dyld_cache_mapping_info from dyld_cache_format.h. |
457 | | #[derive(Debug, Clone, Copy)] |
458 | | #[repr(C)] |
459 | | pub struct DyldCacheMappingInfo<E: Endian> { |
460 | | pub address: U64<E>, |
461 | | pub size: U64<E>, |
462 | | pub file_offset: U64<E>, |
463 | | pub max_prot: U32<E>, |
464 | | pub init_prot: U32<E>, |
465 | | } |
466 | | |
467 | | // Contains the flags for the dyld_cache_mapping_and_slide_info flags field |
468 | | pub const DYLD_CACHE_MAPPING_AUTH_DATA: u64 = 1 << 0; |
469 | | pub const DYLD_CACHE_MAPPING_DIRTY_DATA: u64 = 1 << 1; |
470 | | pub const DYLD_CACHE_MAPPING_CONST_DATA: u64 = 1 << 2; |
471 | | pub const DYLD_CACHE_MAPPING_TEXT_STUBS: u64 = 1 << 3; |
472 | | pub const DYLD_CACHE_DYNAMIC_CONFIG_DATA: u64 = 1 << 4; |
473 | | |
474 | | /// Corresponds to struct dyld_cache_mapping_and_slide_info from dyld_cache_format.h. |
475 | | #[derive(Debug, Clone, Copy)] |
476 | | #[repr(C)] |
477 | | pub struct DyldCacheMappingAndSlideInfo<E: Endian> { |
478 | | pub address: U64<E>, |
479 | | pub size: U64<E>, |
480 | | pub file_offset: U64<E>, |
481 | | pub slide_info_file_offset: U64<E>, |
482 | | pub slide_info_file_size: U64<E>, |
483 | | pub flags: U64<E>, |
484 | | pub max_prot: U32<E>, |
485 | | pub init_prot: U32<E>, |
486 | | } |
487 | | |
488 | | /// Corresponds to struct dyld_cache_image_info from dyld_cache_format.h. |
489 | | #[derive(Debug, Clone, Copy)] |
490 | | #[repr(C)] |
491 | | pub struct DyldCacheImageInfo<E: Endian> { |
492 | | pub address: U64<E>, |
493 | | pub mod_time: U64<E>, |
494 | | pub inode: U64<E>, |
495 | | pub path_file_offset: U32<E>, |
496 | | pub pad: U32<E>, |
497 | | } |
498 | | |
499 | | /// Corresponds to struct dyld_cache_slide_info2 from dyld_cache_format.h. |
500 | | #[derive(Debug, Clone, Copy)] |
501 | | #[repr(C)] |
502 | | pub struct DyldCacheSlideInfo2<E: Endian> { |
503 | | pub version: U32<E>, // currently 2 |
504 | | pub page_size: U32<E>, // currently 4096 (may also be 16384) |
505 | | pub page_starts_offset: U32<E>, |
506 | | pub page_starts_count: U32<E>, |
507 | | pub page_extras_offset: U32<E>, |
508 | | pub page_extras_count: U32<E>, |
509 | | pub delta_mask: U64<E>, // which (contiguous) set of bits contains the delta to the next rebase location |
510 | | pub value_add: U64<E>, |
511 | | } |
512 | | |
513 | | pub const DYLD_CACHE_SLIDE_PAGE_ATTRS: u16 = 0xC000; |
514 | | // Index is into extras array (not starts array). |
515 | | pub const DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA: u16 = 0x8000; |
516 | | // Page has no rebasing. |
517 | | pub const DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE: u16 = 0x4000; |
518 | | // Last chain entry for page. |
519 | | pub const DYLD_CACHE_SLIDE_PAGE_ATTR_END: u16 = 0x8000; |
520 | | |
521 | | /// Corresponds to struct dyld_cache_slide_info3 from dyld_cache_format.h. |
522 | | #[derive(Debug, Clone, Copy)] |
523 | | #[repr(C)] |
524 | | pub struct DyldCacheSlideInfo3<E: Endian> { |
525 | | pub version: U32<E>, // currently 3 |
526 | | pub page_size: U32<E>, // currently 4096 (may also be 16384) |
527 | | pub page_starts_count: U32<E>, |
528 | | reserved1: [u8; 4], |
529 | | pub auth_value_add: U64<E>, |
530 | | } |
531 | | |
532 | | /// Page has no rebasing. |
533 | | pub const DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE: u16 = 0xFFFF; |
534 | | |
535 | | /// Corresponds to union dyld_cache_slide_pointer3 from dyld_cache_format.h. |
536 | | #[derive(Debug, Clone, Copy)] |
537 | | pub struct DyldCacheSlidePointer3(pub u64); |
538 | | |
539 | | impl DyldCacheSlidePointer3 { |
540 | | /// Whether the pointer is authenticated. |
541 | 0 | pub fn is_auth(&self) -> bool { |
542 | 0 | ((self.0 >> 63) & 1) != 0 |
543 | 0 | } |
544 | | |
545 | | /// The target of the pointer. |
546 | | /// |
547 | | /// Only valid if `is_auth` is false. |
548 | 0 | pub fn target(&self) -> u64 { |
549 | 0 | self.0 & ((1 << 43) - 1) |
550 | 0 | } |
551 | | |
552 | | /// The high 8 bits of the pointer. |
553 | | /// |
554 | | /// Only valid if `is_auth` is false. |
555 | 0 | pub fn high8(&self) -> u64 { |
556 | 0 | (self.0 >> 43) & 0xff |
557 | 0 | } |
558 | | |
559 | | /// The target of the pointer as an offset from the start of the shared cache. |
560 | | /// |
561 | | /// Only valid if `is_auth` is true. |
562 | 0 | pub fn runtime_offset(&self) -> u64 { |
563 | 0 | self.0 & ((1 << 32) - 1) |
564 | 0 | } |
565 | | |
566 | | /// The diversity value for authentication. |
567 | | /// |
568 | | /// Only valid if `is_auth` is true. |
569 | 0 | pub fn diversity(&self) -> u16 { |
570 | 0 | ((self.0 >> 32) & 0xffff) as u16 |
571 | 0 | } |
572 | | |
573 | | /// Whether to use address diversity for authentication. |
574 | | /// |
575 | | /// Only valid if `is_auth` is true. |
576 | 0 | pub fn addr_div(&self) -> bool { |
577 | 0 | ((self.0 >> 48) & 1) != 0 |
578 | 0 | } |
579 | | |
580 | | /// The key for authentication. |
581 | | /// |
582 | | /// Only valid if `is_auth` is true. |
583 | 0 | pub fn key(&self) -> u8 { |
584 | 0 | ((self.0 >> 49) & 3) as u8 |
585 | 0 | } |
586 | | |
587 | | /// The offset to the next slide pointer in 8-byte units. |
588 | | /// |
589 | | /// 0 if no next slide pointer. |
590 | 0 | pub fn next(&self) -> u64 { |
591 | 0 | (self.0 >> 51) & ((1 << 11) - 1) |
592 | 0 | } |
593 | | } |
594 | | |
595 | | /// Corresponds to struct dyld_cache_slide_info5 from dyld_cache_format.h. |
596 | | #[derive(Debug, Clone, Copy)] |
597 | | #[repr(C)] |
598 | | pub struct DyldCacheSlideInfo5<E: Endian> { |
599 | | pub version: U32<E>, // currently 5 |
600 | | pub page_size: U32<E>, // currently 4096 (may also be 16384) |
601 | | pub page_starts_count: U32<E>, |
602 | | reserved1: [u8; 4], |
603 | | pub value_add: U64<E>, |
604 | | } |
605 | | |
606 | | /// Page has no rebasing. |
607 | | pub const DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE: u16 = 0xFFFF; |
608 | | |
609 | | /// Corresponds to struct dyld_cache_slide_pointer5 from dyld_cache_format.h. |
610 | | #[derive(Debug, Clone, Copy)] |
611 | | pub struct DyldCacheSlidePointer5(pub u64); |
612 | | |
613 | | impl DyldCacheSlidePointer5 { |
614 | | /// Whether the pointer is authenticated. |
615 | 0 | pub fn is_auth(&self) -> bool { |
616 | 0 | ((self.0 >> 63) & 1) != 0 |
617 | 0 | } |
618 | | |
619 | | /// The target of the pointer as an offset from the start of the shared cache. |
620 | 0 | pub fn runtime_offset(&self) -> u64 { |
621 | 0 | self.0 & 0x3_ffff_ffff |
622 | 0 | } |
623 | | |
624 | | /// The high 8 bits of the pointer. |
625 | | /// |
626 | | /// Only valid if `is_auth` is false. |
627 | 0 | pub fn high8(&self) -> u64 { |
628 | 0 | (self.0 >> 34) & 0xff |
629 | 0 | } |
630 | | |
631 | | /// The diversity value for authentication. |
632 | | /// |
633 | | /// Only valid if `is_auth` is true. |
634 | 0 | pub fn diversity(&self) -> u16 { |
635 | 0 | ((self.0 >> 34) & 0xffff) as u16 |
636 | 0 | } |
637 | | |
638 | | /// Whether to use address diversity for authentication. |
639 | | /// |
640 | | /// Only valid if `is_auth` is true. |
641 | 0 | pub fn addr_div(&self) -> bool { |
642 | 0 | ((self.0 >> 50) & 1) != 0 |
643 | 0 | } |
644 | | |
645 | | /// Whether the key is IA or DA. |
646 | | /// |
647 | | /// Only valid if `is_auth` is true. |
648 | 0 | pub fn key_is_data(&self) -> bool { |
649 | 0 | ((self.0 >> 51) & 1) != 0 |
650 | 0 | } |
651 | | |
652 | | /// The offset to the next slide pointer in 8-byte units. |
653 | | /// |
654 | | /// 0 if no next slide pointer. |
655 | 0 | pub fn next(&self) -> u64 { |
656 | 0 | (self.0 >> 52) & 0x7ff |
657 | 0 | } |
658 | | } |
659 | | |
660 | | /// Added in dyld-940, which shipped with macOS 12 / iOS 15. |
661 | | /// Originally called `dyld_subcache_entry`, renamed to `dyld_subcache_entry_v1` |
662 | | /// in dyld-1042.1. |
663 | | #[derive(Debug, Clone, Copy)] |
664 | | #[repr(C)] |
665 | | pub struct DyldSubCacheEntryV1<E: Endian> { |
666 | | /// The UUID of this subcache. |
667 | | pub uuid: [u8; 16], |
668 | | /// The offset of this subcache from the main cache base address. |
669 | | pub cache_vm_offset: U64<E>, |
670 | | } |
671 | | |
672 | | /// Added in dyld-1042.1, which shipped with macOS 13 / iOS 16. |
673 | | /// Called `dyld_subcache_entry` as of dyld-1042.1. |
674 | | #[derive(Debug, Clone, Copy)] |
675 | | #[repr(C)] |
676 | | pub struct DyldSubCacheEntryV2<E: Endian> { |
677 | | /// The UUID of this subcache. |
678 | | pub uuid: [u8; 16], |
679 | | /// The offset of this subcache from the main cache base address. |
680 | | pub cache_vm_offset: U64<E>, |
681 | | /// The file name suffix of the subCache file, e.g. ".25.data" or ".03.development". |
682 | | pub file_suffix: [u8; 32], |
683 | | } |
684 | | |
685 | | // Definitions from "/usr/include/mach-o/loader.h". |
686 | | |
687 | | /* |
688 | | * This header file describes the structures of the file format for "fat" |
689 | | * architecture specific file (wrapper design). At the beginning of the file |
690 | | * there is one `FatHeader` structure followed by a number of `FatArch*` |
691 | | * structures. For each architecture in the file, specified by a pair of |
692 | | * cputype and cpusubtype, the `FatHeader` describes the file offset, file |
693 | | * size and alignment in the file of the architecture specific member. |
694 | | * The padded bytes in the file to place each member on it's specific alignment |
695 | | * are defined to be read as zeros and can be left as "holes" if the file system |
696 | | * can support them as long as they read as zeros. |
697 | | * |
698 | | * All structures defined here are always written and read to/from disk |
699 | | * in big-endian order. |
700 | | */ |
701 | | |
702 | | pub const FAT_MAGIC: u32 = 0xcafe_babe; |
703 | | /// NXSwapLong(FAT_MAGIC) |
704 | | pub const FAT_CIGAM: u32 = 0xbeba_feca; |
705 | | |
706 | | #[derive(Debug, Clone, Copy)] |
707 | | #[repr(C)] |
708 | | pub struct FatHeader { |
709 | | /// FAT_MAGIC or FAT_MAGIC_64 |
710 | | pub magic: U32<BigEndian>, |
711 | | /// number of structs that follow |
712 | | pub nfat_arch: U32<BigEndian>, |
713 | | } |
714 | | |
715 | | #[derive(Debug, Clone, Copy)] |
716 | | #[repr(C)] |
717 | | pub struct FatArch32 { |
718 | | /// cpu specifier (int) |
719 | | pub cputype: U32<BigEndian>, |
720 | | /// machine specifier (int) |
721 | | pub cpusubtype: U32<BigEndian>, |
722 | | /// file offset to this object file |
723 | | pub offset: U32<BigEndian>, |
724 | | /// size of this object file |
725 | | pub size: U32<BigEndian>, |
726 | | /// alignment as a power of 2 |
727 | | pub align: U32<BigEndian>, |
728 | | } |
729 | | |
730 | | /* |
731 | | * The support for the 64-bit fat file format described here is a work in |
732 | | * progress and not yet fully supported in all the Apple Developer Tools. |
733 | | * |
734 | | * When a slice is greater than 4mb or an offset to a slice is greater than 4mb |
735 | | * then the 64-bit fat file format is used. |
736 | | */ |
737 | | pub const FAT_MAGIC_64: u32 = 0xcafe_babf; |
738 | | /// NXSwapLong(FAT_MAGIC_64) |
739 | | pub const FAT_CIGAM_64: u32 = 0xbfba_feca; |
740 | | |
741 | | #[derive(Debug, Clone, Copy)] |
742 | | #[repr(C)] |
743 | | pub struct FatArch64 { |
744 | | /// cpu specifier (int) |
745 | | pub cputype: U32<BigEndian>, |
746 | | /// machine specifier (int) |
747 | | pub cpusubtype: U32<BigEndian>, |
748 | | /// file offset to this object file |
749 | | pub offset: U64<BigEndian>, |
750 | | /// size of this object file |
751 | | pub size: U64<BigEndian>, |
752 | | /// alignment as a power of 2 |
753 | | pub align: U32<BigEndian>, |
754 | | /// reserved |
755 | | pub reserved: U32<BigEndian>, |
756 | | } |
757 | | |
758 | | // Definitions from "/usr/include/mach-o/loader.h". |
759 | | |
760 | | /// The 32-bit mach header. |
761 | | /// |
762 | | /// Appears at the very beginning of the object file for 32-bit architectures. |
763 | | #[derive(Debug, Clone, Copy)] |
764 | | #[repr(C)] |
765 | | pub struct MachHeader32<E: Endian> { |
766 | | /// mach magic number identifier |
767 | | pub magic: U32<BigEndian>, |
768 | | /// cpu specifier |
769 | | pub cputype: U32<E>, |
770 | | /// machine specifier |
771 | | pub cpusubtype: U32<E>, |
772 | | /// type of file |
773 | | pub filetype: U32<E>, |
774 | | /// number of load commands |
775 | | pub ncmds: U32<E>, |
776 | | /// the size of all the load commands |
777 | | pub sizeofcmds: U32<E>, |
778 | | /// flags |
779 | | pub flags: U32<E>, |
780 | | } |
781 | | |
782 | | // Values for `MachHeader32::magic`. |
783 | | /// the mach magic number |
784 | | pub const MH_MAGIC: u32 = 0xfeed_face; |
785 | | /// NXSwapInt(MH_MAGIC) |
786 | | pub const MH_CIGAM: u32 = 0xcefa_edfe; |
787 | | |
788 | | /// The 64-bit mach header. |
789 | | /// |
790 | | /// Appears at the very beginning of object files for 64-bit architectures. |
791 | | #[derive(Debug, Clone, Copy)] |
792 | | #[repr(C)] |
793 | | pub struct MachHeader64<E: Endian> { |
794 | | /// mach magic number identifier |
795 | | pub magic: U32<BigEndian>, |
796 | | /// cpu specifier |
797 | | pub cputype: U32<E>, |
798 | | /// machine specifier |
799 | | pub cpusubtype: U32<E>, |
800 | | /// type of file |
801 | | pub filetype: U32<E>, |
802 | | /// number of load commands |
803 | | pub ncmds: U32<E>, |
804 | | /// the size of all the load commands |
805 | | pub sizeofcmds: U32<E>, |
806 | | /// flags |
807 | | pub flags: U32<E>, |
808 | | /// reserved |
809 | | pub reserved: U32<E>, |
810 | | } |
811 | | |
812 | | // Values for `MachHeader64::magic`. |
813 | | /// the 64-bit mach magic number |
814 | | pub const MH_MAGIC_64: u32 = 0xfeed_facf; |
815 | | /// NXSwapInt(MH_MAGIC_64) |
816 | | pub const MH_CIGAM_64: u32 = 0xcffa_edfe; |
817 | | |
818 | | /* |
819 | | * The layout of the file depends on the filetype. For all but the MH_OBJECT |
820 | | * file type the segments are padded out and aligned on a segment alignment |
821 | | * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, |
822 | | * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part |
823 | | * of their first segment. |
824 | | * |
825 | | * The file type MH_OBJECT is a compact format intended as output of the |
826 | | * assembler and input (and possibly output) of the link editor (the .o |
827 | | * format). All sections are in one unnamed segment with no segment padding. |
828 | | * This format is used as an executable format when the file is so small the |
829 | | * segment padding greatly increases its size. |
830 | | * |
831 | | * The file type MH_PRELOAD is an executable format intended for things that |
832 | | * are not executed under the kernel (proms, stand alones, kernels, etc). The |
833 | | * format can be executed under the kernel but may demand paged it and not |
834 | | * preload it before execution. |
835 | | * |
836 | | * A core file is in MH_CORE format and can be any in an arbritray legal |
837 | | * Mach-O file. |
838 | | */ |
839 | | |
840 | | // Values for `MachHeader*::filetype`. |
841 | | /// relocatable object file |
842 | | pub const MH_OBJECT: u32 = 0x1; |
843 | | /// demand paged executable file |
844 | | pub const MH_EXECUTE: u32 = 0x2; |
845 | | /// fixed VM shared library file |
846 | | pub const MH_FVMLIB: u32 = 0x3; |
847 | | /// core file |
848 | | pub const MH_CORE: u32 = 0x4; |
849 | | /// preloaded executable file |
850 | | pub const MH_PRELOAD: u32 = 0x5; |
851 | | /// dynamically bound shared library |
852 | | pub const MH_DYLIB: u32 = 0x6; |
853 | | /// dynamic link editor |
854 | | pub const MH_DYLINKER: u32 = 0x7; |
855 | | /// dynamically bound bundle file |
856 | | pub const MH_BUNDLE: u32 = 0x8; |
857 | | /// shared library stub for static linking only, no section contents |
858 | | pub const MH_DYLIB_STUB: u32 = 0x9; |
859 | | /// companion file with only debug sections |
860 | | pub const MH_DSYM: u32 = 0xa; |
861 | | /// x86_64 kexts |
862 | | pub const MH_KEXT_BUNDLE: u32 = 0xb; |
863 | | /// set of mach-o's |
864 | | pub const MH_FILESET: u32 = 0xc; |
865 | | |
866 | | // Values for `MachHeader*::flags`. |
867 | | /// the object file has no undefined references |
868 | | pub const MH_NOUNDEFS: u32 = 0x1; |
869 | | /// the object file is the output of an incremental link against a base file and can't be link edited again |
870 | | pub const MH_INCRLINK: u32 = 0x2; |
871 | | /// the object file is input for the dynamic linker and can't be statically link edited again |
872 | | pub const MH_DYLDLINK: u32 = 0x4; |
873 | | /// the object file's undefined references are bound by the dynamic linker when loaded. |
874 | | pub const MH_BINDATLOAD: u32 = 0x8; |
875 | | /// the file has its dynamic undefined references prebound. |
876 | | pub const MH_PREBOUND: u32 = 0x10; |
877 | | /// the file has its read-only and read-write segments split |
878 | | pub const MH_SPLIT_SEGS: u32 = 0x20; |
879 | | /// the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) |
880 | | pub const MH_LAZY_INIT: u32 = 0x40; |
881 | | /// the image is using two-level name space bindings |
882 | | pub const MH_TWOLEVEL: u32 = 0x80; |
883 | | /// the executable is forcing all images to use flat name space bindings |
884 | | pub const MH_FORCE_FLAT: u32 = 0x100; |
885 | | /// this umbrella guarantees no multiple definitions of symbols in its sub-images so the two-level namespace hints can always be used. |
886 | | pub const MH_NOMULTIDEFS: u32 = 0x200; |
887 | | /// do not have dyld notify the prebinding agent about this executable |
888 | | pub const MH_NOFIXPREBINDING: u32 = 0x400; |
889 | | /// the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set. |
890 | | pub const MH_PREBINDABLE: u32 = 0x800; |
891 | | /// indicates that this binary binds to all two-level namespace modules of its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set. |
892 | | pub const MH_ALLMODSBOUND: u32 = 0x1000; |
893 | | /// safe to divide up the sections into sub-sections via symbols for dead code stripping |
894 | | pub const MH_SUBSECTIONS_VIA_SYMBOLS: u32 = 0x2000; |
895 | | /// the binary has been canonicalized via the unprebind operation |
896 | | pub const MH_CANONICAL: u32 = 0x4000; |
897 | | /// the final linked image contains external weak symbols |
898 | | pub const MH_WEAK_DEFINES: u32 = 0x8000; |
899 | | /// the final linked image uses weak symbols |
900 | | pub const MH_BINDS_TO_WEAK: u32 = 0x10000; |
901 | | /// When this bit is set, all stacks in the task will be given stack execution privilege. Only used in MH_EXECUTE filetypes. |
902 | | pub const MH_ALLOW_STACK_EXECUTION: u32 = 0x20000; |
903 | | /// When this bit is set, the binary declares it is safe for use in processes with uid zero |
904 | | pub const MH_ROOT_SAFE: u32 = 0x40000; |
905 | | /// When this bit is set, the binary declares it is safe for use in processes when issetugid() is true |
906 | | pub const MH_SETUID_SAFE: u32 = 0x80000; |
907 | | /// When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported |
908 | | pub const MH_NO_REEXPORTED_DYLIBS: u32 = 0x10_0000; |
909 | | /// When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes. |
910 | | pub const MH_PIE: u32 = 0x20_0000; |
911 | | /// Only for use on dylibs. When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIB load command to the dylib if no symbols are being referenced from the dylib. |
912 | | pub const MH_DEAD_STRIPPABLE_DYLIB: u32 = 0x40_0000; |
913 | | /// Contains a section of type S_THREAD_LOCAL_VARIABLES |
914 | | pub const MH_HAS_TLV_DESCRIPTORS: u32 = 0x80_0000; |
915 | | /// When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it. Only used in MH_EXECUTE filetypes. |
916 | | pub const MH_NO_HEAP_EXECUTION: u32 = 0x100_0000; |
917 | | /// The code was linked for use in an application extension. |
918 | | pub const MH_APP_EXTENSION_SAFE: u32 = 0x0200_0000; |
919 | | /// The external symbols listed in the nlist symbol table do not include all the symbols listed in the dyld info. |
920 | | pub const MH_NLIST_OUTOFSYNC_WITH_DYLDINFO: u32 = 0x0400_0000; |
921 | | /// Allow LC_MIN_VERSION_MACOS and LC_BUILD_VERSION load commands with |
922 | | /// the platforms macOS, iOSMac, iOSSimulator, tvOSSimulator and watchOSSimulator. |
923 | | pub const MH_SIM_SUPPORT: u32 = 0x0800_0000; |
924 | | /// Only for use on dylibs. When this bit is set, the dylib is part of the dyld |
925 | | /// shared cache, rather than loose in the filesystem. |
926 | | pub const MH_DYLIB_IN_CACHE: u32 = 0x8000_0000; |
927 | | |
928 | | /// Common fields at the start of every load command. |
929 | | /// |
930 | | /// The load commands directly follow the mach_header. The total size of all |
931 | | /// of the commands is given by the sizeofcmds field in the mach_header. All |
932 | | /// load commands must have as their first two fields `cmd` and `cmdsize`. The `cmd` |
933 | | /// field is filled in with a constant for that command type. Each command type |
934 | | /// has a structure specifically for it. The `cmdsize` field is the size in bytes |
935 | | /// of the particular load command structure plus anything that follows it that |
936 | | /// is a part of the load command (i.e. section structures, strings, etc.). To |
937 | | /// advance to the next load command the `cmdsize` can be added to the offset or |
938 | | /// pointer of the current load command. The `cmdsize` for 32-bit architectures |
939 | | /// MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple |
940 | | /// of 8 bytes (these are forever the maximum alignment of any load commands). |
941 | | /// The padded bytes must be zero. All tables in the object file must also |
942 | | /// follow these rules so the file can be memory mapped. Otherwise the pointers |
943 | | /// to these tables will not work well or at all on some machines. With all |
944 | | /// padding zeroed like objects will compare byte for byte. |
945 | | #[derive(Debug, Clone, Copy)] |
946 | | #[repr(C)] |
947 | | pub struct LoadCommand<E: Endian> { |
948 | | /// Type of load command. |
949 | | /// |
950 | | /// One of the `LC_*` constants. |
951 | | pub cmd: U32<E>, |
952 | | /// Total size of command in bytes. |
953 | | pub cmdsize: U32<E>, |
954 | | } |
955 | | |
956 | | /* |
957 | | * After MacOS X 10.1 when a new load command is added that is required to be |
958 | | * understood by the dynamic linker for the image to execute properly the |
959 | | * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic |
960 | | * linker sees such a load command it it does not understand will issue a |
961 | | * "unknown load command required for execution" error and refuse to use the |
962 | | * image. Other load commands without this bit that are not understood will |
963 | | * simply be ignored. |
964 | | */ |
965 | | pub const LC_REQ_DYLD: u32 = 0x8000_0000; |
966 | | |
967 | | /* Constants for the cmd field of all load commands, the type */ |
968 | | /// segment of this file to be mapped |
969 | | pub const LC_SEGMENT: u32 = 0x1; |
970 | | /// link-edit stab symbol table info |
971 | | pub const LC_SYMTAB: u32 = 0x2; |
972 | | /// link-edit gdb symbol table info (obsolete) |
973 | | pub const LC_SYMSEG: u32 = 0x3; |
974 | | /// thread |
975 | | pub const LC_THREAD: u32 = 0x4; |
976 | | /// unix thread (includes a stack) |
977 | | pub const LC_UNIXTHREAD: u32 = 0x5; |
978 | | /// load a specified fixed VM shared library |
979 | | pub const LC_LOADFVMLIB: u32 = 0x6; |
980 | | /// fixed VM shared library identification |
981 | | pub const LC_IDFVMLIB: u32 = 0x7; |
982 | | /// object identification info (obsolete) |
983 | | pub const LC_IDENT: u32 = 0x8; |
984 | | /// fixed VM file inclusion (internal use) |
985 | | pub const LC_FVMFILE: u32 = 0x9; |
986 | | /// prepage command (internal use) |
987 | | pub const LC_PREPAGE: u32 = 0xa; |
988 | | /// dynamic link-edit symbol table info |
989 | | pub const LC_DYSYMTAB: u32 = 0xb; |
990 | | /// load a dynamically linked shared library |
991 | | pub const LC_LOAD_DYLIB: u32 = 0xc; |
992 | | /// dynamically linked shared lib ident |
993 | | pub const LC_ID_DYLIB: u32 = 0xd; |
994 | | /// load a dynamic linker |
995 | | pub const LC_LOAD_DYLINKER: u32 = 0xe; |
996 | | /// dynamic linker identification |
997 | | pub const LC_ID_DYLINKER: u32 = 0xf; |
998 | | /// modules prebound for a dynamically linked shared library |
999 | | pub const LC_PREBOUND_DYLIB: u32 = 0x10; |
1000 | | /// image routines |
1001 | | pub const LC_ROUTINES: u32 = 0x11; |
1002 | | /// sub framework |
1003 | | pub const LC_SUB_FRAMEWORK: u32 = 0x12; |
1004 | | /// sub umbrella |
1005 | | pub const LC_SUB_UMBRELLA: u32 = 0x13; |
1006 | | /// sub client |
1007 | | pub const LC_SUB_CLIENT: u32 = 0x14; |
1008 | | /// sub library |
1009 | | pub const LC_SUB_LIBRARY: u32 = 0x15; |
1010 | | /// two-level namespace lookup hints |
1011 | | pub const LC_TWOLEVEL_HINTS: u32 = 0x16; |
1012 | | /// prebind checksum |
1013 | | pub const LC_PREBIND_CKSUM: u32 = 0x17; |
1014 | | /// load a dynamically linked shared library that is allowed to be missing |
1015 | | /// (all symbols are weak imported). |
1016 | | pub const LC_LOAD_WEAK_DYLIB: u32 = 0x18 | LC_REQ_DYLD; |
1017 | | /// 64-bit segment of this file to be mapped |
1018 | | pub const LC_SEGMENT_64: u32 = 0x19; |
1019 | | /// 64-bit image routines |
1020 | | pub const LC_ROUTINES_64: u32 = 0x1a; |
1021 | | /// the uuid |
1022 | | pub const LC_UUID: u32 = 0x1b; |
1023 | | /// runpath additions |
1024 | | pub const LC_RPATH: u32 = 0x1c | LC_REQ_DYLD; |
1025 | | /// local of code signature |
1026 | | pub const LC_CODE_SIGNATURE: u32 = 0x1d; |
1027 | | /// local of info to split segments |
1028 | | pub const LC_SEGMENT_SPLIT_INFO: u32 = 0x1e; |
1029 | | /// load and re-export dylib |
1030 | | pub const LC_REEXPORT_DYLIB: u32 = 0x1f | LC_REQ_DYLD; |
1031 | | /// delay load of dylib until first use |
1032 | | pub const LC_LAZY_LOAD_DYLIB: u32 = 0x20; |
1033 | | /// encrypted segment information |
1034 | | pub const LC_ENCRYPTION_INFO: u32 = 0x21; |
1035 | | /// compressed dyld information |
1036 | | pub const LC_DYLD_INFO: u32 = 0x22; |
1037 | | /// compressed dyld information only |
1038 | | pub const LC_DYLD_INFO_ONLY: u32 = 0x22 | LC_REQ_DYLD; |
1039 | | /// load upward dylib |
1040 | | pub const LC_LOAD_UPWARD_DYLIB: u32 = 0x23 | LC_REQ_DYLD; |
1041 | | /// build for MacOSX min OS version |
1042 | | pub const LC_VERSION_MIN_MACOSX: u32 = 0x24; |
1043 | | /// build for iPhoneOS min OS version |
1044 | | pub const LC_VERSION_MIN_IPHONEOS: u32 = 0x25; |
1045 | | /// compressed table of function start addresses |
1046 | | pub const LC_FUNCTION_STARTS: u32 = 0x26; |
1047 | | /// string for dyld to treat like environment variable |
1048 | | pub const LC_DYLD_ENVIRONMENT: u32 = 0x27; |
1049 | | /// replacement for LC_UNIXTHREAD |
1050 | | pub const LC_MAIN: u32 = 0x28 | LC_REQ_DYLD; |
1051 | | /// table of non-instructions in __text |
1052 | | pub const LC_DATA_IN_CODE: u32 = 0x29; |
1053 | | /// source version used to build binary |
1054 | | pub const LC_SOURCE_VERSION: u32 = 0x2A; |
1055 | | /// Code signing DRs copied from linked dylibs |
1056 | | pub const LC_DYLIB_CODE_SIGN_DRS: u32 = 0x2B; |
1057 | | /// 64-bit encrypted segment information |
1058 | | pub const LC_ENCRYPTION_INFO_64: u32 = 0x2C; |
1059 | | /// linker options in MH_OBJECT files |
1060 | | pub const LC_LINKER_OPTION: u32 = 0x2D; |
1061 | | /// optimization hints in MH_OBJECT files |
1062 | | pub const LC_LINKER_OPTIMIZATION_HINT: u32 = 0x2E; |
1063 | | /// build for AppleTV min OS version |
1064 | | pub const LC_VERSION_MIN_TVOS: u32 = 0x2F; |
1065 | | /// build for Watch min OS version |
1066 | | pub const LC_VERSION_MIN_WATCHOS: u32 = 0x30; |
1067 | | /// arbitrary data included within a Mach-O file |
1068 | | pub const LC_NOTE: u32 = 0x31; |
1069 | | /// build for platform min OS version |
1070 | | pub const LC_BUILD_VERSION: u32 = 0x32; |
1071 | | /// used with `LinkeditDataCommand`, payload is trie |
1072 | | pub const LC_DYLD_EXPORTS_TRIE: u32 = 0x33 | LC_REQ_DYLD; |
1073 | | /// used with `LinkeditDataCommand` |
1074 | | pub const LC_DYLD_CHAINED_FIXUPS: u32 = 0x34 | LC_REQ_DYLD; |
1075 | | /// used with `FilesetEntryCommand` |
1076 | | pub const LC_FILESET_ENTRY: u32 = 0x35 | LC_REQ_DYLD; |
1077 | | |
1078 | | /// A variable length string in a load command. |
1079 | | /// |
1080 | | /// The strings are stored just after the load command structure and |
1081 | | /// the offset is from the start of the load command structure. The size |
1082 | | /// of the string is reflected in the `cmdsize` field of the load command. |
1083 | | /// Once again any padded bytes to bring the `cmdsize` field to a multiple |
1084 | | /// of 4 bytes must be zero. |
1085 | | #[derive(Debug, Clone, Copy)] |
1086 | | #[repr(C)] |
1087 | | pub struct LcStr<E: Endian> { |
1088 | | /// offset to the string |
1089 | | pub offset: U32<E>, |
1090 | | } |
1091 | | |
1092 | | /// 32-bit segment load command. |
1093 | | /// |
1094 | | /// The segment load command indicates that a part of this file is to be |
1095 | | /// mapped into the task's address space. The size of this segment in memory, |
1096 | | /// vmsize, maybe equal to or larger than the amount to map from this file, |
1097 | | /// filesize. The file is mapped starting at fileoff to the beginning of |
1098 | | /// the segment in memory, vmaddr. The rest of the memory of the segment, |
1099 | | /// if any, is allocated zero fill on demand. The segment's maximum virtual |
1100 | | /// memory protection and initial virtual memory protection are specified |
1101 | | /// by the maxprot and initprot fields. If the segment has sections then the |
1102 | | /// `Section32` structures directly follow the segment command and their size is |
1103 | | /// reflected in `cmdsize`. |
1104 | | #[derive(Debug, Clone, Copy)] |
1105 | | #[repr(C)] |
1106 | | pub struct SegmentCommand32<E: Endian> { |
1107 | | /// LC_SEGMENT |
1108 | | pub cmd: U32<E>, |
1109 | | /// includes sizeof section structs |
1110 | | pub cmdsize: U32<E>, |
1111 | | /// segment name |
1112 | | pub segname: [u8; 16], |
1113 | | /// memory address of this segment |
1114 | | pub vmaddr: U32<E>, |
1115 | | /// memory size of this segment |
1116 | | pub vmsize: U32<E>, |
1117 | | /// file offset of this segment |
1118 | | pub fileoff: U32<E>, |
1119 | | /// amount to map from the file |
1120 | | pub filesize: U32<E>, |
1121 | | /// maximum VM protection |
1122 | | pub maxprot: U32<E>, |
1123 | | /// initial VM protection |
1124 | | pub initprot: U32<E>, |
1125 | | /// number of sections in segment |
1126 | | pub nsects: U32<E>, |
1127 | | /// flags |
1128 | | pub flags: U32<E>, |
1129 | | } |
1130 | | |
1131 | | /// 64-bit segment load command. |
1132 | | /// |
1133 | | /// The 64-bit segment load command indicates that a part of this file is to be |
1134 | | /// mapped into a 64-bit task's address space. If the 64-bit segment has |
1135 | | /// sections then `Section64` structures directly follow the 64-bit segment |
1136 | | /// command and their size is reflected in `cmdsize`. |
1137 | | #[derive(Debug, Clone, Copy)] |
1138 | | #[repr(C)] |
1139 | | pub struct SegmentCommand64<E: Endian> { |
1140 | | /// LC_SEGMENT_64 |
1141 | | pub cmd: U32<E>, |
1142 | | /// includes sizeof section_64 structs |
1143 | | pub cmdsize: U32<E>, |
1144 | | /// segment name |
1145 | | pub segname: [u8; 16], |
1146 | | /// memory address of this segment |
1147 | | pub vmaddr: U64<E>, |
1148 | | /// memory size of this segment |
1149 | | pub vmsize: U64<E>, |
1150 | | /// file offset of this segment |
1151 | | pub fileoff: U64<E>, |
1152 | | /// amount to map from the file |
1153 | | pub filesize: U64<E>, |
1154 | | /// maximum VM protection |
1155 | | pub maxprot: U32<E>, |
1156 | | /// initial VM protection |
1157 | | pub initprot: U32<E>, |
1158 | | /// number of sections in segment |
1159 | | pub nsects: U32<E>, |
1160 | | /// flags |
1161 | | pub flags: U32<E>, |
1162 | | } |
1163 | | |
1164 | | // Values for `SegmentCommand*::flags`. |
1165 | | /// the file contents for this segment is for the high part of the VM space, the low part is zero filled (for stacks in core files) |
1166 | | pub const SG_HIGHVM: u32 = 0x1; |
1167 | | /// this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor |
1168 | | pub const SG_FVMLIB: u32 = 0x2; |
1169 | | /// this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation |
1170 | | pub const SG_NORELOC: u32 = 0x4; |
1171 | | /// This segment is protected. If the segment starts at file offset 0, the first page of the segment is not protected. All other pages of the segment are protected. |
1172 | | pub const SG_PROTECTED_VERSION_1: u32 = 0x8; |
1173 | | /// This segment is made read-only after fixups |
1174 | | pub const SG_READ_ONLY: u32 = 0x10; |
1175 | | |
1176 | | /* |
1177 | | * A segment is made up of zero or more sections. Non-MH_OBJECT files have |
1178 | | * all of their segments with the proper sections in each, and padded to the |
1179 | | * specified segment alignment when produced by the link editor. The first |
1180 | | * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header |
1181 | | * and load commands of the object file before its first section. The zero |
1182 | | * fill sections are always last in their segment (in all formats). This |
1183 | | * allows the zeroed segment padding to be mapped into memory where zero fill |
1184 | | * sections might be. The gigabyte zero fill sections, those with the section |
1185 | | * type S_GB_ZEROFILL, can only be in a segment with sections of this type. |
1186 | | * These segments are then placed after all other segments. |
1187 | | * |
1188 | | * The MH_OBJECT format has all of its sections in one segment for |
1189 | | * compactness. There is no padding to a specified segment boundary and the |
1190 | | * mach_header and load commands are not part of the segment. |
1191 | | * |
1192 | | * Sections with the same section name, sectname, going into the same segment, |
1193 | | * segname, are combined by the link editor. The resulting section is aligned |
1194 | | * to the maximum alignment of the combined sections and is the new section's |
1195 | | * alignment. The combined sections are aligned to their original alignment in |
1196 | | * the combined section. Any padded bytes to get the specified alignment are |
1197 | | * zeroed. |
1198 | | * |
1199 | | * The format of the relocation entries referenced by the reloff and nreloc |
1200 | | * fields of the section structure for mach object files is described in the |
1201 | | * header file <reloc.h>. |
1202 | | */ |
1203 | | /// 32-bit section. |
1204 | | #[derive(Debug, Clone, Copy)] |
1205 | | #[repr(C)] |
1206 | | pub struct Section32<E: Endian> { |
1207 | | /// name of this section |
1208 | | pub sectname: [u8; 16], |
1209 | | /// segment this section goes in |
1210 | | pub segname: [u8; 16], |
1211 | | /// memory address of this section |
1212 | | pub addr: U32<E>, |
1213 | | /// size in bytes of this section |
1214 | | pub size: U32<E>, |
1215 | | /// file offset of this section |
1216 | | pub offset: U32<E>, |
1217 | | /// section alignment (power of 2) |
1218 | | pub align: U32<E>, |
1219 | | /// file offset of relocation entries |
1220 | | pub reloff: U32<E>, |
1221 | | /// number of relocation entries |
1222 | | pub nreloc: U32<E>, |
1223 | | /// flags (section type and attributes) |
1224 | | pub flags: U32<E>, |
1225 | | /// reserved (for offset or index) |
1226 | | pub reserved1: U32<E>, |
1227 | | /// reserved (for count or sizeof) |
1228 | | pub reserved2: U32<E>, |
1229 | | } |
1230 | | |
1231 | | /// 64-bit section. |
1232 | | #[derive(Debug, Clone, Copy)] |
1233 | | #[repr(C)] |
1234 | | pub struct Section64<E: Endian> { |
1235 | | /// name of this section |
1236 | | pub sectname: [u8; 16], |
1237 | | /// segment this section goes in |
1238 | | pub segname: [u8; 16], |
1239 | | /// memory address of this section |
1240 | | pub addr: U64<E>, |
1241 | | /// size in bytes of this section |
1242 | | pub size: U64<E>, |
1243 | | /// file offset of this section |
1244 | | pub offset: U32<E>, |
1245 | | /// section alignment (power of 2) |
1246 | | pub align: U32<E>, |
1247 | | /// file offset of relocation entries |
1248 | | pub reloff: U32<E>, |
1249 | | /// number of relocation entries |
1250 | | pub nreloc: U32<E>, |
1251 | | /// flags (section type and attributes) |
1252 | | pub flags: U32<E>, |
1253 | | /// reserved (for offset or index) |
1254 | | pub reserved1: U32<E>, |
1255 | | /// reserved (for count or sizeof) |
1256 | | pub reserved2: U32<E>, |
1257 | | /// reserved |
1258 | | pub reserved3: U32<E>, |
1259 | | } |
1260 | | |
1261 | | /* |
1262 | | * The flags field of a section structure is separated into two parts a section |
1263 | | * type and section attributes. The section types are mutually exclusive (it |
1264 | | * can only have one type) but the section attributes are not (it may have more |
1265 | | * than one attribute). |
1266 | | */ |
1267 | | /// 256 section types |
1268 | | pub const SECTION_TYPE: u32 = 0x0000_00ff; |
1269 | | /// 24 section attributes |
1270 | | pub const SECTION_ATTRIBUTES: u32 = 0xffff_ff00; |
1271 | | |
1272 | | /* Constants for the type of a section */ |
1273 | | /// regular section |
1274 | | pub const S_REGULAR: u32 = 0x0; |
1275 | | /// zero fill on demand section |
1276 | | pub const S_ZEROFILL: u32 = 0x1; |
1277 | | /// section with only literal C strings |
1278 | | pub const S_CSTRING_LITERALS: u32 = 0x2; |
1279 | | /// section with only 4 byte literals |
1280 | | pub const S_4BYTE_LITERALS: u32 = 0x3; |
1281 | | /// section with only 8 byte literals |
1282 | | pub const S_8BYTE_LITERALS: u32 = 0x4; |
1283 | | /// section with only pointers to literals |
1284 | | pub const S_LITERAL_POINTERS: u32 = 0x5; |
1285 | | /* |
1286 | | * For the two types of symbol pointers sections and the symbol stubs section |
1287 | | * they have indirect symbol table entries. For each of the entries in the |
1288 | | * section the indirect symbol table entries, in corresponding order in the |
1289 | | * indirect symbol table, start at the index stored in the reserved1 field |
1290 | | * of the section structure. Since the indirect symbol table entries |
1291 | | * correspond to the entries in the section the number of indirect symbol table |
1292 | | * entries is inferred from the size of the section divided by the size of the |
1293 | | * entries in the section. For symbol pointers sections the size of the entries |
1294 | | * in the section is 4 bytes and for symbol stubs sections the byte size of the |
1295 | | * stubs is stored in the reserved2 field of the section structure. |
1296 | | */ |
1297 | | /// section with only non-lazy symbol pointers |
1298 | | pub const S_NON_LAZY_SYMBOL_POINTERS: u32 = 0x6; |
1299 | | /// section with only lazy symbol pointers |
1300 | | pub const S_LAZY_SYMBOL_POINTERS: u32 = 0x7; |
1301 | | /// section with only symbol stubs, byte size of stub in the reserved2 field |
1302 | | pub const S_SYMBOL_STUBS: u32 = 0x8; |
1303 | | /// section with only function pointers for initialization |
1304 | | pub const S_MOD_INIT_FUNC_POINTERS: u32 = 0x9; |
1305 | | /// section with only function pointers for termination |
1306 | | pub const S_MOD_TERM_FUNC_POINTERS: u32 = 0xa; |
1307 | | /// section contains symbols that are to be coalesced |
1308 | | pub const S_COALESCED: u32 = 0xb; |
1309 | | /// zero fill on demand section (that can be larger than 4 gigabytes) |
1310 | | pub const S_GB_ZEROFILL: u32 = 0xc; |
1311 | | /// section with only pairs of function pointers for interposing |
1312 | | pub const S_INTERPOSING: u32 = 0xd; |
1313 | | /// section with only 16 byte literals |
1314 | | pub const S_16BYTE_LITERALS: u32 = 0xe; |
1315 | | /// section contains DTrace Object Format |
1316 | | pub const S_DTRACE_DOF: u32 = 0xf; |
1317 | | /// section with only lazy symbol pointers to lazy loaded dylibs |
1318 | | pub const S_LAZY_DYLIB_SYMBOL_POINTERS: u32 = 0x10; |
1319 | | /* |
1320 | | * Section types to support thread local variables |
1321 | | */ |
1322 | | /// template of initial values for TLVs |
1323 | | pub const S_THREAD_LOCAL_REGULAR: u32 = 0x11; |
1324 | | /// template of initial values for TLVs |
1325 | | pub const S_THREAD_LOCAL_ZEROFILL: u32 = 0x12; |
1326 | | /// TLV descriptors |
1327 | | pub const S_THREAD_LOCAL_VARIABLES: u32 = 0x13; |
1328 | | /// pointers to TLV descriptors |
1329 | | pub const S_THREAD_LOCAL_VARIABLE_POINTERS: u32 = 0x14; |
1330 | | /// functions to call to initialize TLV values |
1331 | | pub const S_THREAD_LOCAL_INIT_FUNCTION_POINTERS: u32 = 0x15; |
1332 | | /// 32-bit offsets to initializers |
1333 | | pub const S_INIT_FUNC_OFFSETS: u32 = 0x16; |
1334 | | |
1335 | | /* |
1336 | | * Constants for the section attributes part of the flags field of a section |
1337 | | * structure. |
1338 | | */ |
1339 | | /// User setable attributes |
1340 | | pub const SECTION_ATTRIBUTES_USR: u32 = 0xff00_0000; |
1341 | | /// section contains only true machine instructions |
1342 | | pub const S_ATTR_PURE_INSTRUCTIONS: u32 = 0x8000_0000; |
1343 | | /// section contains coalesced symbols that are not to be in a ranlib table of contents |
1344 | | pub const S_ATTR_NO_TOC: u32 = 0x4000_0000; |
1345 | | /// ok to strip static symbols in this section in files with the MH_DYLDLINK flag |
1346 | | pub const S_ATTR_STRIP_STATIC_SYMS: u32 = 0x2000_0000; |
1347 | | /// no dead stripping |
1348 | | pub const S_ATTR_NO_DEAD_STRIP: u32 = 0x1000_0000; |
1349 | | /// blocks are live if they reference live blocks |
1350 | | pub const S_ATTR_LIVE_SUPPORT: u32 = 0x0800_0000; |
1351 | | /// Used with i386 code stubs written on by dyld |
1352 | | pub const S_ATTR_SELF_MODIFYING_CODE: u32 = 0x0400_0000; |
1353 | | /* |
1354 | | * If a segment contains any sections marked with S_ATTR_DEBUG then all |
1355 | | * sections in that segment must have this attribute. No section other than |
1356 | | * a section marked with this attribute may reference the contents of this |
1357 | | * section. A section with this attribute may contain no symbols and must have |
1358 | | * a section type S_REGULAR. The static linker will not copy section contents |
1359 | | * from sections with this attribute into its output file. These sections |
1360 | | * generally contain DWARF debugging info. |
1361 | | */ |
1362 | | /// a debug section |
1363 | | pub const S_ATTR_DEBUG: u32 = 0x0200_0000; |
1364 | | /// system setable attributes |
1365 | | pub const SECTION_ATTRIBUTES_SYS: u32 = 0x00ff_ff00; |
1366 | | /// section contains some machine instructions |
1367 | | pub const S_ATTR_SOME_INSTRUCTIONS: u32 = 0x0000_0400; |
1368 | | /// section has external relocation entries |
1369 | | pub const S_ATTR_EXT_RELOC: u32 = 0x0000_0200; |
1370 | | /// section has local relocation entries |
1371 | | pub const S_ATTR_LOC_RELOC: u32 = 0x0000_0100; |
1372 | | |
1373 | | /* |
1374 | | * The names of segments and sections in them are mostly meaningless to the |
1375 | | * link-editor. But there are few things to support traditional UNIX |
1376 | | * executables that require the link-editor and assembler to use some names |
1377 | | * agreed upon by convention. |
1378 | | * |
1379 | | * The initial protection of the "__TEXT" segment has write protection turned |
1380 | | * off (not writeable). |
1381 | | * |
1382 | | * The link-editor will allocate common symbols at the end of the "__common" |
1383 | | * section in the "__DATA" segment. It will create the section and segment |
1384 | | * if needed. |
1385 | | */ |
1386 | | |
1387 | | /* The currently known segment names and the section names in those segments */ |
1388 | | |
1389 | | /// the pagezero segment which has no protections and catches NULL references for MH_EXECUTE files |
1390 | | pub const SEG_PAGEZERO: &str = "__PAGEZERO"; |
1391 | | |
1392 | | /// the tradition UNIX text segment |
1393 | | pub const SEG_TEXT: &str = "__TEXT"; |
1394 | | /// the real text part of the text section no headers, and no padding |
1395 | | pub const SECT_TEXT: &str = "__text"; |
1396 | | /// the fvmlib initialization section |
1397 | | pub const SECT_FVMLIB_INIT0: &str = "__fvmlib_init0"; |
1398 | | /// the section following the fvmlib initialization section |
1399 | | pub const SECT_FVMLIB_INIT1: &str = "__fvmlib_init1"; |
1400 | | |
1401 | | /// the tradition UNIX data segment |
1402 | | pub const SEG_DATA: &str = "__DATA"; |
1403 | | /// the real initialized data section no padding, no bss overlap |
1404 | | pub const SECT_DATA: &str = "__data"; |
1405 | | /// the real uninitialized data section no padding |
1406 | | pub const SECT_BSS: &str = "__bss"; |
1407 | | /// the section common symbols are allocated in by the link editor |
1408 | | pub const SECT_COMMON: &str = "__common"; |
1409 | | |
1410 | | /// objective-C runtime segment |
1411 | | pub const SEG_OBJC: &str = "__OBJC"; |
1412 | | /// symbol table |
1413 | | pub const SECT_OBJC_SYMBOLS: &str = "__symbol_table"; |
1414 | | /// module information |
1415 | | pub const SECT_OBJC_MODULES: &str = "__module_info"; |
1416 | | /// string table |
1417 | | pub const SECT_OBJC_STRINGS: &str = "__selector_strs"; |
1418 | | /// string table |
1419 | | pub const SECT_OBJC_REFS: &str = "__selector_refs"; |
1420 | | |
1421 | | /// the icon segment |
1422 | | pub const SEG_ICON: &str = "__ICON"; |
1423 | | /// the icon headers |
1424 | | pub const SECT_ICON_HEADER: &str = "__header"; |
1425 | | /// the icons in tiff format |
1426 | | pub const SECT_ICON_TIFF: &str = "__tiff"; |
1427 | | |
1428 | | /// the segment containing all structs created and maintained by the link editor. Created with -seglinkedit option to ld(1) for MH_EXECUTE and FVMLIB file types only |
1429 | | pub const SEG_LINKEDIT: &str = "__LINKEDIT"; |
1430 | | |
1431 | | /// the segment overlapping with linkedit containing linking information |
1432 | | pub const SEG_LINKINFO: &str = "__LINKINFO"; |
1433 | | |
1434 | | /// the unix stack segment |
1435 | | pub const SEG_UNIXSTACK: &str = "__UNIXSTACK"; |
1436 | | |
1437 | | /// the segment for the self (dyld) modifying code stubs that has read, write and execute permissions |
1438 | | pub const SEG_IMPORT: &str = "__IMPORT"; |
1439 | | |
1440 | | /* |
1441 | | * Fixed virtual memory shared libraries are identified by two things. The |
1442 | | * target pathname (the name of the library as found for execution), and the |
1443 | | * minor version number. The address of where the headers are loaded is in |
1444 | | * header_addr. (THIS IS OBSOLETE and no longer supported). |
1445 | | */ |
1446 | | #[derive(Debug, Clone, Copy)] |
1447 | | #[repr(C)] |
1448 | | pub struct Fvmlib<E: Endian> { |
1449 | | /// library's target pathname |
1450 | | pub name: LcStr<E>, |
1451 | | /// library's minor version number |
1452 | | pub minor_version: U32<E>, |
1453 | | /// library's header address |
1454 | | pub header_addr: U32<E>, |
1455 | | } |
1456 | | |
1457 | | /* |
1458 | | * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) |
1459 | | * contains a `FvmlibCommand` (cmd == LC_IDFVMLIB) to identify the library. |
1460 | | * An object that uses a fixed virtual shared library also contains a |
1461 | | * `FvmlibCommand` (cmd == LC_LOADFVMLIB) for each library it uses. |
1462 | | * (THIS IS OBSOLETE and no longer supported). |
1463 | | */ |
1464 | | #[derive(Debug, Clone, Copy)] |
1465 | | #[repr(C)] |
1466 | | pub struct FvmlibCommand<E: Endian> { |
1467 | | /// LC_IDFVMLIB or LC_LOADFVMLIB |
1468 | | pub cmd: U32<E>, |
1469 | | /// includes pathname string |
1470 | | pub cmdsize: U32<E>, |
1471 | | /// the library identification |
1472 | | pub fvmlib: Fvmlib<E>, |
1473 | | } |
1474 | | |
1475 | | /* |
1476 | | * Dynamically linked shared libraries are identified by two things. The |
1477 | | * pathname (the name of the library as found for execution), and the |
1478 | | * compatibility version number. The pathname must match and the compatibility |
1479 | | * number in the user of the library must be greater than or equal to the |
1480 | | * library being used. The time stamp is used to record the time a library was |
1481 | | * built and copied into user so it can be use to determined if the library used |
1482 | | * at runtime is exactly the same as used to built the program. |
1483 | | */ |
1484 | | #[derive(Debug, Clone, Copy)] |
1485 | | #[repr(C)] |
1486 | | pub struct Dylib<E: Endian> { |
1487 | | /// library's path name |
1488 | | pub name: LcStr<E>, |
1489 | | /// library's build time stamp |
1490 | | pub timestamp: U32<E>, |
1491 | | /// library's current version number |
1492 | | pub current_version: U32<E>, |
1493 | | /// library's compatibility vers number |
1494 | | pub compatibility_version: U32<E>, |
1495 | | } |
1496 | | |
1497 | | /* |
1498 | | * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) |
1499 | | * contains a `DylibCommand` (cmd == LC_ID_DYLIB) to identify the library. |
1500 | | * An object that uses a dynamically linked shared library also contains a |
1501 | | * `DylibCommand` (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or |
1502 | | * LC_REEXPORT_DYLIB) for each library it uses. |
1503 | | */ |
1504 | | #[derive(Debug, Clone, Copy)] |
1505 | | #[repr(C)] |
1506 | | pub struct DylibCommand<E: Endian> { |
1507 | | /// LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB |
1508 | | pub cmd: U32<E>, |
1509 | | /// includes pathname string |
1510 | | pub cmdsize: U32<E>, |
1511 | | /// the library identification |
1512 | | pub dylib: Dylib<E>, |
1513 | | } |
1514 | | |
1515 | | /* |
1516 | | * A dynamically linked shared library may be a subframework of an umbrella |
1517 | | * framework. If so it will be linked with "-umbrella umbrella_name" where |
1518 | | * Where "umbrella_name" is the name of the umbrella framework. A subframework |
1519 | | * can only be linked against by its umbrella framework or other subframeworks |
1520 | | * that are part of the same umbrella framework. Otherwise the static link |
1521 | | * editor produces an error and states to link against the umbrella framework. |
1522 | | * The name of the umbrella framework for subframeworks is recorded in the |
1523 | | * following structure. |
1524 | | */ |
1525 | | #[derive(Debug, Clone, Copy)] |
1526 | | #[repr(C)] |
1527 | | pub struct SubFrameworkCommand<E: Endian> { |
1528 | | /// LC_SUB_FRAMEWORK |
1529 | | pub cmd: U32<E>, |
1530 | | /// includes umbrella string |
1531 | | pub cmdsize: U32<E>, |
1532 | | /// the umbrella framework name |
1533 | | pub umbrella: LcStr<E>, |
1534 | | } |
1535 | | |
1536 | | /* |
1537 | | * For dynamically linked shared libraries that are subframework of an umbrella |
1538 | | * framework they can allow clients other than the umbrella framework or other |
1539 | | * subframeworks in the same umbrella framework. To do this the subframework |
1540 | | * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load |
1541 | | * command is created for each -allowable_client flag. The client_name is |
1542 | | * usually a framework name. It can also be a name used for bundles clients |
1543 | | * where the bundle is built with "-client_name client_name". |
1544 | | */ |
1545 | | #[derive(Debug, Clone, Copy)] |
1546 | | #[repr(C)] |
1547 | | pub struct SubClientCommand<E: Endian> { |
1548 | | /// LC_SUB_CLIENT |
1549 | | pub cmd: U32<E>, |
1550 | | /// includes client string |
1551 | | pub cmdsize: U32<E>, |
1552 | | /// the client name |
1553 | | pub client: LcStr<E>, |
1554 | | } |
1555 | | |
1556 | | /* |
1557 | | * A dynamically linked shared library may be a sub_umbrella of an umbrella |
1558 | | * framework. If so it will be linked with "-sub_umbrella umbrella_name" where |
1559 | | * Where "umbrella_name" is the name of the sub_umbrella framework. When |
1560 | | * statically linking when -twolevel_namespace is in effect a twolevel namespace |
1561 | | * umbrella framework will only cause its subframeworks and those frameworks |
1562 | | * listed as sub_umbrella frameworks to be implicited linked in. Any other |
1563 | | * dependent dynamic libraries will not be linked it when -twolevel_namespace |
1564 | | * is in effect. The primary library recorded by the static linker when |
1565 | | * resolving a symbol in these libraries will be the umbrella framework. |
1566 | | * Zero or more sub_umbrella frameworks may be use by an umbrella framework. |
1567 | | * The name of a sub_umbrella framework is recorded in the following structure. |
1568 | | */ |
1569 | | #[derive(Debug, Clone, Copy)] |
1570 | | #[repr(C)] |
1571 | | pub struct SubUmbrellaCommand<E: Endian> { |
1572 | | /// LC_SUB_UMBRELLA |
1573 | | pub cmd: U32<E>, |
1574 | | /// includes sub_umbrella string |
1575 | | pub cmdsize: U32<E>, |
1576 | | /// the sub_umbrella framework name |
1577 | | pub sub_umbrella: LcStr<E>, |
1578 | | } |
1579 | | |
1580 | | /* |
1581 | | * A dynamically linked shared library may be a sub_library of another shared |
1582 | | * library. If so it will be linked with "-sub_library library_name" where |
1583 | | * Where "library_name" is the name of the sub_library shared library. When |
1584 | | * statically linking when -twolevel_namespace is in effect a twolevel namespace |
1585 | | * shared library will only cause its subframeworks and those frameworks |
1586 | | * listed as sub_umbrella frameworks and libraries listed as sub_libraries to |
1587 | | * be implicited linked in. Any other dependent dynamic libraries will not be |
1588 | | * linked it when -twolevel_namespace is in effect. The primary library |
1589 | | * recorded by the static linker when resolving a symbol in these libraries |
1590 | | * will be the umbrella framework (or dynamic library). Zero or more sub_library |
1591 | | * shared libraries may be use by an umbrella framework or (or dynamic library). |
1592 | | * The name of a sub_library framework is recorded in the following structure. |
1593 | | * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". |
1594 | | */ |
1595 | | #[derive(Debug, Clone, Copy)] |
1596 | | #[repr(C)] |
1597 | | pub struct SubLibraryCommand<E: Endian> { |
1598 | | /// LC_SUB_LIBRARY |
1599 | | pub cmd: U32<E>, |
1600 | | /// includes sub_library string |
1601 | | pub cmdsize: U32<E>, |
1602 | | /// the sub_library name |
1603 | | pub sub_library: LcStr<E>, |
1604 | | } |
1605 | | |
1606 | | /* |
1607 | | * A program (filetype == MH_EXECUTE) that is |
1608 | | * prebound to its dynamic libraries has one of these for each library that |
1609 | | * the static linker used in prebinding. It contains a bit vector for the |
1610 | | * modules in the library. The bits indicate which modules are bound (1) and |
1611 | | * which are not (0) from the library. The bit for module 0 is the low bit |
1612 | | * of the first byte. So the bit for the Nth module is: |
1613 | | * (linked_modules[N/8] >> N%8) & 1 |
1614 | | */ |
1615 | | #[derive(Debug, Clone, Copy)] |
1616 | | #[repr(C)] |
1617 | | pub struct PreboundDylibCommand<E: Endian> { |
1618 | | /// LC_PREBOUND_DYLIB |
1619 | | pub cmd: U32<E>, |
1620 | | /// includes strings |
1621 | | pub cmdsize: U32<E>, |
1622 | | /// library's path name |
1623 | | pub name: LcStr<E>, |
1624 | | /// number of modules in library |
1625 | | pub nmodules: U32<E>, |
1626 | | /// bit vector of linked modules |
1627 | | pub linked_modules: LcStr<E>, |
1628 | | } |
1629 | | |
1630 | | /* |
1631 | | * A program that uses a dynamic linker contains a `DylinkerCommand` to identify |
1632 | | * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker |
1633 | | * contains a `DylinkerCommand` to identify the dynamic linker (LC_ID_DYLINKER). |
1634 | | * A file can have at most one of these. |
1635 | | * This struct is also used for the LC_DYLD_ENVIRONMENT load command and |
1636 | | * contains string for dyld to treat like environment variable. |
1637 | | */ |
1638 | | #[derive(Debug, Clone, Copy)] |
1639 | | #[repr(C)] |
1640 | | pub struct DylinkerCommand<E: Endian> { |
1641 | | /// LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT |
1642 | | pub cmd: U32<E>, |
1643 | | /// includes pathname string |
1644 | | pub cmdsize: U32<E>, |
1645 | | /// dynamic linker's path name |
1646 | | pub name: LcStr<E>, |
1647 | | } |
1648 | | |
1649 | | /* |
1650 | | * Thread commands contain machine-specific data structures suitable for |
1651 | | * use in the thread state primitives. The machine specific data structures |
1652 | | * follow the struct `ThreadCommand` as follows. |
1653 | | * Each flavor of machine specific data structure is preceded by an uint32_t |
1654 | | * constant for the flavor of that data structure, an uint32_t that is the |
1655 | | * count of uint32_t's of the size of the state data structure and then |
1656 | | * the state data structure follows. This triple may be repeated for many |
1657 | | * flavors. The constants for the flavors, counts and state data structure |
1658 | | * definitions are expected to be in the header file <machine/thread_status.h>. |
1659 | | * These machine specific data structures sizes must be multiples of |
1660 | | * 4 bytes. The `cmdsize` reflects the total size of the `ThreadCommand` |
1661 | | * and all of the sizes of the constants for the flavors, counts and state |
1662 | | * data structures. |
1663 | | * |
1664 | | * For executable objects that are unix processes there will be one |
1665 | | * `ThreadCommand` (cmd == LC_UNIXTHREAD) created for it by the link-editor. |
1666 | | * This is the same as a LC_THREAD, except that a stack is automatically |
1667 | | * created (based on the shell's limit for the stack size). Command arguments |
1668 | | * and environment variables are copied onto that stack. |
1669 | | */ |
1670 | | #[derive(Debug, Clone, Copy)] |
1671 | | #[repr(C)] |
1672 | | pub struct ThreadCommand<E: Endian> { |
1673 | | /// LC_THREAD or LC_UNIXTHREAD |
1674 | | pub cmd: U32<E>, |
1675 | | /// total size of this command |
1676 | | pub cmdsize: U32<E>, |
1677 | | /* uint32_t flavor flavor of thread state */ |
1678 | | /* uint32_t count count of uint32_t's in thread state */ |
1679 | | /* struct XXX_thread_state state thread state for this flavor */ |
1680 | | /* ... */ |
1681 | | } |
1682 | | |
1683 | | /* |
1684 | | * The routines command contains the address of the dynamic shared library |
1685 | | * initialization routine and an index into the module table for the module |
1686 | | * that defines the routine. Before any modules are used from the library the |
1687 | | * dynamic linker fully binds the module that defines the initialization routine |
1688 | | * and then calls it. This gets called before any module initialization |
1689 | | * routines (used for C++ static constructors) in the library. |
1690 | | */ |
1691 | | #[derive(Debug, Clone, Copy)] |
1692 | | #[repr(C)] |
1693 | | pub struct RoutinesCommand32<E: Endian> { |
1694 | | /* for 32-bit architectures */ |
1695 | | /// LC_ROUTINES |
1696 | | pub cmd: U32<E>, |
1697 | | /// total size of this command |
1698 | | pub cmdsize: U32<E>, |
1699 | | /// address of initialization routine |
1700 | | pub init_address: U32<E>, |
1701 | | /// index into the module table that the init routine is defined in |
1702 | | pub init_module: U32<E>, |
1703 | | pub reserved1: U32<E>, |
1704 | | pub reserved2: U32<E>, |
1705 | | pub reserved3: U32<E>, |
1706 | | pub reserved4: U32<E>, |
1707 | | pub reserved5: U32<E>, |
1708 | | pub reserved6: U32<E>, |
1709 | | } |
1710 | | |
1711 | | /* |
1712 | | * The 64-bit routines command. Same use as above. |
1713 | | */ |
1714 | | #[derive(Debug, Clone, Copy)] |
1715 | | #[repr(C)] |
1716 | | pub struct RoutinesCommand64<E: Endian> { |
1717 | | /* for 64-bit architectures */ |
1718 | | /// LC_ROUTINES_64 |
1719 | | pub cmd: U32<E>, |
1720 | | /// total size of this command |
1721 | | pub cmdsize: U32<E>, |
1722 | | /// address of initialization routine |
1723 | | pub init_address: U64<E>, |
1724 | | /// index into the module table that the init routine is defined in |
1725 | | pub init_module: U64<E>, |
1726 | | pub reserved1: U64<E>, |
1727 | | pub reserved2: U64<E>, |
1728 | | pub reserved3: U64<E>, |
1729 | | pub reserved4: U64<E>, |
1730 | | pub reserved5: U64<E>, |
1731 | | pub reserved6: U64<E>, |
1732 | | } |
1733 | | |
1734 | | /* |
1735 | | * The `SymtabCommand` contains the offsets and sizes of the link-edit 4.3BSD |
1736 | | * "stab" style symbol table information as described in the header files |
1737 | | * <nlist.h> and <stab.h>. |
1738 | | */ |
1739 | | #[derive(Debug, Clone, Copy)] |
1740 | | #[repr(C)] |
1741 | | pub struct SymtabCommand<E: Endian> { |
1742 | | /// LC_SYMTAB |
1743 | | pub cmd: U32<E>, |
1744 | | /// sizeof(struct SymtabCommand) |
1745 | | pub cmdsize: U32<E>, |
1746 | | /// symbol table offset |
1747 | | pub symoff: U32<E>, |
1748 | | /// number of symbol table entries |
1749 | | pub nsyms: U32<E>, |
1750 | | /// string table offset |
1751 | | pub stroff: U32<E>, |
1752 | | /// string table size in bytes |
1753 | | pub strsize: U32<E>, |
1754 | | } |
1755 | | |
1756 | | /* |
1757 | | * This is the second set of the symbolic information which is used to support |
1758 | | * the data structures for the dynamically link editor. |
1759 | | * |
1760 | | * The original set of symbolic information in the `SymtabCommand` which contains |
1761 | | * the symbol and string tables must also be present when this load command is |
1762 | | * present. When this load command is present the symbol table is organized |
1763 | | * into three groups of symbols: |
1764 | | * local symbols (static and debugging symbols) - grouped by module |
1765 | | * defined external symbols - grouped by module (sorted by name if not lib) |
1766 | | * undefined external symbols (sorted by name if MH_BINDATLOAD is not set, |
1767 | | * and in order the were seen by the static |
1768 | | * linker if MH_BINDATLOAD is set) |
1769 | | * In this load command there are offsets and counts to each of the three groups |
1770 | | * of symbols. |
1771 | | * |
1772 | | * This load command contains a the offsets and sizes of the following new |
1773 | | * symbolic information tables: |
1774 | | * table of contents |
1775 | | * module table |
1776 | | * reference symbol table |
1777 | | * indirect symbol table |
1778 | | * The first three tables above (the table of contents, module table and |
1779 | | * reference symbol table) are only present if the file is a dynamically linked |
1780 | | * shared library. For executable and object modules, which are files |
1781 | | * containing only one module, the information that would be in these three |
1782 | | * tables is determined as follows: |
1783 | | * table of contents - the defined external symbols are sorted by name |
1784 | | * module table - the file contains only one module so everything in the |
1785 | | * file is part of the module. |
1786 | | * reference symbol table - is the defined and undefined external symbols |
1787 | | * |
1788 | | * For dynamically linked shared library files this load command also contains |
1789 | | * offsets and sizes to the pool of relocation entries for all sections |
1790 | | * separated into two groups: |
1791 | | * external relocation entries |
1792 | | * local relocation entries |
1793 | | * For executable and object modules the relocation entries continue to hang |
1794 | | * off the section structures. |
1795 | | */ |
1796 | | #[derive(Debug, Clone, Copy)] |
1797 | | #[repr(C)] |
1798 | | pub struct DysymtabCommand<E: Endian> { |
1799 | | /// LC_DYSYMTAB |
1800 | | pub cmd: U32<E>, |
1801 | | /// sizeof(struct DysymtabCommand) |
1802 | | pub cmdsize: U32<E>, |
1803 | | |
1804 | | /* |
1805 | | * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command |
1806 | | * are grouped into the following three groups: |
1807 | | * local symbols (further grouped by the module they are from) |
1808 | | * defined external symbols (further grouped by the module they are from) |
1809 | | * undefined symbols |
1810 | | * |
1811 | | * The local symbols are used only for debugging. The dynamic binding |
1812 | | * process may have to use them to indicate to the debugger the local |
1813 | | * symbols for a module that is being bound. |
1814 | | * |
1815 | | * The last two groups are used by the dynamic binding process to do the |
1816 | | * binding (indirectly through the module table and the reference symbol |
1817 | | * table when this is a dynamically linked shared library file). |
1818 | | */ |
1819 | | /// index to local symbols |
1820 | | pub ilocalsym: U32<E>, |
1821 | | /// number of local symbols |
1822 | | pub nlocalsym: U32<E>, |
1823 | | |
1824 | | /// index to externally defined symbols |
1825 | | pub iextdefsym: U32<E>, |
1826 | | /// number of externally defined symbols |
1827 | | pub nextdefsym: U32<E>, |
1828 | | |
1829 | | /// index to undefined symbols |
1830 | | pub iundefsym: U32<E>, |
1831 | | /// number of undefined symbols |
1832 | | pub nundefsym: U32<E>, |
1833 | | |
1834 | | /* |
1835 | | * For the for the dynamic binding process to find which module a symbol |
1836 | | * is defined in the table of contents is used (analogous to the ranlib |
1837 | | * structure in an archive) which maps defined external symbols to modules |
1838 | | * they are defined in. This exists only in a dynamically linked shared |
1839 | | * library file. For executable and object modules the defined external |
1840 | | * symbols are sorted by name and is use as the table of contents. |
1841 | | */ |
1842 | | /// file offset to table of contents |
1843 | | pub tocoff: U32<E>, |
1844 | | /// number of entries in table of contents |
1845 | | pub ntoc: U32<E>, |
1846 | | |
1847 | | /* |
1848 | | * To support dynamic binding of "modules" (whole object files) the symbol |
1849 | | * table must reflect the modules that the file was created from. This is |
1850 | | * done by having a module table that has indexes and counts into the merged |
1851 | | * tables for each module. The module structure that these two entries |
1852 | | * refer to is described below. This exists only in a dynamically linked |
1853 | | * shared library file. For executable and object modules the file only |
1854 | | * contains one module so everything in the file belongs to the module. |
1855 | | */ |
1856 | | /// file offset to module table |
1857 | | pub modtaboff: U32<E>, |
1858 | | /// number of module table entries |
1859 | | pub nmodtab: U32<E>, |
1860 | | |
1861 | | /* |
1862 | | * To support dynamic module binding the module structure for each module |
1863 | | * indicates the external references (defined and undefined) each module |
1864 | | * makes. For each module there is an offset and a count into the |
1865 | | * reference symbol table for the symbols that the module references. |
1866 | | * This exists only in a dynamically linked shared library file. For |
1867 | | * executable and object modules the defined external symbols and the |
1868 | | * undefined external symbols indicates the external references. |
1869 | | */ |
1870 | | /// offset to referenced symbol table |
1871 | | pub extrefsymoff: U32<E>, |
1872 | | /// number of referenced symbol table entries |
1873 | | pub nextrefsyms: U32<E>, |
1874 | | |
1875 | | /* |
1876 | | * The sections that contain "symbol pointers" and "routine stubs" have |
1877 | | * indexes and (implied counts based on the size of the section and fixed |
1878 | | * size of the entry) into the "indirect symbol" table for each pointer |
1879 | | * and stub. For every section of these two types the index into the |
1880 | | * indirect symbol table is stored in the section header in the field |
1881 | | * reserved1. An indirect symbol table entry is simply a 32bit index into |
1882 | | * the symbol table to the symbol that the pointer or stub is referring to. |
1883 | | * The indirect symbol table is ordered to match the entries in the section. |
1884 | | */ |
1885 | | /// file offset to the indirect symbol table |
1886 | | pub indirectsymoff: U32<E>, |
1887 | | /// number of indirect symbol table entries |
1888 | | pub nindirectsyms: U32<E>, |
1889 | | |
1890 | | /* |
1891 | | * To support relocating an individual module in a library file quickly the |
1892 | | * external relocation entries for each module in the library need to be |
1893 | | * accessed efficiently. Since the relocation entries can't be accessed |
1894 | | * through the section headers for a library file they are separated into |
1895 | | * groups of local and external entries further grouped by module. In this |
1896 | | * case the presents of this load command who's extreloff, nextrel, |
1897 | | * locreloff and nlocrel fields are non-zero indicates that the relocation |
1898 | | * entries of non-merged sections are not referenced through the section |
1899 | | * structures (and the reloff and nreloc fields in the section headers are |
1900 | | * set to zero). |
1901 | | * |
1902 | | * Since the relocation entries are not accessed through the section headers |
1903 | | * this requires the r_address field to be something other than a section |
1904 | | * offset to identify the item to be relocated. In this case r_address is |
1905 | | * set to the offset from the vmaddr of the first LC_SEGMENT command. |
1906 | | * For MH_SPLIT_SEGS images r_address is set to the the offset from the |
1907 | | * vmaddr of the first read-write LC_SEGMENT command. |
1908 | | * |
1909 | | * The relocation entries are grouped by module and the module table |
1910 | | * entries have indexes and counts into them for the group of external |
1911 | | * relocation entries for that the module. |
1912 | | * |
1913 | | * For sections that are merged across modules there must not be any |
1914 | | * remaining external relocation entries for them (for merged sections |
1915 | | * remaining relocation entries must be local). |
1916 | | */ |
1917 | | /// offset to external relocation entries |
1918 | | pub extreloff: U32<E>, |
1919 | | /// number of external relocation entries |
1920 | | pub nextrel: U32<E>, |
1921 | | |
1922 | | /* |
1923 | | * All the local relocation entries are grouped together (they are not |
1924 | | * grouped by their module since they are only used if the object is moved |
1925 | | * from it statically link edited address). |
1926 | | */ |
1927 | | /// offset to local relocation entries |
1928 | | pub locreloff: U32<E>, |
1929 | | /// number of local relocation entries |
1930 | | pub nlocrel: U32<E>, |
1931 | | } |
1932 | | |
1933 | | /* |
1934 | | * An indirect symbol table entry is simply a 32bit index into the symbol table |
1935 | | * to the symbol that the pointer or stub is referring to. Unless it is for a |
1936 | | * non-lazy symbol pointer section for a defined symbol which strip(1) as |
1937 | | * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the |
1938 | | * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. |
1939 | | */ |
1940 | | pub const INDIRECT_SYMBOL_LOCAL: u32 = 0x8000_0000; |
1941 | | pub const INDIRECT_SYMBOL_ABS: u32 = 0x4000_0000; |
1942 | | |
1943 | | /* a table of contents entry */ |
1944 | | #[derive(Debug, Clone, Copy)] |
1945 | | #[repr(C)] |
1946 | | pub struct DylibTableOfContents<E: Endian> { |
1947 | | /// the defined external symbol (index into the symbol table) |
1948 | | pub symbol_index: U32<E>, |
1949 | | /// index into the module table this symbol is defined in |
1950 | | pub module_index: U32<E>, |
1951 | | } |
1952 | | |
1953 | | /* a module table entry */ |
1954 | | #[derive(Debug, Clone, Copy)] |
1955 | | #[repr(C)] |
1956 | | pub struct DylibModule32<E: Endian> { |
1957 | | /// the module name (index into string table) |
1958 | | pub module_name: U32<E>, |
1959 | | |
1960 | | /// index into externally defined symbols |
1961 | | pub iextdefsym: U32<E>, |
1962 | | /// number of externally defined symbols |
1963 | | pub nextdefsym: U32<E>, |
1964 | | /// index into reference symbol table |
1965 | | pub irefsym: U32<E>, |
1966 | | /// number of reference symbol table entries |
1967 | | pub nrefsym: U32<E>, |
1968 | | /// index into symbols for local symbols |
1969 | | pub ilocalsym: U32<E>, |
1970 | | /// number of local symbols |
1971 | | pub nlocalsym: U32<E>, |
1972 | | |
1973 | | /// index into external relocation entries |
1974 | | pub iextrel: U32<E>, |
1975 | | /// number of external relocation entries |
1976 | | pub nextrel: U32<E>, |
1977 | | |
1978 | | /// low 16 bits are the index into the init section, high 16 bits are the index into the term section |
1979 | | pub iinit_iterm: U32<E>, |
1980 | | /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries |
1981 | | pub ninit_nterm: U32<E>, |
1982 | | |
1983 | | /// for this module address of the start of the (__OBJC,__module_info) section |
1984 | | pub objc_module_info_addr: U32<E>, |
1985 | | /// for this module size of the (__OBJC,__module_info) section |
1986 | | pub objc_module_info_size: U32<E>, |
1987 | | } |
1988 | | |
1989 | | /* a 64-bit module table entry */ |
1990 | | #[derive(Debug, Clone, Copy)] |
1991 | | #[repr(C)] |
1992 | | pub struct DylibModule64<E: Endian> { |
1993 | | /// the module name (index into string table) |
1994 | | pub module_name: U32<E>, |
1995 | | |
1996 | | /// index into externally defined symbols |
1997 | | pub iextdefsym: U32<E>, |
1998 | | /// number of externally defined symbols |
1999 | | pub nextdefsym: U32<E>, |
2000 | | /// index into reference symbol table |
2001 | | pub irefsym: U32<E>, |
2002 | | /// number of reference symbol table entries |
2003 | | pub nrefsym: U32<E>, |
2004 | | /// index into symbols for local symbols |
2005 | | pub ilocalsym: U32<E>, |
2006 | | /// number of local symbols |
2007 | | pub nlocalsym: U32<E>, |
2008 | | |
2009 | | /// index into external relocation entries |
2010 | | pub iextrel: U32<E>, |
2011 | | /// number of external relocation entries |
2012 | | pub nextrel: U32<E>, |
2013 | | |
2014 | | /// low 16 bits are the index into the init section, high 16 bits are the index into the term section |
2015 | | pub iinit_iterm: U32<E>, |
2016 | | /// low 16 bits are the number of init section entries, high 16 bits are the number of term section entries |
2017 | | pub ninit_nterm: U32<E>, |
2018 | | |
2019 | | /// for this module size of the (__OBJC,__module_info) section |
2020 | | pub objc_module_info_size: U32<E>, |
2021 | | /// for this module address of the start of the (__OBJC,__module_info) section |
2022 | | pub objc_module_info_addr: U64<E>, |
2023 | | } |
2024 | | |
2025 | | /* |
2026 | | * The entries in the reference symbol table are used when loading the module |
2027 | | * (both by the static and dynamic link editors) and if the module is unloaded |
2028 | | * or replaced. Therefore all external symbols (defined and undefined) are |
2029 | | * listed in the module's reference table. The flags describe the type of |
2030 | | * reference that is being made. The constants for the flags are defined in |
2031 | | * <mach-o/nlist.h> as they are also used for symbol table entries. |
2032 | | */ |
2033 | | #[derive(Debug, Clone, Copy)] |
2034 | | #[repr(C)] |
2035 | | pub struct DylibReference<E: Endian> { |
2036 | | /* TODO: |
2037 | | uint32_t isym:24, /* index into the symbol table */ |
2038 | | flags:8; /* flags to indicate the type of reference */ |
2039 | | */ |
2040 | | pub bitfield: U32<E>, |
2041 | | } |
2042 | | |
2043 | | /* |
2044 | | * The TwolevelHintsCommand contains the offset and number of hints in the |
2045 | | * two-level namespace lookup hints table. |
2046 | | */ |
2047 | | #[derive(Debug, Clone, Copy)] |
2048 | | #[repr(C)] |
2049 | | pub struct TwolevelHintsCommand<E: Endian> { |
2050 | | /// LC_TWOLEVEL_HINTS |
2051 | | pub cmd: U32<E>, |
2052 | | /// sizeof(struct TwolevelHintsCommand) |
2053 | | pub cmdsize: U32<E>, |
2054 | | /// offset to the hint table |
2055 | | pub offset: U32<E>, |
2056 | | /// number of hints in the hint table |
2057 | | pub nhints: U32<E>, |
2058 | | } |
2059 | | |
2060 | | /* |
2061 | | * The entries in the two-level namespace lookup hints table are TwolevelHint |
2062 | | * structs. These provide hints to the dynamic link editor where to start |
2063 | | * looking for an undefined symbol in a two-level namespace image. The |
2064 | | * isub_image field is an index into the sub-images (sub-frameworks and |
2065 | | * sub-umbrellas list) that made up the two-level image that the undefined |
2066 | | * symbol was found in when it was built by the static link editor. If |
2067 | | * isub-image is 0 the the symbol is expected to be defined in library and not |
2068 | | * in the sub-images. If isub-image is non-zero it is an index into the array |
2069 | | * of sub-images for the umbrella with the first index in the sub-images being |
2070 | | * 1. The array of sub-images is the ordered list of sub-images of the umbrella |
2071 | | * that would be searched for a symbol that has the umbrella recorded as its |
2072 | | * primary library. The table of contents index is an index into the |
2073 | | * library's table of contents. This is used as the starting point of the |
2074 | | * binary search or a directed linear search. |
2075 | | */ |
2076 | | #[derive(Debug, Clone, Copy)] |
2077 | | #[repr(C)] |
2078 | | pub struct TwolevelHint<E: Endian> { |
2079 | | /* TODO: |
2080 | | uint32_t |
2081 | | isub_image:8, /* index into the sub images */ |
2082 | | itoc:24; /* index into the table of contents */ |
2083 | | */ |
2084 | | pub bitfield: U32<E>, |
2085 | | } |
2086 | | |
2087 | | /* |
2088 | | * The PrebindCksumCommand contains the value of the original check sum for |
2089 | | * prebound files or zero. When a prebound file is first created or modified |
2090 | | * for other than updating its prebinding information the value of the check sum |
2091 | | * is set to zero. When the file has it prebinding re-done and if the value of |
2092 | | * the check sum is zero the original check sum is calculated and stored in |
2093 | | * cksum field of this load command in the output file. If when the prebinding |
2094 | | * is re-done and the cksum field is non-zero it is left unchanged from the |
2095 | | * input file. |
2096 | | */ |
2097 | | #[derive(Debug, Clone, Copy)] |
2098 | | #[repr(C)] |
2099 | | pub struct PrebindCksumCommand<E: Endian> { |
2100 | | /// LC_PREBIND_CKSUM |
2101 | | pub cmd: U32<E>, |
2102 | | /// sizeof(struct PrebindCksumCommand) |
2103 | | pub cmdsize: U32<E>, |
2104 | | /// the check sum or zero |
2105 | | pub cksum: U32<E>, |
2106 | | } |
2107 | | |
2108 | | /* |
2109 | | * The uuid load command contains a single 128-bit unique random number that |
2110 | | * identifies an object produced by the static link editor. |
2111 | | */ |
2112 | | #[derive(Debug, Clone, Copy)] |
2113 | | #[repr(C)] |
2114 | | pub struct UuidCommand<E: Endian> { |
2115 | | /// LC_UUID |
2116 | | pub cmd: U32<E>, |
2117 | | /// sizeof(struct UuidCommand) |
2118 | | pub cmdsize: U32<E>, |
2119 | | /// the 128-bit uuid |
2120 | | pub uuid: [u8; 16], |
2121 | | } |
2122 | | |
2123 | | /* |
2124 | | * The RpathCommand contains a path which at runtime should be added to |
2125 | | * the current run path used to find @rpath prefixed dylibs. |
2126 | | */ |
2127 | | #[derive(Debug, Clone, Copy)] |
2128 | | #[repr(C)] |
2129 | | pub struct RpathCommand<E: Endian> { |
2130 | | /// LC_RPATH |
2131 | | pub cmd: U32<E>, |
2132 | | /// includes string |
2133 | | pub cmdsize: U32<E>, |
2134 | | /// path to add to run path |
2135 | | pub path: LcStr<E>, |
2136 | | } |
2137 | | |
2138 | | /* |
2139 | | * The LinkeditDataCommand contains the offsets and sizes of a blob |
2140 | | * of data in the __LINKEDIT segment. |
2141 | | */ |
2142 | | #[derive(Debug, Clone, Copy)] |
2143 | | #[repr(C)] |
2144 | | pub struct LinkeditDataCommand<E: Endian> { |
2145 | | /// `LC_CODE_SIGNATURE`, `LC_SEGMENT_SPLIT_INFO`, `LC_FUNCTION_STARTS`, |
2146 | | /// `LC_DATA_IN_CODE`, `LC_DYLIB_CODE_SIGN_DRS`, `LC_LINKER_OPTIMIZATION_HINT`, |
2147 | | /// `LC_DYLD_EXPORTS_TRIE`, or `LC_DYLD_CHAINED_FIXUPS`. |
2148 | | pub cmd: U32<E>, |
2149 | | /// sizeof(struct LinkeditDataCommand) |
2150 | | pub cmdsize: U32<E>, |
2151 | | /// file offset of data in __LINKEDIT segment |
2152 | | pub dataoff: U32<E>, |
2153 | | /// file size of data in __LINKEDIT segment |
2154 | | pub datasize: U32<E>, |
2155 | | } |
2156 | | |
2157 | | #[derive(Debug, Clone, Copy)] |
2158 | | #[repr(C)] |
2159 | | pub struct FilesetEntryCommand<E: Endian> { |
2160 | | // LC_FILESET_ENTRY |
2161 | | pub cmd: U32<E>, |
2162 | | /// includes id string |
2163 | | pub cmdsize: U32<E>, |
2164 | | /// memory address of the dylib |
2165 | | pub vmaddr: U64<E>, |
2166 | | /// file offset of the dylib |
2167 | | pub fileoff: U64<E>, |
2168 | | /// contained entry id |
2169 | | pub entry_id: LcStr<E>, |
2170 | | /// entry_id is 32-bits long, so this is the reserved padding |
2171 | | pub reserved: U32<E>, |
2172 | | } |
2173 | | |
2174 | | /* |
2175 | | * The EncryptionInfoCommand32 contains the file offset and size of an |
2176 | | * of an encrypted segment. |
2177 | | */ |
2178 | | #[derive(Debug, Clone, Copy)] |
2179 | | #[repr(C)] |
2180 | | pub struct EncryptionInfoCommand32<E: Endian> { |
2181 | | /// LC_ENCRYPTION_INFO |
2182 | | pub cmd: U32<E>, |
2183 | | /// sizeof(struct EncryptionInfoCommand32) |
2184 | | pub cmdsize: U32<E>, |
2185 | | /// file offset of encrypted range |
2186 | | pub cryptoff: U32<E>, |
2187 | | /// file size of encrypted range |
2188 | | pub cryptsize: U32<E>, |
2189 | | /// which enryption system, 0 means not-encrypted yet |
2190 | | pub cryptid: U32<E>, |
2191 | | } |
2192 | | |
2193 | | /* |
2194 | | * The EncryptionInfoCommand64 contains the file offset and size of an |
2195 | | * of an encrypted segment (for use in x86_64 targets). |
2196 | | */ |
2197 | | #[derive(Debug, Clone, Copy)] |
2198 | | #[repr(C)] |
2199 | | pub struct EncryptionInfoCommand64<E: Endian> { |
2200 | | /// LC_ENCRYPTION_INFO_64 |
2201 | | pub cmd: U32<E>, |
2202 | | /// sizeof(struct EncryptionInfoCommand64) |
2203 | | pub cmdsize: U32<E>, |
2204 | | /// file offset of encrypted range |
2205 | | pub cryptoff: U32<E>, |
2206 | | /// file size of encrypted range |
2207 | | pub cryptsize: U32<E>, |
2208 | | /// which enryption system, 0 means not-encrypted yet |
2209 | | pub cryptid: U32<E>, |
2210 | | /// padding to make this struct's size a multiple of 8 bytes |
2211 | | pub pad: U32<E>, |
2212 | | } |
2213 | | |
2214 | | /* |
2215 | | * The VersionMinCommand contains the min OS version on which this |
2216 | | * binary was built to run. |
2217 | | */ |
2218 | | #[derive(Debug, Clone, Copy)] |
2219 | | #[repr(C)] |
2220 | | pub struct VersionMinCommand<E: Endian> { |
2221 | | /// LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS or LC_VERSION_MIN_TVOS |
2222 | | pub cmd: U32<E>, |
2223 | | /// sizeof(struct VersionMinCommand) |
2224 | | pub cmdsize: U32<E>, |
2225 | | /// X.Y.Z is encoded in nibbles xxxx.yy.zz |
2226 | | pub version: U32<E>, |
2227 | | /// X.Y.Z is encoded in nibbles xxxx.yy.zz |
2228 | | pub sdk: U32<E>, |
2229 | | } |
2230 | | |
2231 | | /* |
2232 | | * The BuildVersionCommand contains the min OS version on which this |
2233 | | * binary was built to run for its platform. The list of known platforms and |
2234 | | * tool values following it. |
2235 | | */ |
2236 | | #[derive(Debug, Clone, Copy)] |
2237 | | #[repr(C)] |
2238 | | pub struct BuildVersionCommand<E: Endian> { |
2239 | | /// LC_BUILD_VERSION |
2240 | | pub cmd: U32<E>, |
2241 | | /// sizeof(struct BuildVersionCommand) plus ntools * sizeof(struct BuildToolVersion) |
2242 | | pub cmdsize: U32<E>, |
2243 | | /// platform |
2244 | | pub platform: U32<E>, |
2245 | | /// X.Y.Z is encoded in nibbles xxxx.yy.zz |
2246 | | pub minos: U32<E>, |
2247 | | /// X.Y.Z is encoded in nibbles xxxx.yy.zz |
2248 | | pub sdk: U32<E>, |
2249 | | /// number of tool entries following this |
2250 | | pub ntools: U32<E>, |
2251 | | } |
2252 | | |
2253 | | #[derive(Debug, Clone, Copy)] |
2254 | | #[repr(C)] |
2255 | | pub struct BuildToolVersion<E: Endian> { |
2256 | | /// enum for the tool |
2257 | | pub tool: U32<E>, |
2258 | | /// version number of the tool |
2259 | | pub version: U32<E>, |
2260 | | } |
2261 | | |
2262 | | /* Known values for the platform field above. */ |
2263 | | pub const PLATFORM_MACOS: u32 = 1; |
2264 | | pub const PLATFORM_IOS: u32 = 2; |
2265 | | pub const PLATFORM_TVOS: u32 = 3; |
2266 | | pub const PLATFORM_WATCHOS: u32 = 4; |
2267 | | pub const PLATFORM_BRIDGEOS: u32 = 5; |
2268 | | pub const PLATFORM_MACCATALYST: u32 = 6; |
2269 | | pub const PLATFORM_IOSSIMULATOR: u32 = 7; |
2270 | | pub const PLATFORM_TVOSSIMULATOR: u32 = 8; |
2271 | | pub const PLATFORM_WATCHOSSIMULATOR: u32 = 9; |
2272 | | pub const PLATFORM_DRIVERKIT: u32 = 10; |
2273 | | pub const PLATFORM_XROS: u32 = 11; |
2274 | | pub const PLATFORM_XROSSIMULATOR: u32 = 12; |
2275 | | |
2276 | | /* Known values for the tool field above. */ |
2277 | | pub const TOOL_CLANG: u32 = 1; |
2278 | | pub const TOOL_SWIFT: u32 = 2; |
2279 | | pub const TOOL_LD: u32 = 3; |
2280 | | |
2281 | | /* |
2282 | | * The DyldInfoCommand contains the file offsets and sizes of |
2283 | | * the new compressed form of the information dyld needs to |
2284 | | * load the image. This information is used by dyld on Mac OS X |
2285 | | * 10.6 and later. All information pointed to by this command |
2286 | | * is encoded using byte streams, so no endian swapping is needed |
2287 | | * to interpret it. |
2288 | | */ |
2289 | | #[derive(Debug, Clone, Copy)] |
2290 | | #[repr(C)] |
2291 | | pub struct DyldInfoCommand<E: Endian> { |
2292 | | /// LC_DYLD_INFO or LC_DYLD_INFO_ONLY |
2293 | | pub cmd: U32<E>, |
2294 | | /// sizeof(struct DyldInfoCommand) |
2295 | | pub cmdsize: U32<E>, |
2296 | | |
2297 | | /* |
2298 | | * Dyld rebases an image whenever dyld loads it at an address different |
2299 | | * from its preferred address. The rebase information is a stream |
2300 | | * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. |
2301 | | * Conceptually the rebase information is a table of tuples: |
2302 | | * <seg-index, seg-offset, type> |
2303 | | * The opcodes are a compressed way to encode the table by only |
2304 | | * encoding when a column changes. In addition simple patterns |
2305 | | * like "every n'th offset for m times" can be encoded in a few |
2306 | | * bytes. |
2307 | | */ |
2308 | | /// file offset to rebase info |
2309 | | pub rebase_off: U32<E>, |
2310 | | /// size of rebase info |
2311 | | pub rebase_size: U32<E>, |
2312 | | |
2313 | | /* |
2314 | | * Dyld binds an image during the loading process, if the image |
2315 | | * requires any pointers to be initialized to symbols in other images. |
2316 | | * The bind information is a stream of byte sized |
2317 | | * opcodes whose symbolic names start with BIND_OPCODE_. |
2318 | | * Conceptually the bind information is a table of tuples: |
2319 | | * <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend> |
2320 | | * The opcodes are a compressed way to encode the table by only |
2321 | | * encoding when a column changes. In addition simple patterns |
2322 | | * like for runs of pointers initialized to the same value can be |
2323 | | * encoded in a few bytes. |
2324 | | */ |
2325 | | /// file offset to binding info |
2326 | | pub bind_off: U32<E>, |
2327 | | /// size of binding info |
2328 | | pub bind_size: U32<E>, |
2329 | | |
2330 | | /* |
2331 | | * Some C++ programs require dyld to unique symbols so that all |
2332 | | * images in the process use the same copy of some code/data. |
2333 | | * This step is done after binding. The content of the weak_bind |
2334 | | * info is an opcode stream like the bind_info. But it is sorted |
2335 | | * alphabetically by symbol name. This enable dyld to walk |
2336 | | * all images with weak binding information in order and look |
2337 | | * for collisions. If there are no collisions, dyld does |
2338 | | * no updating. That means that some fixups are also encoded |
2339 | | * in the bind_info. For instance, all calls to "operator new" |
2340 | | * are first bound to libstdc++.dylib using the information |
2341 | | * in bind_info. Then if some image overrides operator new |
2342 | | * that is detected when the weak_bind information is processed |
2343 | | * and the call to operator new is then rebound. |
2344 | | */ |
2345 | | /// file offset to weak binding info |
2346 | | pub weak_bind_off: U32<E>, |
2347 | | /// size of weak binding info |
2348 | | pub weak_bind_size: U32<E>, |
2349 | | |
2350 | | /* |
2351 | | * Some uses of external symbols do not need to be bound immediately. |
2352 | | * Instead they can be lazily bound on first use. The lazy_bind |
2353 | | * are contains a stream of BIND opcodes to bind all lazy symbols. |
2354 | | * Normal use is that dyld ignores the lazy_bind section when |
2355 | | * loading an image. Instead the static linker arranged for the |
2356 | | * lazy pointer to initially point to a helper function which |
2357 | | * pushes the offset into the lazy_bind area for the symbol |
2358 | | * needing to be bound, then jumps to dyld which simply adds |
2359 | | * the offset to lazy_bind_off to get the information on what |
2360 | | * to bind. |
2361 | | */ |
2362 | | /// file offset to lazy binding info |
2363 | | pub lazy_bind_off: U32<E>, |
2364 | | /// size of lazy binding infs |
2365 | | pub lazy_bind_size: U32<E>, |
2366 | | |
2367 | | /* |
2368 | | * The symbols exported by a dylib are encoded in a trie. This |
2369 | | * is a compact representation that factors out common prefixes. |
2370 | | * It also reduces LINKEDIT pages in RAM because it encodes all |
2371 | | * information (name, address, flags) in one small, contiguous range. |
2372 | | * The export area is a stream of nodes. The first node sequentially |
2373 | | * is the start node for the trie. |
2374 | | * |
2375 | | * Nodes for a symbol start with a uleb128 that is the length of |
2376 | | * the exported symbol information for the string so far. |
2377 | | * If there is no exported symbol, the node starts with a zero byte. |
2378 | | * If there is exported info, it follows the length. |
2379 | | * |
2380 | | * First is a uleb128 containing flags. Normally, it is followed by |
2381 | | * a uleb128 encoded offset which is location of the content named |
2382 | | * by the symbol from the mach_header for the image. If the flags |
2383 | | * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is |
2384 | | * a uleb128 encoded library ordinal, then a zero terminated |
2385 | | * UTF8 string. If the string is zero length, then the symbol |
2386 | | * is re-export from the specified dylib with the same name. |
2387 | | * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following |
2388 | | * the flags is two uleb128s: the stub offset and the resolver offset. |
2389 | | * The stub is used by non-lazy pointers. The resolver is used |
2390 | | * by lazy pointers and must be called to get the actual address to use. |
2391 | | * |
2392 | | * After the optional exported symbol information is a byte of |
2393 | | * how many edges (0-255) that this node has leaving it, |
2394 | | * followed by each edge. |
2395 | | * Each edge is a zero terminated UTF8 of the addition chars |
2396 | | * in the symbol, followed by a uleb128 offset for the node that |
2397 | | * edge points to. |
2398 | | * |
2399 | | */ |
2400 | | /// file offset to lazy binding info |
2401 | | pub export_off: U32<E>, |
2402 | | /// size of lazy binding infs |
2403 | | pub export_size: U32<E>, |
2404 | | } |
2405 | | |
2406 | | /* |
2407 | | * The following are used to encode rebasing information |
2408 | | */ |
2409 | | pub const REBASE_TYPE_POINTER: u8 = 1; |
2410 | | pub const REBASE_TYPE_TEXT_ABSOLUTE32: u8 = 2; |
2411 | | pub const REBASE_TYPE_TEXT_PCREL32: u8 = 3; |
2412 | | |
2413 | | pub const REBASE_OPCODE_MASK: u8 = 0xF0; |
2414 | | pub const REBASE_IMMEDIATE_MASK: u8 = 0x0F; |
2415 | | pub const REBASE_OPCODE_DONE: u8 = 0x00; |
2416 | | pub const REBASE_OPCODE_SET_TYPE_IMM: u8 = 0x10; |
2417 | | pub const REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x20; |
2418 | | pub const REBASE_OPCODE_ADD_ADDR_ULEB: u8 = 0x30; |
2419 | | pub const REBASE_OPCODE_ADD_ADDR_IMM_SCALED: u8 = 0x40; |
2420 | | pub const REBASE_OPCODE_DO_REBASE_IMM_TIMES: u8 = 0x50; |
2421 | | pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES: u8 = 0x60; |
2422 | | pub const REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: u8 = 0x70; |
2423 | | pub const REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: u8 = 0x80; |
2424 | | |
2425 | | /* |
2426 | | * The following are used to encode binding information |
2427 | | */ |
2428 | | pub const BIND_TYPE_POINTER: u8 = 1; |
2429 | | pub const BIND_TYPE_TEXT_ABSOLUTE32: u8 = 2; |
2430 | | pub const BIND_TYPE_TEXT_PCREL32: u8 = 3; |
2431 | | |
2432 | | pub const BIND_SPECIAL_DYLIB_SELF: i8 = 0; |
2433 | | pub const BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE: i8 = -1; |
2434 | | pub const BIND_SPECIAL_DYLIB_FLAT_LOOKUP: i8 = -2; |
2435 | | pub const BIND_SPECIAL_DYLIB_WEAK_LOOKUP: i8 = -3; |
2436 | | |
2437 | | pub const BIND_SYMBOL_FLAGS_WEAK_IMPORT: u8 = 0x1; |
2438 | | pub const BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION: u8 = 0x8; |
2439 | | |
2440 | | pub const BIND_OPCODE_MASK: u8 = 0xF0; |
2441 | | pub const BIND_IMMEDIATE_MASK: u8 = 0x0F; |
2442 | | pub const BIND_OPCODE_DONE: u8 = 0x00; |
2443 | | pub const BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: u8 = 0x10; |
2444 | | pub const BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: u8 = 0x20; |
2445 | | pub const BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: u8 = 0x30; |
2446 | | pub const BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: u8 = 0x40; |
2447 | | pub const BIND_OPCODE_SET_TYPE_IMM: u8 = 0x50; |
2448 | | pub const BIND_OPCODE_SET_ADDEND_SLEB: u8 = 0x60; |
2449 | | pub const BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: u8 = 0x70; |
2450 | | pub const BIND_OPCODE_ADD_ADDR_ULEB: u8 = 0x80; |
2451 | | pub const BIND_OPCODE_DO_BIND: u8 = 0x90; |
2452 | | pub const BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: u8 = 0xA0; |
2453 | | pub const BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: u8 = 0xB0; |
2454 | | pub const BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: u8 = 0xC0; |
2455 | | pub const BIND_OPCODE_THREADED: u8 = 0xD0; |
2456 | | pub const BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB: u8 = 0x00; |
2457 | | pub const BIND_SUBOPCODE_THREADED_APPLY: u8 = 0x01; |
2458 | | |
2459 | | /* |
2460 | | * The following are used on the flags byte of a terminal node |
2461 | | * in the export information. |
2462 | | */ |
2463 | | pub const EXPORT_SYMBOL_FLAGS_KIND_MASK: u32 = 0x03; |
2464 | | pub const EXPORT_SYMBOL_FLAGS_KIND_REGULAR: u32 = 0x00; |
2465 | | pub const EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: u32 = 0x01; |
2466 | | pub const EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: u32 = 0x02; |
2467 | | pub const EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION: u32 = 0x04; |
2468 | | pub const EXPORT_SYMBOL_FLAGS_REEXPORT: u32 = 0x08; |
2469 | | pub const EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER: u32 = 0x10; |
2470 | | |
2471 | | /* |
2472 | | * The LinkerOptionCommand contains linker options embedded in object files. |
2473 | | */ |
2474 | | #[derive(Debug, Clone, Copy)] |
2475 | | #[repr(C)] |
2476 | | pub struct LinkerOptionCommand<E: Endian> { |
2477 | | /// LC_LINKER_OPTION only used in MH_OBJECT filetypes |
2478 | | pub cmd: U32<E>, |
2479 | | pub cmdsize: U32<E>, |
2480 | | /// number of strings |
2481 | | pub count: U32<E>, |
2482 | | /* concatenation of zero terminated UTF8 strings. |
2483 | | Zero filled at end to align */ |
2484 | | } |
2485 | | |
2486 | | /* |
2487 | | * The SymsegCommand contains the offset and size of the GNU style |
2488 | | * symbol table information as described in the header file <symseg.h>. |
2489 | | * The symbol roots of the symbol segments must also be aligned properly |
2490 | | * in the file. So the requirement of keeping the offsets aligned to a |
2491 | | * multiple of a 4 bytes translates to the length field of the symbol |
2492 | | * roots also being a multiple of a long. Also the padding must again be |
2493 | | * zeroed. (THIS IS OBSOLETE and no longer supported). |
2494 | | */ |
2495 | | #[derive(Debug, Clone, Copy)] |
2496 | | #[repr(C)] |
2497 | | pub struct SymsegCommand<E: Endian> { |
2498 | | /// LC_SYMSEG |
2499 | | pub cmd: U32<E>, |
2500 | | /// sizeof(struct SymsegCommand) |
2501 | | pub cmdsize: U32<E>, |
2502 | | /// symbol segment offset |
2503 | | pub offset: U32<E>, |
2504 | | /// symbol segment size in bytes |
2505 | | pub size: U32<E>, |
2506 | | } |
2507 | | |
2508 | | /* |
2509 | | * The IdentCommand contains a free format string table following the |
2510 | | * IdentCommand structure. The strings are null terminated and the size of |
2511 | | * the command is padded out with zero bytes to a multiple of 4 bytes/ |
2512 | | * (THIS IS OBSOLETE and no longer supported). |
2513 | | */ |
2514 | | #[derive(Debug, Clone, Copy)] |
2515 | | #[repr(C)] |
2516 | | pub struct IdentCommand<E: Endian> { |
2517 | | /// LC_IDENT |
2518 | | pub cmd: U32<E>, |
2519 | | /// strings that follow this command |
2520 | | pub cmdsize: U32<E>, |
2521 | | } |
2522 | | |
2523 | | /* |
2524 | | * The FvmfileCommand contains a reference to a file to be loaded at the |
2525 | | * specified virtual address. (Presently, this command is reserved for |
2526 | | * internal use. The kernel ignores this command when loading a program into |
2527 | | * memory). |
2528 | | */ |
2529 | | #[derive(Debug, Clone, Copy)] |
2530 | | #[repr(C)] |
2531 | | pub struct FvmfileCommand<E: Endian> { |
2532 | | /// LC_FVMFILE |
2533 | | pub cmd: U32<E>, |
2534 | | /// includes pathname string |
2535 | | pub cmdsize: U32<E>, |
2536 | | /// files pathname |
2537 | | pub name: LcStr<E>, |
2538 | | /// files virtual address |
2539 | | pub header_addr: U32<E>, |
2540 | | } |
2541 | | |
2542 | | /* |
2543 | | * The EntryPointCommand is a replacement for thread_command. |
2544 | | * It is used for main executables to specify the location (file offset) |
2545 | | * of main(). If -stack_size was used at link time, the stacksize |
2546 | | * field will contain the stack size need for the main thread. |
2547 | | */ |
2548 | | #[derive(Debug, Clone, Copy)] |
2549 | | #[repr(C)] |
2550 | | pub struct EntryPointCommand<E: Endian> { |
2551 | | /// LC_MAIN only used in MH_EXECUTE filetypes |
2552 | | pub cmd: U32<E>, |
2553 | | /// 24 |
2554 | | pub cmdsize: U32<E>, |
2555 | | /// file (__TEXT) offset of main() |
2556 | | pub entryoff: U64<E>, |
2557 | | /// if not zero, initial stack size |
2558 | | pub stacksize: U64<E>, |
2559 | | } |
2560 | | |
2561 | | /* |
2562 | | * The SourceVersionCommand is an optional load command containing |
2563 | | * the version of the sources used to build the binary. |
2564 | | */ |
2565 | | #[derive(Debug, Clone, Copy)] |
2566 | | #[repr(C)] |
2567 | | pub struct SourceVersionCommand<E: Endian> { |
2568 | | /// LC_SOURCE_VERSION |
2569 | | pub cmd: U32<E>, |
2570 | | /// 16 |
2571 | | pub cmdsize: U32<E>, |
2572 | | /// A.B.C.D.E packed as a24.b10.c10.d10.e10 |
2573 | | pub version: U64<E>, |
2574 | | } |
2575 | | |
2576 | | /* |
2577 | | * The LC_DATA_IN_CODE load commands uses a LinkeditDataCommand |
2578 | | * to point to an array of DataInCodeEntry entries. Each entry |
2579 | | * describes a range of data in a code section. |
2580 | | */ |
2581 | | #[derive(Debug, Clone, Copy)] |
2582 | | #[repr(C)] |
2583 | | pub struct DataInCodeEntry<E: Endian> { |
2584 | | /// from mach_header to start of data range |
2585 | | pub offset: U32<E>, |
2586 | | /// number of bytes in data range |
2587 | | pub length: U16<E>, |
2588 | | /// a DICE_KIND_* value |
2589 | | pub kind: U16<E>, |
2590 | | } |
2591 | | pub const DICE_KIND_DATA: u32 = 0x0001; |
2592 | | pub const DICE_KIND_JUMP_TABLE8: u32 = 0x0002; |
2593 | | pub const DICE_KIND_JUMP_TABLE16: u32 = 0x0003; |
2594 | | pub const DICE_KIND_JUMP_TABLE32: u32 = 0x0004; |
2595 | | pub const DICE_KIND_ABS_JUMP_TABLE32: u32 = 0x0005; |
2596 | | |
2597 | | /* |
2598 | | * Sections of type S_THREAD_LOCAL_VARIABLES contain an array |
2599 | | * of TlvDescriptor structures. |
2600 | | */ |
2601 | | /* TODO: |
2602 | | #[derive(Debug, Clone, Copy)] |
2603 | | #[repr(C)] |
2604 | | pub struct TlvDescriptor<E: Endian> |
2605 | | { |
2606 | | void* (*thunk)(struct TlvDescriptor*); |
2607 | | unsigned long key; |
2608 | | unsigned long offset; |
2609 | | } |
2610 | | */ |
2611 | | |
2612 | | /* |
2613 | | * LC_NOTE commands describe a region of arbitrary data included in a Mach-O |
2614 | | * file. Its initial use is to record extra data in MH_CORE files. |
2615 | | */ |
2616 | | #[derive(Debug, Clone, Copy)] |
2617 | | #[repr(C)] |
2618 | | pub struct NoteCommand<E: Endian> { |
2619 | | /// LC_NOTE |
2620 | | pub cmd: U32<E>, |
2621 | | /// sizeof(struct NoteCommand) |
2622 | | pub cmdsize: U32<E>, |
2623 | | /// owner name for this LC_NOTE |
2624 | | pub data_owner: [u8; 16], |
2625 | | /// file offset of this data |
2626 | | pub offset: U64<E>, |
2627 | | /// length of data region |
2628 | | pub size: U64<E>, |
2629 | | } |
2630 | | |
2631 | | // Definitions from "/usr/include/mach-o/nlist.h". |
2632 | | |
2633 | | #[derive(Debug, Clone, Copy)] |
2634 | | #[repr(C)] |
2635 | | pub struct Nlist32<E: Endian> { |
2636 | | /// index into the string table |
2637 | | pub n_strx: U32<E>, |
2638 | | /// type flag, see below |
2639 | | pub n_type: u8, |
2640 | | /// section number or NO_SECT |
2641 | | pub n_sect: u8, |
2642 | | /// see <mach-o/stab.h> |
2643 | | pub n_desc: U16<E>, |
2644 | | /// value of this symbol (or stab offset) |
2645 | | pub n_value: U32<E>, |
2646 | | } |
2647 | | |
2648 | | /* |
2649 | | * This is the symbol table entry structure for 64-bit architectures. |
2650 | | */ |
2651 | | #[derive(Debug, Clone, Copy)] |
2652 | | #[repr(C)] |
2653 | | pub struct Nlist64<E: Endian> { |
2654 | | /// index into the string table |
2655 | | pub n_strx: U32<E>, |
2656 | | /// type flag, see below |
2657 | | pub n_type: u8, |
2658 | | /// section number or NO_SECT |
2659 | | pub n_sect: u8, |
2660 | | /// see <mach-o/stab.h> |
2661 | | pub n_desc: U16<E>, |
2662 | | /// value of this symbol (or stab offset) |
2663 | | // Note: 4 byte alignment has been observed in practice. |
2664 | | pub n_value: U64Bytes<E>, |
2665 | | } |
2666 | | |
2667 | | /* |
2668 | | * Symbols with a index into the string table of zero (n_un.n_strx == 0) are |
2669 | | * defined to have a null, "", name. Therefore all string indexes to non null |
2670 | | * names must not have a zero string index. This is bit historical information |
2671 | | * that has never been well documented. |
2672 | | */ |
2673 | | |
2674 | | /* |
2675 | | * The n_type field really contains four fields: |
2676 | | * unsigned char N_STAB:3, |
2677 | | * N_PEXT:1, |
2678 | | * N_TYPE:3, |
2679 | | * N_EXT:1; |
2680 | | * which are used via the following masks. |
2681 | | */ |
2682 | | /// if any of these bits set, a symbolic debugging entry |
2683 | | pub const N_STAB: u8 = 0xe0; |
2684 | | /// private external symbol bit |
2685 | | pub const N_PEXT: u8 = 0x10; |
2686 | | /// mask for the type bits |
2687 | | pub const N_TYPE: u8 = 0x0e; |
2688 | | /// external symbol bit, set for external symbols |
2689 | | pub const N_EXT: u8 = 0x01; |
2690 | | |
2691 | | /* |
2692 | | * Only symbolic debugging entries have some of the N_STAB bits set and if any |
2693 | | * of these bits are set then it is a symbolic debugging entry (a stab). In |
2694 | | * which case then the values of the n_type field (the entire field) are given |
2695 | | * in <mach-o/stab.h> |
2696 | | */ |
2697 | | |
2698 | | /* |
2699 | | * Values for N_TYPE bits of the n_type field. |
2700 | | */ |
2701 | | /// undefined, n_sect == NO_SECT |
2702 | | pub const N_UNDF: u8 = 0x0; |
2703 | | /// absolute, n_sect == NO_SECT |
2704 | | pub const N_ABS: u8 = 0x2; |
2705 | | /// defined in section number n_sect |
2706 | | pub const N_SECT: u8 = 0xe; |
2707 | | /// prebound undefined (defined in a dylib) |
2708 | | pub const N_PBUD: u8 = 0xc; |
2709 | | /// indirect |
2710 | | pub const N_INDR: u8 = 0xa; |
2711 | | |
2712 | | /* |
2713 | | * If the type is N_INDR then the symbol is defined to be the same as another |
2714 | | * symbol. In this case the n_value field is an index into the string table |
2715 | | * of the other symbol's name. When the other symbol is defined then they both |
2716 | | * take on the defined type and value. |
2717 | | */ |
2718 | | |
2719 | | /* |
2720 | | * If the type is N_SECT then the n_sect field contains an ordinal of the |
2721 | | * section the symbol is defined in. The sections are numbered from 1 and |
2722 | | * refer to sections in order they appear in the load commands for the file |
2723 | | * they are in. This means the same ordinal may very well refer to different |
2724 | | * sections in different files. |
2725 | | * |
2726 | | * The n_value field for all symbol table entries (including N_STAB's) gets |
2727 | | * updated by the link editor based on the value of it's n_sect field and where |
2728 | | * the section n_sect references gets relocated. If the value of the n_sect |
2729 | | * field is NO_SECT then it's n_value field is not changed by the link editor. |
2730 | | */ |
2731 | | /// symbol is not in any section |
2732 | | pub const NO_SECT: u8 = 0; |
2733 | | /// 1 thru 255 inclusive |
2734 | | pub const MAX_SECT: u8 = 255; |
2735 | | |
2736 | | /* |
2737 | | * Common symbols are represented by undefined (N_UNDF) external (N_EXT) types |
2738 | | * who's values (n_value) are non-zero. In which case the value of the n_value |
2739 | | * field is the size (in bytes) of the common symbol. The n_sect field is set |
2740 | | * to NO_SECT. The alignment of a common symbol may be set as a power of 2 |
2741 | | * between 2^1 and 2^15 as part of the n_desc field using the macros below. If |
2742 | | * the alignment is not set (a value of zero) then natural alignment based on |
2743 | | * the size is used. |
2744 | | */ |
2745 | | /* TODO: |
2746 | | #define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f) |
2747 | | #define SET_COMM_ALIGN(n_desc,align) \ |
2748 | | (n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8)) |
2749 | | */ |
2750 | | |
2751 | | /* |
2752 | | * To support the lazy binding of undefined symbols in the dynamic link-editor, |
2753 | | * the undefined symbols in the symbol table (the nlist structures) are marked |
2754 | | * with the indication if the undefined reference is a lazy reference or |
2755 | | * non-lazy reference. If both a non-lazy reference and a lazy reference is |
2756 | | * made to the same symbol the non-lazy reference takes precedence. A reference |
2757 | | * is lazy only when all references to that symbol are made through a symbol |
2758 | | * pointer in a lazy symbol pointer section. |
2759 | | * |
2760 | | * The implementation of marking nlist structures in the symbol table for |
2761 | | * undefined symbols will be to use some of the bits of the n_desc field as a |
2762 | | * reference type. The mask REFERENCE_TYPE will be applied to the n_desc field |
2763 | | * of an nlist structure for an undefined symbol to determine the type of |
2764 | | * undefined reference (lazy or non-lazy). |
2765 | | * |
2766 | | * The constants for the REFERENCE FLAGS are propagated to the reference table |
2767 | | * in a shared library file. In that case the constant for a defined symbol, |
2768 | | * REFERENCE_FLAG_DEFINED, is also used. |
2769 | | */ |
2770 | | /* Reference type bits of the n_desc field of undefined symbols */ |
2771 | | pub const REFERENCE_TYPE: u16 = 0x7; |
2772 | | /* types of references */ |
2773 | | pub const REFERENCE_FLAG_UNDEFINED_NON_LAZY: u16 = 0; |
2774 | | pub const REFERENCE_FLAG_UNDEFINED_LAZY: u16 = 1; |
2775 | | pub const REFERENCE_FLAG_DEFINED: u16 = 2; |
2776 | | pub const REFERENCE_FLAG_PRIVATE_DEFINED: u16 = 3; |
2777 | | pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY: u16 = 4; |
2778 | | pub const REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY: u16 = 5; |
2779 | | |
2780 | | /* |
2781 | | * To simplify stripping of objects that use are used with the dynamic link |
2782 | | * editor, the static link editor marks the symbols defined an object that are |
2783 | | * referenced by a dynamically bound object (dynamic shared libraries, bundles). |
2784 | | * With this marking strip knows not to strip these symbols. |
2785 | | */ |
2786 | | pub const REFERENCED_DYNAMICALLY: u16 = 0x0010; |
2787 | | |
2788 | | /* |
2789 | | * For images created by the static link editor with the -twolevel_namespace |
2790 | | * option in effect the flags field of the mach header is marked with |
2791 | | * MH_TWOLEVEL. And the binding of the undefined references of the image are |
2792 | | * determined by the static link editor. Which library an undefined symbol is |
2793 | | * bound to is recorded by the static linker in the high 8 bits of the n_desc |
2794 | | * field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded |
2795 | | * references the libraries listed in the Mach-O's LC_LOAD_DYLIB, |
2796 | | * LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and |
2797 | | * LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the |
2798 | | * headers. The library ordinals start from 1. |
2799 | | * For a dynamic library that is built as a two-level namespace image the |
2800 | | * undefined references from module defined in another use the same nlist struct |
2801 | | * an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For |
2802 | | * defined symbols in all images they also must have the library ordinal set to |
2803 | | * SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable |
2804 | | * image for references from plugins that refer to the executable that loads |
2805 | | * them. |
2806 | | * |
2807 | | * The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace |
2808 | | * image that are looked up by the dynamic linker with flat namespace semantics. |
2809 | | * This ordinal was added as a feature in Mac OS X 10.3 by reducing the |
2810 | | * value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries |
2811 | | * or binaries built with older tools to have 0xfe (254) dynamic libraries. In |
2812 | | * this case the ordinal value 0xfe (254) must be treated as a library ordinal |
2813 | | * for compatibility. |
2814 | | */ |
2815 | | /* TODO: |
2816 | | #define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff) |
2817 | | #define SET_LIBRARY_ORDINAL(n_desc,ordinal) \ |
2818 | | (n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8)) |
2819 | | */ |
2820 | | pub const SELF_LIBRARY_ORDINAL: u8 = 0x0; |
2821 | | pub const MAX_LIBRARY_ORDINAL: u8 = 0xfd; |
2822 | | pub const DYNAMIC_LOOKUP_ORDINAL: u8 = 0xfe; |
2823 | | pub const EXECUTABLE_ORDINAL: u8 = 0xff; |
2824 | | |
2825 | | /* |
2826 | | * The bit 0x0020 of the n_desc field is used for two non-overlapping purposes |
2827 | | * and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED. |
2828 | | */ |
2829 | | |
2830 | | /* |
2831 | | * The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a |
2832 | | * relocatable .o file (MH_OBJECT filetype). And is used to indicate to the |
2833 | | * static link editor it is never to dead strip the symbol. |
2834 | | */ |
2835 | | /// symbol is not to be dead stripped |
2836 | | pub const N_NO_DEAD_STRIP: u16 = 0x0020; |
2837 | | |
2838 | | /* |
2839 | | * The N_DESC_DISCARDED bit of the n_desc field never appears in linked image. |
2840 | | * But is used in very rare cases by the dynamic link editor to mark an in |
2841 | | * memory symbol as discared and longer used for linking. |
2842 | | */ |
2843 | | /// symbol is discarded |
2844 | | pub const N_DESC_DISCARDED: u16 = 0x0020; |
2845 | | |
2846 | | /* |
2847 | | * The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that |
2848 | | * the undefined symbol is allowed to be missing and is to have the address of |
2849 | | * zero when missing. |
2850 | | */ |
2851 | | /// symbol is weak referenced |
2852 | | pub const N_WEAK_REF: u16 = 0x0040; |
2853 | | |
2854 | | /* |
2855 | | * The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic |
2856 | | * linkers that the symbol definition is weak, allowing a non-weak symbol to |
2857 | | * also be used which causes the weak definition to be discared. Currently this |
2858 | | * is only supported for symbols in coalesced sections. |
2859 | | */ |
2860 | | /// coalesced symbol is a weak definition |
2861 | | pub const N_WEAK_DEF: u16 = 0x0080; |
2862 | | |
2863 | | /* |
2864 | | * The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker |
2865 | | * that the undefined symbol should be resolved using flat namespace searching. |
2866 | | */ |
2867 | | /// reference to a weak symbol |
2868 | | pub const N_REF_TO_WEAK: u16 = 0x0080; |
2869 | | |
2870 | | /* |
2871 | | * The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is |
2872 | | * a definition of a Thumb function. |
2873 | | */ |
2874 | | /// symbol is a Thumb function (ARM) |
2875 | | pub const N_ARM_THUMB_DEF: u16 = 0x0008; |
2876 | | |
2877 | | /* |
2878 | | * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the |
2879 | | * that the function is actually a resolver function and should |
2880 | | * be called to get the address of the real function to use. |
2881 | | * This bit is only available in .o files (MH_OBJECT filetype) |
2882 | | */ |
2883 | | pub const N_SYMBOL_RESOLVER: u16 = 0x0100; |
2884 | | |
2885 | | /* |
2886 | | * The N_ALT_ENTRY bit of the n_desc field indicates that the |
2887 | | * symbol is pinned to the previous content. |
2888 | | */ |
2889 | | pub const N_ALT_ENTRY: u16 = 0x0200; |
2890 | | |
2891 | | // Definitions from "/usr/include/mach-o/stab.h". |
2892 | | |
2893 | | /* |
2894 | | * This file gives definitions supplementing <nlist.h> for permanent symbol |
2895 | | * table entries of Mach-O files. Modified from the BSD definitions. The |
2896 | | * modifications from the original definitions were changing what the values of |
2897 | | * what was the n_other field (an unused field) which is now the n_sect field. |
2898 | | * These modifications are required to support symbols in an arbitrary number of |
2899 | | * sections not just the three sections (text, data and bss) in a BSD file. |
2900 | | * The values of the defined constants have NOT been changed. |
2901 | | * |
2902 | | * These must have one of the N_STAB bits on. The n_value fields are subject |
2903 | | * to relocation according to the value of their n_sect field. So for types |
2904 | | * that refer to things in sections the n_sect field must be filled in with the |
2905 | | * proper section ordinal. For types that are not to have their n_value field |
2906 | | * relocatated the n_sect field must be NO_SECT. |
2907 | | */ |
2908 | | |
2909 | | /* |
2910 | | * Symbolic debugger symbols. The comments give the conventional use for |
2911 | | * |
2912 | | * .stabs "n_name", n_type, n_sect, n_desc, n_value |
2913 | | * |
2914 | | * where n_type is the defined constant and not listed in the comment. Other |
2915 | | * fields not listed are zero. n_sect is the section ordinal the entry is |
2916 | | * referring to. |
2917 | | */ |
2918 | | /// global symbol: name,,NO_SECT,type,0 |
2919 | | pub const N_GSYM: u8 = 0x20; |
2920 | | /// procedure name (f77 kludge): name,,NO_SECT,0,0 |
2921 | | pub const N_FNAME: u8 = 0x22; |
2922 | | /// procedure: name,,n_sect,linenumber,address |
2923 | | pub const N_FUN: u8 = 0x24; |
2924 | | /// static symbol: name,,n_sect,type,address |
2925 | | pub const N_STSYM: u8 = 0x26; |
2926 | | /// .lcomm symbol: name,,n_sect,type,address |
2927 | | pub const N_LCSYM: u8 = 0x28; |
2928 | | /// begin nsect sym: 0,,n_sect,0,address |
2929 | | pub const N_BNSYM: u8 = 0x2e; |
2930 | | /// AST file path: name,,NO_SECT,0,0 |
2931 | | pub const N_AST: u8 = 0x32; |
2932 | | /// emitted with gcc2_compiled and in gcc source |
2933 | | pub const N_OPT: u8 = 0x3c; |
2934 | | /// register sym: name,,NO_SECT,type,register |
2935 | | pub const N_RSYM: u8 = 0x40; |
2936 | | /// src line: 0,,n_sect,linenumber,address |
2937 | | pub const N_SLINE: u8 = 0x44; |
2938 | | /// end nsect sym: 0,,n_sect,0,address |
2939 | | pub const N_ENSYM: u8 = 0x4e; |
2940 | | /// structure elt: name,,NO_SECT,type,struct_offset |
2941 | | pub const N_SSYM: u8 = 0x60; |
2942 | | /// source file name: name,,n_sect,0,address |
2943 | | pub const N_SO: u8 = 0x64; |
2944 | | /// object file name: name,,0,0,st_mtime |
2945 | | pub const N_OSO: u8 = 0x66; |
2946 | | /// local sym: name,,NO_SECT,type,offset |
2947 | | pub const N_LSYM: u8 = 0x80; |
2948 | | /// include file beginning: name,,NO_SECT,0,sum |
2949 | | pub const N_BINCL: u8 = 0x82; |
2950 | | /// #included file name: name,,n_sect,0,address |
2951 | | pub const N_SOL: u8 = 0x84; |
2952 | | /// compiler parameters: name,,NO_SECT,0,0 |
2953 | | pub const N_PARAMS: u8 = 0x86; |
2954 | | /// compiler version: name,,NO_SECT,0,0 |
2955 | | pub const N_VERSION: u8 = 0x88; |
2956 | | /// compiler -O level: name,,NO_SECT,0,0 |
2957 | | pub const N_OLEVEL: u8 = 0x8A; |
2958 | | /// parameter: name,,NO_SECT,type,offset |
2959 | | pub const N_PSYM: u8 = 0xa0; |
2960 | | /// include file end: name,,NO_SECT,0,0 |
2961 | | pub const N_EINCL: u8 = 0xa2; |
2962 | | /// alternate entry: name,,n_sect,linenumber,address |
2963 | | pub const N_ENTRY: u8 = 0xa4; |
2964 | | /// left bracket: 0,,NO_SECT,nesting level,address |
2965 | | pub const N_LBRAC: u8 = 0xc0; |
2966 | | /// deleted include file: name,,NO_SECT,0,sum |
2967 | | pub const N_EXCL: u8 = 0xc2; |
2968 | | /// right bracket: 0,,NO_SECT,nesting level,address |
2969 | | pub const N_RBRAC: u8 = 0xe0; |
2970 | | /// begin common: name,,NO_SECT,0,0 |
2971 | | pub const N_BCOMM: u8 = 0xe2; |
2972 | | /// end common: name,,n_sect,0,0 |
2973 | | pub const N_ECOMM: u8 = 0xe4; |
2974 | | /// end common (local name): 0,,n_sect,0,address |
2975 | | pub const N_ECOML: u8 = 0xe8; |
2976 | | /// second stab entry with length information |
2977 | | pub const N_LENG: u8 = 0xfe; |
2978 | | |
2979 | | /* |
2980 | | * for the berkeley pascal compiler, pc(1): |
2981 | | */ |
2982 | | /// global pascal symbol: name,,NO_SECT,subtype,line |
2983 | | pub const N_PC: u8 = 0x30; |
2984 | | |
2985 | | // Definitions from "/usr/include/mach-o/reloc.h". |
2986 | | |
2987 | | /// A relocation entry. |
2988 | | /// |
2989 | | /// Mach-O relocations have plain and scattered variants, with the |
2990 | | /// meaning of the fields depending on the variant. |
2991 | | /// |
2992 | | /// This type provides functions for determining whether the relocation |
2993 | | /// is scattered, and for accessing the fields of each variant. |
2994 | | #[derive(Debug, Clone, Copy)] |
2995 | | #[repr(C)] |
2996 | | pub struct Relocation<E: Endian> { |
2997 | | pub r_word0: U32<E>, |
2998 | | pub r_word1: U32<E>, |
2999 | | } |
3000 | | |
3001 | | impl<E: Endian> Relocation<E> { |
3002 | | /// Determine whether this is a scattered relocation. |
3003 | | #[inline] |
3004 | 0 | pub fn r_scattered(self, endian: E, cputype: u32) -> bool { |
3005 | 0 | if cputype == CPU_TYPE_X86_64 { |
3006 | 0 | false |
3007 | | } else { |
3008 | 0 | self.r_word0.get(endian) & R_SCATTERED != 0 |
3009 | | } |
3010 | 0 | } |
3011 | | |
3012 | | /// Return the fields of a plain relocation. |
3013 | 0 | pub fn info(self, endian: E) -> RelocationInfo { |
3014 | 0 | let r_address = self.r_word0.get(endian); |
3015 | 0 | let r_word1 = self.r_word1.get(endian); |
3016 | 0 | if endian.is_little_endian() { |
3017 | 0 | RelocationInfo { |
3018 | 0 | r_address, |
3019 | 0 | r_symbolnum: r_word1 & 0x00ff_ffff, |
3020 | 0 | r_pcrel: ((r_word1 >> 24) & 0x1) != 0, |
3021 | 0 | r_length: ((r_word1 >> 25) & 0x3) as u8, |
3022 | 0 | r_extern: ((r_word1 >> 27) & 0x1) != 0, |
3023 | 0 | r_type: (r_word1 >> 28) as u8, |
3024 | 0 | } |
3025 | | } else { |
3026 | 0 | RelocationInfo { |
3027 | 0 | r_address, |
3028 | 0 | r_symbolnum: r_word1 >> 8, |
3029 | 0 | r_pcrel: ((r_word1 >> 7) & 0x1) != 0, |
3030 | 0 | r_length: ((r_word1 >> 5) & 0x3) as u8, |
3031 | 0 | r_extern: ((r_word1 >> 4) & 0x1) != 0, |
3032 | 0 | r_type: (r_word1 & 0xf) as u8, |
3033 | 0 | } |
3034 | | } |
3035 | 0 | } |
3036 | | |
3037 | | /// Return the fields of a scattered relocation. |
3038 | 0 | pub fn scattered_info(self, endian: E) -> ScatteredRelocationInfo { |
3039 | 0 | let r_word0 = self.r_word0.get(endian); |
3040 | 0 | let r_value = self.r_word1.get(endian); |
3041 | 0 | ScatteredRelocationInfo { |
3042 | 0 | r_address: r_word0 & 0x00ff_ffff, |
3043 | 0 | r_type: ((r_word0 >> 24) & 0xf) as u8, |
3044 | 0 | r_length: ((r_word0 >> 28) & 0x3) as u8, |
3045 | 0 | r_pcrel: ((r_word0 >> 30) & 0x1) != 0, |
3046 | 0 | r_value, |
3047 | 0 | } |
3048 | 0 | } |
3049 | | } |
3050 | | |
3051 | | /* |
3052 | | * Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD |
3053 | | * format. The modifications from the original format were changing the value |
3054 | | * of the r_symbolnum field for "local" (r_extern == 0) relocation entries. |
3055 | | * This modification is required to support symbols in an arbitrary number of |
3056 | | * sections not just the three sections (text, data and bss) in a 4.3BSD file. |
3057 | | * Also the last 4 bits have had the r_type tag added to them. |
3058 | | */ |
3059 | | |
3060 | | #[derive(Debug, Clone, Copy)] |
3061 | | pub struct RelocationInfo { |
3062 | | /// offset in the section to what is being relocated |
3063 | | pub r_address: u32, |
3064 | | /// symbol index if r_extern == 1 or section ordinal if r_extern == 0 |
3065 | | pub r_symbolnum: u32, |
3066 | | /// was relocated pc relative already |
3067 | | pub r_pcrel: bool, |
3068 | | /// 0=byte, 1=word, 2=long, 3=quad |
3069 | | pub r_length: u8, |
3070 | | /// does not include value of sym referenced |
3071 | | pub r_extern: bool, |
3072 | | /// if not 0, machine specific relocation type |
3073 | | pub r_type: u8, |
3074 | | } |
3075 | | |
3076 | | impl RelocationInfo { |
3077 | | /// Combine the fields into a `Relocation`. |
3078 | 0 | pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> { |
3079 | 0 | let r_word0 = U32::new(endian, self.r_address); |
3080 | 0 | let r_word1 = U32::new( |
3081 | 0 | endian, |
3082 | 0 | if endian.is_little_endian() { |
3083 | 0 | self.r_symbolnum & 0x00ff_ffff |
3084 | 0 | | u32::from(self.r_pcrel) << 24 |
3085 | 0 | | u32::from(self.r_length & 0x3) << 25 |
3086 | 0 | | u32::from(self.r_extern) << 27 |
3087 | 0 | | u32::from(self.r_type) << 28 |
3088 | | } else { |
3089 | 0 | self.r_symbolnum >> 8 |
3090 | 0 | | u32::from(self.r_pcrel) << 7 |
3091 | 0 | | u32::from(self.r_length & 0x3) << 5 |
3092 | 0 | | u32::from(self.r_extern) << 4 |
3093 | 0 | | u32::from(self.r_type) & 0xf |
3094 | | }, |
3095 | | ); |
3096 | 0 | Relocation { r_word0, r_word1 } |
3097 | 0 | } |
3098 | | } |
3099 | | |
3100 | | /// absolute relocation type for Mach-O files |
3101 | | pub const R_ABS: u8 = 0; |
3102 | | |
3103 | | /* |
3104 | | * The r_address is not really the address as it's name indicates but an offset. |
3105 | | * In 4.3BSD a.out objects this offset is from the start of the "segment" for |
3106 | | * which relocation entry is for (text or data). For Mach-O object files it is |
3107 | | * also an offset but from the start of the "section" for which the relocation |
3108 | | * entry is for. See comments in <mach-o/loader.h> about the r_address feild |
3109 | | * in images for used with the dynamic linker. |
3110 | | * |
3111 | | * In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal |
3112 | | * for the segment the symbol being relocated is in. These ordinals are the |
3113 | | * symbol types N_TEXT, N_DATA, N_BSS or N_ABS. In Mach-O object files these |
3114 | | * ordinals refer to the sections in the object file in the order their section |
3115 | | * structures appear in the headers of the object file they are in. The first |
3116 | | * section has the ordinal 1, the second 2, and so on. This means that the |
3117 | | * same ordinal in two different object files could refer to two different |
3118 | | * sections. And further could have still different ordinals when combined |
3119 | | * by the link-editor. The value R_ABS is used for relocation entries for |
3120 | | * absolute symbols which need no further relocation. |
3121 | | */ |
3122 | | |
3123 | | /* |
3124 | | * For RISC machines some of the references are split across two instructions |
3125 | | * and the instruction does not contain the complete value of the reference. |
3126 | | * In these cases a second, or paired relocation entry, follows each of these |
3127 | | * relocation entries, using a PAIR r_type, which contains the other part of the |
3128 | | * reference not contained in the instruction. This other part is stored in the |
3129 | | * pair's r_address field. The exact number of bits of the other part of the |
3130 | | * reference store in the r_address field is dependent on the particular |
3131 | | * relocation type for the particular architecture. |
3132 | | */ |
3133 | | |
3134 | | /* |
3135 | | * To make scattered loading by the link editor work correctly "local" |
3136 | | * relocation entries can't be used when the item to be relocated is the value |
3137 | | * of a symbol plus an offset (where the resulting expression is outside the |
3138 | | * block the link editor is moving, a blocks are divided at symbol addresses). |
3139 | | * In this case. where the item is a symbol value plus offset, the link editor |
3140 | | * needs to know more than just the section the symbol was defined. What is |
3141 | | * needed is the actual value of the symbol without the offset so it can do the |
3142 | | * relocation correctly based on where the value of the symbol got relocated to |
3143 | | * not the value of the expression (with the offset added to the symbol value). |
3144 | | * So for the NeXT 2.0 release no "local" relocation entries are ever used when |
3145 | | * there is a non-zero offset added to a symbol. The "external" and "local" |
3146 | | * relocation entries remain unchanged. |
3147 | | * |
3148 | | * The implementation is quite messy given the compatibility with the existing |
3149 | | * relocation entry format. The ASSUMPTION is that a section will never be |
3150 | | * bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes. This assumption |
3151 | | * allows the r_address (which is really an offset) to fit in 24 bits and high |
3152 | | * bit of the r_address field in the relocation_info structure to indicate |
3153 | | * it is really a scattered_relocation_info structure. Since these are only |
3154 | | * used in places where "local" relocation entries are used and not where |
3155 | | * "external" relocation entries are used the r_extern field has been removed. |
3156 | | * |
3157 | | * For scattered loading to work on a RISC machine where some of the references |
3158 | | * are split across two instructions the link editor needs to be assured that |
3159 | | * each reference has a unique 32 bit reference (that more than one reference is |
3160 | | * NOT sharing the same high 16 bits for example) so it move each referenced |
3161 | | * item independent of each other. Some compilers guarantees this but the |
3162 | | * compilers don't so scattered loading can be done on those that do guarantee |
3163 | | * this. |
3164 | | */ |
3165 | | |
3166 | | /// Bit set in `Relocation::r_word0` for scattered relocations. |
3167 | | pub const R_SCATTERED: u32 = 0x8000_0000; |
3168 | | |
3169 | | #[derive(Debug, Clone, Copy)] |
3170 | | pub struct ScatteredRelocationInfo { |
3171 | | /// offset in the section to what is being relocated |
3172 | | pub r_address: u32, |
3173 | | /// if not 0, machine specific relocation type |
3174 | | pub r_type: u8, |
3175 | | /// 0=byte, 1=word, 2=long, 3=quad |
3176 | | pub r_length: u8, |
3177 | | /// was relocated pc relative already |
3178 | | pub r_pcrel: bool, |
3179 | | /// the value the item to be relocated is referring to (without any offset added) |
3180 | | pub r_value: u32, |
3181 | | } |
3182 | | |
3183 | | impl ScatteredRelocationInfo { |
3184 | | /// Combine the fields into a `Relocation`. |
3185 | 0 | pub fn relocation<E: Endian>(self, endian: E) -> Relocation<E> { |
3186 | 0 | let r_word0 = U32::new( |
3187 | 0 | endian, |
3188 | 0 | self.r_address & 0x00ff_ffff |
3189 | 0 | | u32::from(self.r_type & 0xf) << 24 |
3190 | 0 | | u32::from(self.r_length & 0x3) << 28 |
3191 | 0 | | u32::from(self.r_pcrel) << 30 |
3192 | 0 | | R_SCATTERED, |
3193 | | ); |
3194 | 0 | let r_word1 = U32::new(endian, self.r_value); |
3195 | 0 | Relocation { r_word0, r_word1 } |
3196 | 0 | } |
3197 | | } |
3198 | | |
3199 | | /* |
3200 | | * Relocation types used in a generic implementation. Relocation entries for |
3201 | | * normal things use the generic relocation as described above and their r_type |
3202 | | * is GENERIC_RELOC_VANILLA (a value of zero). |
3203 | | * |
3204 | | * Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support |
3205 | | * the difference of two symbols defined in different sections. That is the |
3206 | | * expression "symbol1 - symbol2 + constant" is a relocatable expression when |
3207 | | * both symbols are defined in some section. For this type of relocation the |
3208 | | * both relocations entries are scattered relocation entries. The value of |
3209 | | * symbol1 is stored in the first relocation entry's r_value field and the |
3210 | | * value of symbol2 is stored in the pair's r_value field. |
3211 | | * |
3212 | | * A special case for a prebound lazy pointer is needed to beable to set the |
3213 | | * value of the lazy pointer back to its non-prebound state. This is done |
3214 | | * using the GENERIC_RELOC_PB_LA_PTR r_type. This is a scattered relocation |
3215 | | * entry where the r_value feild is the value of the lazy pointer not prebound. |
3216 | | */ |
3217 | | /// generic relocation as described above |
3218 | | pub const GENERIC_RELOC_VANILLA: u8 = 0; |
3219 | | /// Only follows a GENERIC_RELOC_SECTDIFF |
3220 | | pub const GENERIC_RELOC_PAIR: u8 = 1; |
3221 | | pub const GENERIC_RELOC_SECTDIFF: u8 = 2; |
3222 | | /// prebound lazy pointer |
3223 | | pub const GENERIC_RELOC_PB_LA_PTR: u8 = 3; |
3224 | | pub const GENERIC_RELOC_LOCAL_SECTDIFF: u8 = 4; |
3225 | | /// thread local variables |
3226 | | pub const GENERIC_RELOC_TLV: u8 = 5; |
3227 | | |
3228 | | // Definitions from "/usr/include/mach-o/arm/reloc.h". |
3229 | | |
3230 | | /* |
3231 | | * Relocation types used in the arm implementation. Relocation entries for |
3232 | | * things other than instructions use the same generic relocation as described |
3233 | | * in <mach-o/reloc.h> and their r_type is ARM_RELOC_VANILLA, one of the |
3234 | | * *_SECTDIFF or the *_PB_LA_PTR types. The rest of the relocation types are |
3235 | | * for instructions. Since they are for instructions the r_address field |
3236 | | * indicates the 32 bit instruction that the relocation is to be performed on. |
3237 | | */ |
3238 | | /// generic relocation as described above |
3239 | | pub const ARM_RELOC_VANILLA: u8 = 0; |
3240 | | /// the second relocation entry of a pair |
3241 | | pub const ARM_RELOC_PAIR: u8 = 1; |
3242 | | /// a PAIR follows with subtract symbol value |
3243 | | pub const ARM_RELOC_SECTDIFF: u8 = 2; |
3244 | | /// like ARM_RELOC_SECTDIFF, but the symbol referenced was local. |
3245 | | pub const ARM_RELOC_LOCAL_SECTDIFF: u8 = 3; |
3246 | | /// prebound lazy pointer |
3247 | | pub const ARM_RELOC_PB_LA_PTR: u8 = 4; |
3248 | | /// 24 bit branch displacement (to a word address) |
3249 | | pub const ARM_RELOC_BR24: u8 = 5; |
3250 | | /// 22 bit branch displacement (to a half-word address) |
3251 | | pub const ARM_THUMB_RELOC_BR22: u8 = 6; |
3252 | | /// obsolete - a thumb 32-bit branch instruction possibly needing page-spanning branch workaround |
3253 | | pub const ARM_THUMB_32BIT_BRANCH: u8 = 7; |
3254 | | |
3255 | | /* |
3256 | | * For these two r_type relocations they always have a pair following them |
3257 | | * and the r_length bits are used differently. The encoding of the |
3258 | | * r_length is as follows: |
3259 | | * low bit of r_length: |
3260 | | * 0 - :lower16: for movw instructions |
3261 | | * 1 - :upper16: for movt instructions |
3262 | | * high bit of r_length: |
3263 | | * 0 - arm instructions |
3264 | | * 1 - thumb instructions |
3265 | | * the other half of the relocated expression is in the following pair |
3266 | | * relocation entry in the the low 16 bits of r_address field. |
3267 | | */ |
3268 | | pub const ARM_RELOC_HALF: u8 = 8; |
3269 | | pub const ARM_RELOC_HALF_SECTDIFF: u8 = 9; |
3270 | | |
3271 | | // Definitions from "/usr/include/mach-o/arm64/reloc.h". |
3272 | | |
3273 | | /* |
3274 | | * Relocation types used in the arm64 implementation. |
3275 | | */ |
3276 | | /// for pointers |
3277 | | pub const ARM64_RELOC_UNSIGNED: u8 = 0; |
3278 | | /// must be followed by a ARM64_RELOC_UNSIGNED |
3279 | | pub const ARM64_RELOC_SUBTRACTOR: u8 = 1; |
3280 | | /// a B/BL instruction with 26-bit displacement |
3281 | | pub const ARM64_RELOC_BRANCH26: u8 = 2; |
3282 | | /// pc-rel distance to page of target |
3283 | | pub const ARM64_RELOC_PAGE21: u8 = 3; |
3284 | | /// offset within page, scaled by r_length |
3285 | | pub const ARM64_RELOC_PAGEOFF12: u8 = 4; |
3286 | | /// pc-rel distance to page of GOT slot |
3287 | | pub const ARM64_RELOC_GOT_LOAD_PAGE21: u8 = 5; |
3288 | | /// offset within page of GOT slot, scaled by r_length |
3289 | | pub const ARM64_RELOC_GOT_LOAD_PAGEOFF12: u8 = 6; |
3290 | | /// for pointers to GOT slots |
3291 | | pub const ARM64_RELOC_POINTER_TO_GOT: u8 = 7; |
3292 | | /// pc-rel distance to page of TLVP slot |
3293 | | pub const ARM64_RELOC_TLVP_LOAD_PAGE21: u8 = 8; |
3294 | | /// offset within page of TLVP slot, scaled by r_length |
3295 | | pub const ARM64_RELOC_TLVP_LOAD_PAGEOFF12: u8 = 9; |
3296 | | /// must be followed by PAGE21 or PAGEOFF12 |
3297 | | pub const ARM64_RELOC_ADDEND: u8 = 10; |
3298 | | |
3299 | | // An arm64e authenticated pointer. |
3300 | | // |
3301 | | // Represents a pointer to a symbol (like ARM64_RELOC_UNSIGNED). |
3302 | | // Additionally, the resulting pointer is signed. The signature is |
3303 | | // specified in the target location: the addend is restricted to the lower |
3304 | | // 32 bits (instead of the full 64 bits for ARM64_RELOC_UNSIGNED): |
3305 | | // |
3306 | | // |63|62|61-51|50-49| 48 |47 - 32|31 - 0| |
3307 | | // | 1| 0| 0 | key | addr | discriminator | addend | |
3308 | | // |
3309 | | // The key is one of: |
3310 | | // IA: 00 IB: 01 |
3311 | | // DA: 10 DB: 11 |
3312 | | // |
3313 | | // The discriminator field is used as extra signature diversification. |
3314 | | // |
3315 | | // The addr field indicates whether the target address should be blended |
3316 | | // into the discriminator. |
3317 | | // |
3318 | | pub const ARM64_RELOC_AUTHENTICATED_POINTER: u8 = 11; |
3319 | | |
3320 | | // Definitions from "/usr/include/mach-o/ppc/reloc.h". |
3321 | | |
3322 | | /* |
3323 | | * Relocation types used in the ppc implementation. Relocation entries for |
3324 | | * things other than instructions use the same generic relocation as described |
3325 | | * above and their r_type is RELOC_VANILLA. The rest of the relocation types |
3326 | | * are for instructions. Since they are for instructions the r_address field |
3327 | | * indicates the 32 bit instruction that the relocation is to be performed on. |
3328 | | * The fields r_pcrel and r_length are ignored for non-RELOC_VANILLA r_types |
3329 | | * except for PPC_RELOC_BR14. |
3330 | | * |
3331 | | * For PPC_RELOC_BR14 if the r_length is the unused value 3, then the branch was |
3332 | | * statically predicted setting or clearing the Y-bit based on the sign of the |
3333 | | * displacement or the opcode. If this is the case the static linker must flip |
3334 | | * the value of the Y-bit if the sign of the displacement changes for non-branch |
3335 | | * always conditions. |
3336 | | */ |
3337 | | /// generic relocation as described above |
3338 | | pub const PPC_RELOC_VANILLA: u8 = 0; |
3339 | | /// the second relocation entry of a pair |
3340 | | pub const PPC_RELOC_PAIR: u8 = 1; |
3341 | | /// 14 bit branch displacement (to a word address) |
3342 | | pub const PPC_RELOC_BR14: u8 = 2; |
3343 | | /// 24 bit branch displacement (to a word address) |
3344 | | pub const PPC_RELOC_BR24: u8 = 3; |
3345 | | /// a PAIR follows with the low half |
3346 | | pub const PPC_RELOC_HI16: u8 = 4; |
3347 | | /// a PAIR follows with the high half |
3348 | | pub const PPC_RELOC_LO16: u8 = 5; |
3349 | | /// Same as the RELOC_HI16 except the low 16 bits and the high 16 bits are added together |
3350 | | /// with the low 16 bits sign extended first. This means if bit 15 of the low 16 bits is |
3351 | | /// set the high 16 bits stored in the instruction will be adjusted. |
3352 | | pub const PPC_RELOC_HA16: u8 = 6; |
3353 | | /// Same as the LO16 except that the low 2 bits are not stored in the instruction and are |
3354 | | /// always zero. This is used in double word load/store instructions. |
3355 | | pub const PPC_RELOC_LO14: u8 = 7; |
3356 | | /// a PAIR follows with subtract symbol value |
3357 | | pub const PPC_RELOC_SECTDIFF: u8 = 8; |
3358 | | /// prebound lazy pointer |
3359 | | pub const PPC_RELOC_PB_LA_PTR: u8 = 9; |
3360 | | /// section difference forms of above. a PAIR |
3361 | | pub const PPC_RELOC_HI16_SECTDIFF: u8 = 10; |
3362 | | /// follows these with subtract symbol value |
3363 | | pub const PPC_RELOC_LO16_SECTDIFF: u8 = 11; |
3364 | | pub const PPC_RELOC_HA16_SECTDIFF: u8 = 12; |
3365 | | pub const PPC_RELOC_JBSR: u8 = 13; |
3366 | | pub const PPC_RELOC_LO14_SECTDIFF: u8 = 14; |
3367 | | /// like PPC_RELOC_SECTDIFF, but the symbol referenced was local. |
3368 | | pub const PPC_RELOC_LOCAL_SECTDIFF: u8 = 15; |
3369 | | |
3370 | | // Definitions from "/usr/include/mach-o/x86_64/reloc.h". |
3371 | | |
3372 | | /* |
3373 | | * Relocations for x86_64 are a bit different than for other architectures in |
3374 | | * Mach-O: Scattered relocations are not used. Almost all relocations produced |
3375 | | * by the compiler are external relocations. An external relocation has the |
3376 | | * r_extern bit set to 1 and the r_symbolnum field contains the symbol table |
3377 | | * index of the target label. |
3378 | | * |
3379 | | * When the assembler is generating relocations, if the target label is a local |
3380 | | * label (begins with 'L'), then the previous non-local label in the same |
3381 | | * section is used as the target of the external relocation. An addend is used |
3382 | | * with the distance from that non-local label to the target label. Only when |
3383 | | * there is no previous non-local label in the section is an internal |
3384 | | * relocation used. |
3385 | | * |
3386 | | * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does |
3387 | | * not have RELA relocations). For PC-relative relocations, the addend is |
3388 | | * stored directly in the instruction. This is different from other Mach-O |
3389 | | * architectures, which encode the addend minus the current section offset. |
3390 | | * |
3391 | | * The relocation types are: |
3392 | | * |
3393 | | * X86_64_RELOC_UNSIGNED // for absolute addresses |
3394 | | * X86_64_RELOC_SIGNED // for signed 32-bit displacement |
3395 | | * X86_64_RELOC_BRANCH // a CALL/JMP instruction with 32-bit displacement |
3396 | | * X86_64_RELOC_GOT_LOAD // a MOVQ load of a GOT entry |
3397 | | * X86_64_RELOC_GOT // other GOT references |
3398 | | * X86_64_RELOC_SUBTRACTOR // must be followed by a X86_64_RELOC_UNSIGNED |
3399 | | * |
3400 | | * The following are sample assembly instructions, followed by the relocation |
3401 | | * and section content they generate in an object file: |
3402 | | * |
3403 | | * call _foo |
3404 | | * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3405 | | * E8 00 00 00 00 |
3406 | | * |
3407 | | * call _foo+4 |
3408 | | * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3409 | | * E8 04 00 00 00 |
3410 | | * |
3411 | | * movq _foo@GOTPCREL(%rip), %rax |
3412 | | * r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3413 | | * 48 8B 05 00 00 00 00 |
3414 | | * |
3415 | | * pushq _foo@GOTPCREL(%rip) |
3416 | | * r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3417 | | * FF 35 00 00 00 00 |
3418 | | * |
3419 | | * movl _foo(%rip), %eax |
3420 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3421 | | * 8B 05 00 00 00 00 |
3422 | | * |
3423 | | * movl _foo+4(%rip), %eax |
3424 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3425 | | * 8B 05 04 00 00 00 |
3426 | | * |
3427 | | * movb $0x12, _foo(%rip) |
3428 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3429 | | * C6 05 FF FF FF FF 12 |
3430 | | * |
3431 | | * movl $0x12345678, _foo(%rip) |
3432 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo |
3433 | | * C7 05 FC FF FF FF 78 56 34 12 |
3434 | | * |
3435 | | * .quad _foo |
3436 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3437 | | * 00 00 00 00 00 00 00 00 |
3438 | | * |
3439 | | * .quad _foo+4 |
3440 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3441 | | * 04 00 00 00 00 00 00 00 |
3442 | | * |
3443 | | * .quad _foo - _bar |
3444 | | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar |
3445 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3446 | | * 00 00 00 00 00 00 00 00 |
3447 | | * |
3448 | | * .quad _foo - _bar + 4 |
3449 | | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar |
3450 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3451 | | * 04 00 00 00 00 00 00 00 |
3452 | | * |
3453 | | * .long _foo - _bar |
3454 | | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar |
3455 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3456 | | * 00 00 00 00 |
3457 | | * |
3458 | | * lea L1(%rip), %rax |
3459 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev |
3460 | | * 48 8d 05 12 00 00 00 |
3461 | | * // assumes _prev is the first non-local label 0x12 bytes before L1 |
3462 | | * |
3463 | | * lea L0(%rip), %rax |
3464 | | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 |
3465 | | * 48 8d 05 56 00 00 00 |
3466 | | * // assumes L0 is in third section and there is no previous non-local label. |
3467 | | * // The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction. |
3468 | | * // address_of_next_instruction is the address of the relocation + 4. |
3469 | | * |
3470 | | * add $6,L0(%rip) |
3471 | | * r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 |
3472 | | * 83 05 18 00 00 00 06 |
3473 | | * // assumes L0 is in third section and there is no previous non-local label. |
3474 | | * // The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction. |
3475 | | * // address_of_next_instruction is the address of the relocation + 4 + 1. |
3476 | | * // The +1 comes from SIGNED_1. This is used because the relocation is not |
3477 | | * // at the end of the instruction. |
3478 | | * |
3479 | | * .quad L1 |
3480 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev |
3481 | | * 12 00 00 00 00 00 00 00 |
3482 | | * // assumes _prev is the first non-local label 0x12 bytes before L1 |
3483 | | * |
3484 | | * .quad L0 |
3485 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3 |
3486 | | * 56 00 00 00 00 00 00 00 |
3487 | | * // assumes L0 is in third section, has an address of 0x00000056 in .o |
3488 | | * // file, and there is no previous non-local label |
3489 | | * |
3490 | | * .quad _foo - . |
3491 | | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev |
3492 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3493 | | * EE FF FF FF FF FF FF FF |
3494 | | * // assumes _prev is the first non-local label 0x12 bytes before this |
3495 | | * // .quad |
3496 | | * |
3497 | | * .quad _foo - L1 |
3498 | | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev |
3499 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo |
3500 | | * EE FF FF FF FF FF FF FF |
3501 | | * // assumes _prev is the first non-local label 0x12 bytes before L1 |
3502 | | * |
3503 | | * .quad L1 - _prev |
3504 | | * // No relocations. This is an assembly time constant. |
3505 | | * 12 00 00 00 00 00 00 00 |
3506 | | * // assumes _prev is the first non-local label 0x12 bytes before L1 |
3507 | | * |
3508 | | * |
3509 | | * |
3510 | | * In final linked images, there are only two valid relocation kinds: |
3511 | | * |
3512 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index |
3513 | | * This tells dyld to add the address of a symbol to a pointer sized (8-byte) |
3514 | | * piece of data (i.e on disk the 8-byte piece of data contains the addend). The |
3515 | | * r_symbolnum contains the index into the symbol table of the target symbol. |
3516 | | * |
3517 | | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0 |
3518 | | * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount |
3519 | | * the containing image was loaded from its base address (e.g. slide). |
3520 | | * |
3521 | | */ |
3522 | | /// for absolute addresses |
3523 | | pub const X86_64_RELOC_UNSIGNED: u8 = 0; |
3524 | | /// for signed 32-bit displacement |
3525 | | pub const X86_64_RELOC_SIGNED: u8 = 1; |
3526 | | /// a CALL/JMP instruction with 32-bit displacement |
3527 | | pub const X86_64_RELOC_BRANCH: u8 = 2; |
3528 | | /// a MOVQ load of a GOT entry |
3529 | | pub const X86_64_RELOC_GOT_LOAD: u8 = 3; |
3530 | | /// other GOT references |
3531 | | pub const X86_64_RELOC_GOT: u8 = 4; |
3532 | | /// must be followed by a X86_64_RELOC_UNSIGNED |
3533 | | pub const X86_64_RELOC_SUBTRACTOR: u8 = 5; |
3534 | | /// for signed 32-bit displacement with a -1 addend |
3535 | | pub const X86_64_RELOC_SIGNED_1: u8 = 6; |
3536 | | /// for signed 32-bit displacement with a -2 addend |
3537 | | pub const X86_64_RELOC_SIGNED_2: u8 = 7; |
3538 | | /// for signed 32-bit displacement with a -4 addend |
3539 | | pub const X86_64_RELOC_SIGNED_4: u8 = 8; |
3540 | | /// for thread local variables |
3541 | | pub const X86_64_RELOC_TLV: u8 = 9; |
3542 | | |
3543 | | unsafe_impl_pod!(FatHeader, FatArch32, FatArch64,); |
3544 | | unsafe_impl_endian_pod!( |
3545 | | DyldCacheHeader, |
3546 | | DyldCacheMappingInfo, |
3547 | | DyldCacheMappingAndSlideInfo, |
3548 | | DyldCacheImageInfo, |
3549 | | DyldCacheSlideInfo2, |
3550 | | DyldCacheSlideInfo3, |
3551 | | DyldCacheSlideInfo5, |
3552 | | DyldSubCacheEntryV1, |
3553 | | DyldSubCacheEntryV2, |
3554 | | MachHeader32, |
3555 | | MachHeader64, |
3556 | | LoadCommand, |
3557 | | LcStr, |
3558 | | SegmentCommand32, |
3559 | | SegmentCommand64, |
3560 | | Section32, |
3561 | | Section64, |
3562 | | Fvmlib, |
3563 | | FvmlibCommand, |
3564 | | Dylib, |
3565 | | DylibCommand, |
3566 | | SubFrameworkCommand, |
3567 | | SubClientCommand, |
3568 | | SubUmbrellaCommand, |
3569 | | SubLibraryCommand, |
3570 | | PreboundDylibCommand, |
3571 | | DylinkerCommand, |
3572 | | ThreadCommand, |
3573 | | RoutinesCommand32, |
3574 | | RoutinesCommand64, |
3575 | | SymtabCommand, |
3576 | | DysymtabCommand, |
3577 | | DylibTableOfContents, |
3578 | | DylibModule32, |
3579 | | DylibModule64, |
3580 | | DylibReference, |
3581 | | TwolevelHintsCommand, |
3582 | | TwolevelHint, |
3583 | | PrebindCksumCommand, |
3584 | | UuidCommand, |
3585 | | RpathCommand, |
3586 | | LinkeditDataCommand, |
3587 | | FilesetEntryCommand, |
3588 | | EncryptionInfoCommand32, |
3589 | | EncryptionInfoCommand64, |
3590 | | VersionMinCommand, |
3591 | | BuildVersionCommand, |
3592 | | BuildToolVersion, |
3593 | | DyldInfoCommand, |
3594 | | LinkerOptionCommand, |
3595 | | SymsegCommand, |
3596 | | IdentCommand, |
3597 | | FvmfileCommand, |
3598 | | EntryPointCommand, |
3599 | | SourceVersionCommand, |
3600 | | DataInCodeEntry, |
3601 | | //TlvDescriptor, |
3602 | | NoteCommand, |
3603 | | Nlist32, |
3604 | | Nlist64, |
3605 | | Relocation, |
3606 | | ); |