1 // copyright (c) 2017-2021 hors<horsicq@gmail.com> 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 10 // The above copyright notice and this permission notice shall be included in all 11 // copies or substantial portions of the Software. 12 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 // SOFTWARE. 20 // 21 #ifndef QMACH_DEF_H 22 #define QMACH_DEF_H 23 24 #include <QtGlobal> 25 26 namespace XMACH_DEF 27 { 28 /* Constant for the magic field of the mach_header (32-bit architectures) */ 29 const quint32 S_MH_MAGIC =0xFEEDFACE; /* the mach magic number */ 30 const quint32 S_MH_CIGAM =0xCEFAEDFE ; /* NXSwapInt(MH_MAGIC) */ 31 /* Constant for the magic field of the mach_header_64 (64-bit architectures) */ 32 const quint32 S_MH_MAGIC_64 =0xFEEDFACF; /* the 64-bit mach magic number */ 33 const quint32 S_MH_CIGAM_64 =0xCFFAEDFE; /* NXSwapInt(MH_MAGIC_64) */ 34 35 const quint32 S_FAT_MAGIC =0xCAFEBABE; 36 const quint32 S_FAT_CIGAM =0xBEBAFECA; 37 38 const quint32 S_CPU_TYPE_VAX =0x00000001; 39 const quint32 S_CPU_TYPE_ROMP =0x00000002; 40 const quint32 S_CPU_TYPE_NS32032 =0x00000004; 41 const quint32 S_CPU_TYPE_NS32332 =0x00000005; 42 const quint32 S_CPU_TYPE_MC680x0 =0x00000006; 43 const quint32 S_CPU_TYPE_I386 =0x00000007; 44 const quint32 S_CPU_TYPE_X86_64 =0x01000007; 45 const quint32 S_CPU_TYPE_MIPS =0x00000008; 46 const quint32 S_CPU_TYPE_NS32532 =0x00000009; 47 const quint32 S_CPU_TYPE_HPPA =0x0000000B; 48 const quint32 S_CPU_TYPE_ARM =0x0000000C; 49 const quint32 S_CPU_TYPE_ARM64 =0x0100000C; 50 const quint32 S_CPU_TYPE_MC88000 =0x0000000D; 51 const quint32 S_CPU_TYPE_SPARC =0x0000000E; 52 const quint32 S_CPU_TYPE_I860 =0x0000000F; 53 const quint32 S_CPU_TYPE_RS6000 =0x00000011; 54 const quint32 S_CPU_TYPE_MC98000 =0x00000012; 55 const quint32 S_CPU_TYPE_POWERPC =0x00000012; 56 const quint32 S_CPU_TYPE_POWERPC64 =0x01000012; 57 const quint32 S_CPU_TYPE_VEO =0x000000FF; 58 59 const quint32 S_INDIRECT_SYMBOL_LOCAL =0x80000000; 60 const quint32 S_INDIRECT_SYMBOL_ABS =0x40000000; 61 62 struct fat_header 63 { 64 quint32 magic; 65 quint32 nfat_arch; 66 }; 67 68 struct fat_arch 69 { 70 quint32 cputype; 71 quint32 cpusubtype; 72 quint32 offset; 73 quint32 size; 74 quint32 align; 75 }; 76 77 /* 78 * The 32-bit mach header appears at the very beginning of the object file for 79 * 32-bit architectures. 80 */ 81 struct mach_header 82 { 83 quint32 magic; /* mach magic number identifier */ 84 quint32 cputype; /* cpu specifier */ 85 quint32 cpusubtype; /* machine specifier */ 86 quint32 filetype; /* type of file */ 87 quint32 ncmds; /* number of load commands */ 88 quint32 sizeofcmds; /* the size of all the load commands */ 89 quint32 flags; /* flags */ 90 }; 91 92 /* 93 * The 64-bit mach header appears at the very beginning of object files for 94 * 64-bit architectures. 95 */ 96 struct mach_header_64 97 { 98 quint32 magic; /* mach magic number identifier */ 99 quint32 cputype; /* cpu specifier */ 100 quint32 cpusubtype; /* machine specifier */ 101 quint32 filetype; /* type of file */ 102 quint32 ncmds; /* number of load commands */ 103 quint32 sizeofcmds; /* the size of all the load commands */ 104 quint32 flags; /* flags */ 105 quint32 reserved; 106 /* reserved */ 107 }; 108 109 struct load_command 110 { 111 quint32 cmd; 112 quint32 cmdsize; 113 }; 114 115 struct segment_command 116 { 117 quint32 cmd; 118 quint32 cmdsize; 119 char segname[16]; 120 quint32 vmaddr; 121 quint32 vmsize; 122 quint32 fileoff; 123 quint32 filesize; 124 quint32 maxprot; 125 quint32 initprot; 126 quint32 nsects; 127 quint32 flags; 128 }; 129 130 struct segment_command_64 131 { 132 quint32 cmd; 133 quint32 cmdsize; 134 char segname[16]; 135 quint64 vmaddr; 136 quint64 vmsize; 137 quint64 fileoff; 138 quint64 filesize; 139 quint32 maxprot; 140 quint32 initprot; 141 quint32 nsects; 142 quint32 flags; 143 }; 144 145 struct section /* for 32-bit architectures */ 146 { 147 char sectname[16]; /* name of this section */ 148 char segname[16]; /* segment this section goes in */ 149 quint32 addr; /* memory address of this section */ 150 quint32 size; /* size in bytes of this section */ 151 quint32 offset; /* file offset of this section */ 152 quint32 align; /* section alignment (power of 2) */ 153 quint32 reloff; /* file offset of relocation entries */ 154 quint32 nreloc; /* number of relocation entries */ 155 quint32 flags; /* flags (section type and attributes)*/ 156 quint32 reserved1; /* reserved (for offset or index) */ 157 quint32 reserved2; /* reserved (for count or sizeof) */ 158 }; 159 160 struct section_64 /* for 64-bit architectures */ 161 { 162 char sectname[16]; /* name of this section */ 163 char segname[16]; /* segment this section goes in */ 164 quint64 addr; /* memory address of this section */ 165 quint64 size; /* size in bytes of this section */ 166 quint32 offset; /* file offset of this section */ 167 quint32 align; /* section alignment (power of 2) */ 168 quint32 reloff; /* file offset of relocation entries */ 169 quint32 nreloc; /* number of relocation entries */ 170 quint32 flags; /* flags (section type and attributes)*/ 171 quint32 reserved1; /* reserved (for offset or index) */ 172 quint32 reserved2; /* reserved (for count or sizeof) */ 173 quint32 reserved3; /* reserved */ 174 }; 175 176 const quint32 S_LC_REQ_DYLD =0x80000000; 177 const quint32 S_LC_SEGMENT =0x1; /* segment of this file to be mapped */ 178 const quint32 S_LC_SYMTAB =0x2; /* link-edit stab symbol table info */ 179 const quint32 S_LC_SYMSEG =0x3; /* link-edit gdb symbol table info (obsolete) */ 180 const quint32 S_LC_THREAD =0x4; /* thread */ 181 const quint32 S_LC_UNIXTHREAD =0x5; /* unix thread (includes a stack) */ 182 const quint32 S_LC_LOADFVMLIB =0x6; /* load a specified fixed VM shared library */ 183 const quint32 S_LC_IDFVMLIB =0x7; /* fixed VM shared library identification */ 184 const quint32 S_LC_IDENT =0x8; /* object identification info (obsolete) */ 185 const quint32 S_LC_FVMFILE =0x9; /* fixed VM file inclusion (internal use) */ 186 const quint32 S_LC_PREPAGE =0xA; /* prepage command (internal use) */ 187 const quint32 S_LC_DYSYMTAB =0xB; /* dynamic link-edit symbol table info */ 188 const quint32 S_LC_LOAD_DYLIB =0xC; /* load a dynamicly linked shared library */ 189 const quint32 S_LC_ID_DYLIB =0xD; /* dynamicly linked shared lib identification */ 190 const quint32 S_LC_LOAD_DYLINKER =0xE; /* load a dynamic linker */ 191 const quint32 S_LC_ID_DYLINKER =0xF; /* dynamic linker identification */ 192 const quint32 S_LC_PREBOUND_DYLIB =0x10; /* modules prebound for a dynamicly */ 193 const quint32 S_LC_ROUTINES =0x11; /* image routines */ 194 const quint32 S_LC_SUB_FRAMEWORK =0x12; /* sub framework */ 195 const quint32 S_LC_SUB_UMBRELLA =0x13; /* sub umbrella */ 196 const quint32 S_LC_SUB_CLIENT =0x14; /* sub client */ 197 const quint32 S_LC_SUB_LIBRARY =0x15; /* sub library */ 198 const quint32 S_LC_TWOLEVEL_HINTS =0x16; /* two-level namespace lookup hints */ 199 const quint32 S_LC_PREBIND_CKSUM =0x17; /* prebind checksum */ 200 const quint32 S_LC_LOAD_WEAK_DYLIB =(0x18|S_LC_REQ_DYLD); 201 const quint32 S_LC_SEGMENT_64 =0x19; /* 64-bit segment of this file to bemapped */ 202 const quint32 S_LC_ROUTINES_64 =0x1A; /* 64-bit image routines */ 203 const quint32 S_LC_UUID =0x1B; /* the uuid */ 204 const quint32 S_LC_RPATH =(0x1C|S_LC_REQ_DYLD); 205 const quint32 S_LC_CODE_SIGNATURE =0x1D; 206 const quint32 S_LC_ENCRYPTION_INFO =0x21; 207 const quint32 S_LC_DYLD_INFO =0x22; 208 const quint32 S_LC_DYLD_INFO_ONLY =(0x22|S_LC_REQ_DYLD); 209 const quint32 S_LC_VERSION_MIN_MACOSX =0x24; 210 const quint32 S_LC_VERSION_MIN_IPHONEOS =0x25; 211 const quint32 S_LC_FUNCTION_STARTS =0x26; 212 const quint32 S_LC_DATA_IN_CODE =0x29; 213 const quint32 S_LC_SOURCE_VERSION =0x2A; 214 const quint32 S_LC_ENCRYPTION_INFO_64 =0x2C; 215 const quint32 S_LC_VERSION_MIN_TVOS =0x2F; 216 const quint32 S_LC_VERSION_MIN_WATCHOS =0x30; 217 218 const quint32 S_LC_MAIN =(0x28|S_LC_REQ_DYLD); /* main */ 219 220 const quint32 S_MH_OBJECT =0x1; /* relocatable object file */ 221 const quint32 S_MH_EXECUTE =0x2; /* demand paged executable file */ 222 const quint32 S_MH_FVMLIB =0x3; /* fixed VM shared library file */ 223 const quint32 S_MH_CORE =0x4; /* core file */ 224 const quint32 S_MH_PRELOAD =0x5; /* preloaded executable file */ 225 const quint32 S_MH_DYLIB =0x6; /* dynamicly bound shared library file*/ 226 const quint32 S_MH_DYLINKER =0x7; /* dynamic link editor */ 227 const quint32 S_MH_BUNDLE =0x8; /* dynamicly bound bundle file */ 228 const quint32 S_MH_DYLIB_STUB =0x9; 229 const quint32 S_MH_DSYM =0xa; 230 const quint32 S_MH_KEXT_BUNDLE =0xb; 231 232 const quint32 S_VM_PROT_NONE =0x00; 233 const quint32 S_VM_PROT_READ =0x01; /* read permission */ 234 const quint32 S_VM_PROT_WRITE =0x02; /* write permission */ 235 const quint32 S_VM_PROT_EXECUTE =0x04; /* execute permission */ 236 237 const quint32 S_SECTION_TYPE =0x000000ff; 238 const quint32 S_SECTION_ATTRIBUTES_SYS =0x00ffff00; /* system setable attributes */ 239 const quint32 S_SECTION_ATTRIBUTES_USR =0xff000000; /* User setable attributes */ 240 241 struct x86_thread_state32_t 242 { 243 quint32 eax; 244 quint32 ebx; 245 quint32 ecx; 246 quint32 edx; 247 quint32 edi; 248 quint32 esi; 249 quint32 ebp; 250 quint32 esp; 251 quint32 ss; 252 quint32 eflags; 253 quint32 eip; 254 quint32 cs; 255 quint32 ds; 256 quint32 es; 257 quint32 fs; 258 quint32 gs; 259 }; 260 261 struct x86_thread_state64_t 262 { 263 quint64 rax; 264 quint64 rbx; 265 quint64 rcx; 266 quint64 rdx; 267 quint64 rdi; 268 quint64 rsi; 269 quint64 rbp; 270 quint64 rsp; 271 quint64 r8; 272 quint64 r9; 273 quint64 r10; 274 quint64 r11; 275 quint64 r12; 276 quint64 r13; 277 quint64 r14; 278 quint64 r15; 279 quint64 rip; 280 quint64 rflags; 281 quint64 cs; 282 quint64 fs; 283 quint64 gs; 284 }; 285 286 struct fp_control_t 287 { 288 quint16 invalid:1; 289 quint16 denorm:1; 290 quint16 zdiv:1; 291 quint16 ovrfl:1; 292 quint16 undfl:1; 293 quint16 precis:1; 294 quint16 :2; 295 quint16 pc:2; 296 quint16 rc:2; 297 quint16 :1; 298 quint16 :3; 299 }; 300 301 struct fp_status_t 302 { 303 quint16 invalid:1; 304 quint16 denorm:1; 305 quint16 zdiv:1; 306 quint16 ovrfl:1; 307 quint16 undfl:1; 308 quint16 precis:1; 309 quint16 stkflt:1; 310 quint16 errsumm:1; 311 quint16 c0:1; 312 quint16 c1:1; 313 quint16 c2:1; 314 quint16 tos:3; 315 quint16 c3:1; 316 quint16 busy:1; 317 }; 318 319 struct mmst_reg_t 320 { 321 qint8 mmst_reg[10]; 322 qint8 mmst_rsrv[6]; 323 }; 324 325 struct xmm_reg_t 326 { 327 qint8 xmm_reg[16]; 328 }; 329 330 struct x86_float_state64_t 331 { 332 qint32 fpu_reserved[2]; 333 fp_control_t fpu_fcw; 334 fp_status_t fpu_fsw; 335 quint8 fpu_ftw; 336 quint8 fpu_rsrv1; 337 quint16 fpu_fop; 338 quint32 fpu_ip; 339 quint16 fpu_cs; 340 quint16 fpu_rsrv2; 341 quint32 fpu_dp; 342 quint16 fpu_ds; 343 quint16 fpu_rsrv3; 344 quint32 fpu_mxcsr; 345 quint32 fpu_mxcsrmask; 346 mmst_reg_t fpu_stmm0; 347 mmst_reg_t fpu_stmm1; 348 mmst_reg_t fpu_stmm2; 349 mmst_reg_t fpu_stmm3; 350 mmst_reg_t fpu_stmm4; 351 mmst_reg_t fpu_stmm5; 352 mmst_reg_t fpu_stmm6; 353 mmst_reg_t fpu_stmm7; 354 xmm_reg_t fpu_xmm0; 355 xmm_reg_t fpu_xmm1; 356 xmm_reg_t fpu_xmm2; 357 xmm_reg_t fpu_xmm3; 358 xmm_reg_t fpu_xmm4; 359 xmm_reg_t fpu_xmm5; 360 xmm_reg_t fpu_xmm6; 361 xmm_reg_t fpu_xmm7; 362 xmm_reg_t fpu_xmm8; 363 xmm_reg_t fpu_xmm9; 364 xmm_reg_t fpu_xmm10; 365 xmm_reg_t fpu_xmm11; 366 xmm_reg_t fpu_xmm12; 367 xmm_reg_t fpu_xmm13; 368 xmm_reg_t fpu_xmm14; 369 xmm_reg_t fpu_xmm15; 370 qint8 fpu_rsrv4[6*16]; 371 quint32 fpu_reserved1; 372 }; 373 374 struct x86_exception_state64_t 375 { 376 quint16 trapno; 377 quint16 cpu; 378 quint32 err; 379 quint64 faultvaddr; 380 }; 381 382 struct x86_state_hdr_t 383 { 384 quint32 flavor; 385 quint32 count; 386 }; 387 388 struct x86_thread_state_t 389 { 390 x86_state_hdr_t tsh; 391 union 392 { 393 x86_thread_state64_t ts64; 394 x86_thread_state32_t ts32; 395 } uts; 396 }; 397 398 struct x86_float_state_t 399 { 400 x86_state_hdr_t fsh; 401 union 402 { 403 x86_float_state64_t fs64; 404 } ufs; 405 }; 406 407 struct x86_exception_state_t 408 { 409 x86_state_hdr_t esh; 410 union 411 { 412 x86_exception_state64_t es64; 413 } ues; 414 }; 415 416 enum X86ThreadFlavors 417 { 418 x86_THREAD_STATE32=1, 419 x86_FLOAT_STATE32=2, 420 x86_EXCEPTION_STATE32=3, 421 x86_THREAD_STATE64=4, 422 x86_FLOAT_STATE64=5, 423 x86_EXCEPTION_STATE64=6, 424 x86_THREAD_STATE=7, 425 x86_FLOAT_STATE=8, 426 x86_EXCEPTION_STATE=9, 427 x86_DEBUG_STATE32=10, 428 x86_DEBUG_STATE64=11, 429 x86_DEBUG_STATE=12 430 }; 431 432 struct arm_thread_state32_t 433 { 434 quint32 r[13]; 435 quint32 sp; 436 quint32 lr; 437 quint32 pc; 438 quint32 cpsr; 439 }; 440 441 struct arm_thread_state64_t 442 { 443 quint64 x[29]; 444 quint64 fp; 445 quint64 lr; 446 quint64 sp; 447 quint64 pc; 448 quint32 cpsr; 449 quint32 pad; 450 }; 451 452 struct arm_state_hdr_t 453 { 454 quint32 flavor; 455 quint32 count; 456 }; 457 458 struct arm_thread_state_t 459 { 460 arm_state_hdr_t tsh; 461 union 462 { 463 arm_thread_state32_t ts32; 464 } uts; 465 }; 466 467 enum ARMThreadFlavors 468 { 469 ARM_THREAD_STATE=1, 470 ARM_VFP_STATE=2, 471 ARM_EXCEPTION_STATE=3, 472 ARM_DEBUG_STATE=4, 473 ARN_THREAD_STATE_NONE=5, 474 ARM_THREAD_STATE64=6, 475 ARM_EXCEPTION_STATE64=7 476 }; 477 478 struct ppc_thread_state32_t 479 { 480 quint32 srr0; 481 quint32 srr1; 482 quint32 r[32]; 483 quint32 ct; 484 quint32 xer; 485 quint32 lr; 486 quint32 ctr; 487 quint32 mq; 488 quint32 vrsave; 489 }; 490 491 struct ppc_state_hdr_t 492 { 493 quint32 flavor; 494 quint32 count; 495 }; 496 497 struct ppc_thread_state_t 498 { 499 ppc_state_hdr_t tsh; 500 union 501 { 502 ppc_thread_state32_t ts32; 503 } uts; 504 }; 505 506 enum PPCThreadFlavors 507 { 508 PPC_THREAD_STATE=1, 509 PPC_FLOAT_STATE=2, 510 PPC_EXCEPTION_STATE=3, 511 PPC_VECTOR_STATE=4, 512 PPC_THREAD_STATE64=5, 513 PPC_EXCEPTION_STATE64=6, 514 PPC_THREAD_STATE_NONE=7 515 }; 516 517 struct m68k_thread_state32_t 518 { 519 quint32 dreg[8]; /* data registers */ 520 quint32 areg[8]; /* address registers (incl stack pointer) */ 521 quint16 pad0; /* not used */ 522 quint16 sr; /* user's status register */ 523 quint32 pc; /* user's program counter */ 524 }; 525 526 struct m68k_state_hdr_t 527 { 528 quint32 flavor; 529 quint32 count; 530 }; 531 532 struct m68k_thread_state_t 533 { 534 m68k_state_hdr_t tsh; 535 union 536 { 537 m68k_thread_state32_t ts32; 538 } uts; 539 }; 540 541 const quint32 S_M68K_THREAD_STATE_REGS =1; /* normal registers */ 542 const quint32 S_M68K_THREAD_STATE_68882 =2; /* 68882 registers */ 543 const quint32 S_M68K_THREAD_STATE_USER_REG =3; /* additional user register */ 544 545 struct state_hdr_t 546 { 547 quint32 flavor; 548 quint32 count; 549 }; 550 551 struct entry_point_command 552 { 553 quint32 cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */ 554 quint32 cmdsize; /* 24 */ 555 quint64 entryoff; /* file (__TEXT) offset of main() */ 556 quint64 stacksize; /* if not zero, initial stack size */ 557 }; 558 559 struct unix_thread_command 560 { 561 quint32 cmd; 562 quint32 cmdsize; 563 quint32 flavor; 564 quint32 count; 565 }; 566 567 struct dylib 568 { 569 quint32 name; // rel offset 570 quint32 timestamp; 571 quint32 current_version; 572 quint32 compatibility_version; 573 }; 574 575 struct dylib_command 576 { 577 quint32 cmd; 578 quint32 cmdsize; 579 dylib _dylib; 580 }; 581 582 struct dyld_info_command 583 { 584 quint32 cmd; 585 quint32 cmdsize; 586 quint32 rebase_off; 587 quint32 rebase_size; 588 quint32 bind_off; 589 quint32 bind_size; 590 quint32 weak_bind_off; 591 quint32 weak_bind_size; 592 quint32 lazy_bind_off; 593 quint32 lazy_bind_size; 594 quint32 export_off; 595 quint32 export_size; 596 }; 597 /* 598 * Fixed virtual memory shared libraries are identified by two things. The 599 * target pathname (the name of the library as found for execution), and the 600 * minor version number. The address of where the headers are loaded is in 601 * header_addr. 602 */ 603 struct fvmlib 604 { 605 quint32 name; /* library's target pathname */ 606 quint32 minor_version; /* library's minor version number */ 607 quint32 header_addr; /* library's header address */ 608 }; 609 610 /* 611 * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) 612 * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library. 613 * An object that uses a fixed virtual shared library also contains a 614 * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. 615 */ 616 struct fvmlib_command 617 { 618 quint32 cmd; /* LC_IDFVMLIB or LC_LOADFVMLIB */ 619 quint32 cmdsize; /* includes pathname string */ 620 struct fvmlib fvmlib; /* the library identification */ 621 }; 622 623 struct uuid_command 624 { 625 quint32 cmd; 626 quint32 cmdsize; 627 quint8 uuid[16]; 628 }; 629 630 struct symtab_command 631 { 632 quint32 cmd; 633 quint32 cmdsize; 634 quint32 symoff; 635 quint32 nsyms; 636 quint32 stroff; 637 quint32 strsize; 638 }; 639 640 struct dysymtab_command 641 { 642 quint32 cmd; 643 quint32 cmdsize; 644 quint32 ilocalsym; 645 quint32 nlocalsym; 646 quint32 iextdefsym; 647 quint32 nextdefsym; 648 quint32 iundefsym; 649 quint32 nundefsym; 650 quint32 tocoff; 651 quint32 ntoc; 652 quint32 modtaboff; 653 quint32 nmodtab; 654 quint32 extrefsymoff; 655 quint32 nextrefsyms; 656 quint32 indirectsymoff; 657 quint32 nindirectsyms; 658 quint32 extreloff; 659 quint32 nextrel; 660 quint32 locreloff; 661 quint32 nlocrel; 662 }; 663 664 struct version_min_command 665 { 666 quint32 cmd; // LC_VERSION_MIN_MACOSX or 667 // LC_VERSION_MIN_IPHONEOS 668 quint32 cmdsize; // sizeof(struct version_min_command) 669 quint32 version; // X.Y.Z is encoded in nibbles xxxx.yy.zz 670 quint32 sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz 671 }; 672 673 struct dylinker_command 674 { 675 quint32 cmd; 676 quint32 cmdsize; 677 quint32 name; 678 }; 679 680 struct rpath_command 681 { 682 quint32 cmd; 683 quint32 cmdsize; 684 quint32 path; 685 }; 686 687 struct source_version_command 688 { 689 quint32 cmd; 690 quint32 cmdsize; 691 quint64 version; 692 }; 693 694 struct encryption_info_command 695 { 696 quint32 cmd; 697 quint32 cmdsize; 698 quint32 cryptoff; 699 quint32 cryptsize; 700 quint32 cryptid; 701 }; 702 703 struct encryption_info_command_64 704 { 705 quint32 cmd; 706 quint32 cmdsize; 707 quint32 cryptoff; 708 quint32 cryptsize; 709 quint32 cryptid; 710 quint32 pad; 711 }; 712 713 struct dylib_module 714 { 715 quint32 module_name; 716 quint32 iextdefsym; 717 quint32 nextdefsym; 718 quint32 irefsym; 719 quint32 nrefsym; 720 quint32 ilocalsym; 721 quint32 nlocalsym; 722 quint32 iextrel; 723 quint32 nextrel; 724 quint32 iinit_iterm; 725 quint32 ninit_nterm; 726 quint32 objc_module_info_addr; 727 quint32 objc_module_info_size; 728 }; 729 730 struct dylib_module_64 731 { 732 quint32 module_name; 733 quint32 iextdefsym; 734 quint32 nextdefsym; 735 quint32 irefsym; 736 quint32 nrefsym; 737 quint32 ilocalsym; 738 quint32 nlocalsym; 739 quint32 iextrel; 740 quint32 nextrel; 741 quint32 iinit_iterm; 742 quint32 ninit_nterm; 743 quint32 objc_module_info_size; 744 quint64 objc_module_info_addr; 745 }; 746 747 struct routines_command 748 { 749 quint32 cmd; 750 quint32 cmdsize; 751 quint32 init_address; 752 quint32 init_module; 753 quint32 reserved1; 754 quint32 reserved2; 755 quint32 reserved3; 756 quint32 reserved4; 757 quint32 reserved5; 758 quint32 reserved6; 759 }; 760 761 struct routines_command_64 762 { 763 quint32 cmd; 764 quint32 cmdsize; 765 quint64 init_address; 766 quint64 init_module; 767 quint64 reserved1; 768 quint64 reserved2; 769 quint64 reserved3; 770 quint64 reserved4; 771 quint64 reserved5; 772 quint64 reserved6; 773 }; 774 775 struct linkedit_data_command 776 { 777 quint32 cmd; 778 quint32 cmdsize; 779 quint32 dataoff; 780 quint32 datasize; 781 }; 782 783 struct data_in_code_entry 784 { 785 quint32 offset; /* from mach_header to start of data range*/ 786 quint16 length; /* number of bytes in data range */ 787 quint16 kind; /* a DICE_KIND_* value */ 788 }; 789 790 struct nlist 791 { 792 quint32 n_strx; 793 quint8 n_type; 794 quint8 n_sect; 795 quint16 n_desc; 796 quint32 n_value; 797 }; 798 799 struct nlist_64 800 { 801 quint32 n_strx; 802 quint8 n_type; 803 quint8 n_sect; 804 quint16 n_desc; 805 quint64 n_value; 806 }; 807 808 struct sub_framework_command 809 { 810 quint32 cmd; 811 quint32 cmdsize; 812 quint32 umbrella; 813 }; 814 815 struct sub_client_command 816 { 817 quint32 cmd; 818 quint32 cmdsize; 819 quint32 client; 820 }; 821 822 struct sub_umbrella_command 823 { 824 quint32 cmd; 825 quint32 cmdsize; 826 quint32 sub_umbrella; 827 }; 828 829 struct sub_library_command 830 { 831 quint32 cmd; 832 quint32 cmdsize; 833 quint32 sub_library; 834 }; 835 836 struct prebound_dylib_command 837 { 838 quint32 cmd; 839 quint32 cmdsize; 840 quint32 name; 841 quint32 nmodules; 842 quint32 linked_modules; 843 }; 844 845 struct thread_command 846 { 847 quint32 cmd; 848 quint32 cmdsize; 849 }; 850 851 struct twolevel_hints_command 852 { 853 quint32 cmd; 854 quint32 cmdsize; 855 quint32 offset; 856 quint32 nhints; 857 }; 858 859 struct prebind_cksum_command 860 { 861 quint32 cmd; 862 quint32 cmdsize; 863 quint32 cksum; 864 }; 865 866 struct symseg_command 867 { 868 quint32 cmd; 869 quint32 cmdsize; 870 quint32 offset; 871 quint32 size; 872 }; 873 874 struct ident_command 875 { 876 quint32 cmd; 877 quint32 cmdsize; 878 }; 879 880 struct fvmfile_command 881 { 882 quint32 cmd; 883 quint32 cmdsize; 884 quint32 name; 885 quint32 header_addr; 886 }; 887 888 struct dylib_table_of_contents 889 { 890 quint32 symbol_index; /* the defined external symbol (index into the symbol table) */ 891 quint32 module_index; /* index into the module table this symbol is defined in */ 892 }; 893 894 struct relocation_info 895 { 896 quint32 r_address; /* offset in the section to what is being relocated */ 897 union 898 { 899 quint32 value; 900 struct 901 { 902 quint32 r_symbolnum:24; /* symbol index if r_extern == 1 or section ordinal if r_extern == 0 */ 903 quint32 r_pcrel:1; /* was relocated pc relative already */ 904 quint32 r_length:2; /* 0=byte, 1=word, 2=long, 3=quad */ 905 quint32 r_extern:1; /* does not include value of sym referenced */ 906 quint32 r_type:4; /* if not 0, machine specific relocation type */ 907 } _value; 908 } s; 909 }; 910 911 /* 912 * The entries in the reference symbol table are used when loading the module 913 * (both by the static and dynamic link editors) and if the module is unloaded 914 * or replaced. Therefore all external symbols (defined and undefined) are 915 * listed in the module's reference table. The flags describe the type of 916 * reference that is being made. The constants for the flags are defined in 917 * <mach-o/nlist.h> as they are also used for symbol table entries. 918 */ 919 struct dylib_reference 920 { 921 union 922 { 923 quint32 value; 924 struct 925 { 926 quint32 isym:24; /* index into the symbol table */ 927 quint32 flags:8; /* flags to indicate the type of reference */ 928 } _value; 929 } s; 930 }; 931 932 // https://llvm.org/doxygen/BinaryFormat_2MachO_8h_source.html 933 // http://formats.kaitai.io/mach_o/ 934 // https://github.com/phausler/Shinobi/blob/master/include/llvm/Support/MachO.h 935 // https://gist.github.com/yamaya/2924292 936 // https://github.com/aidansteele/osx-abi-macho-file-format-reference 937 // https://code.woboq.org/llvm/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h.html 938 // https://stuff.mit.edu/afs/sipb/project/gnu/share/gcc-lib/m68k-next-mach31/2.5.4/include/mach/m68k/thread_status.h 939 enum reloc_type_x86_64 940 { 941 X86_64_RELOC_UNSIGNED, // for absolute addresses 942 X86_64_RELOC_SIGNED, // for signed 32-bit displacement 943 X86_64_RELOC_BRANCH, // a CALL/JMP instruction with 32-bit displacement 944 X86_64_RELOC_GOT_LOAD, // a MOVQ load of a GOT entry 945 X86_64_RELOC_GOT, // other GOT references 946 X86_64_RELOC_SUBTRACTOR, // must be followed by a X86_64_RELOC_UNSIGNED 947 X86_64_RELOC_SIGNED_1, // for signed 32-bit displacement with a -1 addend 948 X86_64_RELOC_SIGNED_2, // for signed 32-bit displacement with a -2 addend 949 X86_64_RELOC_SIGNED_4, // for signed 32-bit displacement with a -4 addend 950 }; 951 952 enum reloc_type_arm 953 { 954 ARM_RELOC_VANILLA, /* generic relocation as discribed above */ 955 ARM_RELOC_PAIR, /* the second relocation entry of a pair */ 956 ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ 957 ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol referenced was local. */ 958 ARM_RELOC_PB_LA_PTR, /* prebound lazy pointer */ 959 ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ 960 ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word address) */ 961 }; 962 963 enum reloc_type_ppc 964 { 965 PPC_RELOC_VANILLA, /* generic relocation as discribed above */ 966 PPC_RELOC_PAIR, /* the second relocation entry of a pair */ 967 PPC_RELOC_BR14, /* 14 bit branch displacement (to a word address) */ 968 PPC_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ 969 PPC_RELOC_HI16, /* a PAIR follows with the low half */ 970 PPC_RELOC_LO16, /* a PAIR follows with the high half */ 971 PPC_RELOC_HA16, /* Same as the RELOC_HI16 except the low 16 bits and the 972 * high 16 bits are added together with the low 16 bits 973 * sign extened first. This means if bit 15 of the low 974 * 16 bits is set the high 16 bits stored in the 975 * instruction will be adjusted. 976 */ 977 PPC_RELOC_LO14, /* Same as the LO16 except that the low 2 bits are not 978 * stored in the instruction and are always zero. This 979 * is used in double word load/store instructions. 980 */ 981 PPC_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ 982 PPC_RELOC_PB_LA_PTR, /* prebound lazy pointer */ 983 PPC_RELOC_HI16_SECTDIFF, /* section difference forms of above. a PAIR */ 984 PPC_RELOC_LO16_SECTDIFF, /* follows these with subtract symbol value */ 985 PPC_RELOC_HA16_SECTDIFF, 986 PPC_RELOC_JBSR, 987 PPC_RELOC_LO14_SECTDIFF, 988 PPC_RELOC_LOCAL_SECTDIFF /* like PPC_RELOC_SECTDIFF, but the symbol 989 referenced was local. */ 990 }; 991 992 /* 993 * The following are used to encode rebasing information 994 */ 995 const quint32 S_REBASE_TYPE_POINTER =1; 996 const quint32 S_REBASE_TYPE_TEXT_ABSOLUTE32 =2; 997 const quint32 S_REBASE_TYPE_TEXT_PCREL32 =3; 998 999 const quint32 S_REBASE_OPCODE_MASK =0xF0; 1000 const quint32 S_REBASE_IMMEDIATE_MASK =0x0F; 1001 const quint32 S_REBASE_OPCODE_DONE =0x00; 1002 const quint32 S_REBASE_OPCODE_SET_TYPE_IMM =0x10; 1003 const quint32 S_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB =0x20; 1004 const quint32 S_REBASE_OPCODE_ADD_ADDR_ULEB =0x30; 1005 const quint32 S_REBASE_OPCODE_ADD_ADDR_IMM_SCALED =0x40; 1006 const quint32 S_REBASE_OPCODE_DO_REBASE_IMM_TIMES =0x50; 1007 const quint32 S_REBASE_OPCODE_DO_REBASE_ULEB_TIMES =0x60; 1008 const quint32 S_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB =0x70; 1009 const quint32 S_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB =0x80; 1010 /* 1011 * The following are used to encode binding information 1012 */ 1013 const quint32 S_BIND_TYPE_POINTER =1; 1014 const quint32 S_BIND_TYPE_TEXT_ABSOLUTE32 =2; 1015 const quint32 S_BIND_TYPE_TEXT_PCREL32 =3; 1016 1017 const quint32 S_BIND_SPECIAL_DYLIB_SELF =0; 1018 const quint32 S_BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE =-1; 1019 const quint32 S_BIND_SPECIAL_DYLIB_FLAT_LOOKUP =-2; 1020 const quint32 S_BIND_SPECIAL_DYLIB_WEAK_LOOKUP =-3; 1021 1022 const quint32 S_BIND_SYMBOL_FLAGS_WEAK_IMPORT =0x1; 1023 const quint32 S_BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION =0x8; 1024 1025 const quint32 S_BIND_OPCODE_MASK =0xF0; 1026 const quint32 S_BIND_IMMEDIATE_MASK =0x0F; 1027 const quint32 S_BIND_OPCODE_DONE =0x00; 1028 const quint32 S_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM =0x10; 1029 const quint32 S_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB =0x20; 1030 const quint32 S_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM =0x30; 1031 const quint32 S_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM =0x40; 1032 const quint32 S_BIND_OPCODE_SET_TYPE_IMM =0x50; 1033 const quint32 S_BIND_OPCODE_SET_ADDEND_SLEB =0x60; 1034 const quint32 S_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB =0x70; 1035 const quint32 S_BIND_OPCODE_ADD_ADDR_ULEB =0x80; 1036 const quint32 S_BIND_OPCODE_DO_BIND =0x90; 1037 const quint32 S_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB =0xA0; 1038 const quint32 S_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED =0xB0; 1039 const quint32 S_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB =0xC0; 1040 const quint32 S_BIND_OPCODE_THREADED =0xD0; 1041 const quint32 S_BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB =0x00; 1042 const quint32 S_BIND_SUBOPCODE_THREADED_APPLY =0x01; 1043 /* 1044 * The following are used on the flags byte of a terminal node 1045 * in the export information. 1046 */ 1047 const quint32 S_EXPORT_SYMBOL_FLAGS_KIND_MASK =0x03; 1048 const quint32 S_EXPORT_SYMBOL_FLAGS_KIND_REGULAR =0x00; 1049 const quint32 S_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL =0x01; 1050 const quint32 S_EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE =0x02; 1051 const quint32 S_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION =0x04; 1052 const quint32 S_EXPORT_SYMBOL_FLAGS_REEXPORT =0x08; 1053 const quint32 S_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER =0x10; 1054 } 1055 1056 #endif // QMACH_DEF_H 1057