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