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