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