1 /*
2  * Copyright 2008-2021 Gentoo Foundation
3  * Distributed under the terms of the GNU General Public License v2
4  */
5 
6 #ifndef _MACHO_H
7 #define	_MACHO_H 1
8 
9 #include <stdint.h>
10 
11 /*
12  * https://nicolascormier.com/documentation/macosx-programming/MachORuntime.pdf
13  * https://web.archive.org/web/20090404123504/http://developer.apple.com/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
14  */
15 
16 #define CPU_ARCH_ABI64  0x01000000      /* 64 bit */
17 typedef int   cpu_type_t;
18 typedef int   cpu_subtype_t;
19 
20 struct mach_header
21 {
22 	uint32_t magic;
23 	cpu_type_t cputype;
24 	cpu_subtype_t cpusubtype;
25 	uint32_t filetype;
26 	uint32_t ncmds;
27 	uint32_t sizeofcmds;
28 	uint32_t flags;
29 };
30 
31 /* magic */
32 #define MH_MAGIC    0xfeedface  /* same endianness */
33 #define MH_CIGAM    0xcefaedfe  /* the other endianness */
34 /* cputype */
35 #define CPU_TYPE_POWERPC            ((cpu_type_t)18)
36 #define CPU_TYPE_I386               ((cpu_type_t)7)
37 #define CPU_TYPE_ARM                ((cpu_type_t)12)
38 /* cpusubtype */
39 #define CPU_SUBTYPE_POWERPC_ALL     ((cpu_subtype_t)0)
40 #define CPU_SUBTYPE_POWERPC_601     ((cpu_subtype_t)1)
41 #define CPU_SUBTYPE_POWERPC_602     ((cpu_subtype_t)2)
42 #define CPU_SUBTYPE_POWERPC_603     ((cpu_subtype_t)3)
43 #define CPU_SUBTYPE_POWERPC_603e    ((cpu_subtype_t)4)
44 #define CPU_SUBTYPE_POWERPC_603ev   ((cpu_subtype_t)5)
45 #define CPU_SUBTYPE_POWERPC_604     ((cpu_subtype_t)6)
46 #define CPU_SUBTYPE_POWERPC_604e    ((cpu_subtype_t)7)
47 #define CPU_SUBTYPE_POWERPC_620     ((cpu_subtype_t)8)
48 #define CPU_SUBTYPE_POWERPC_750     ((cpu_subtype_t)9)
49 #define CPU_SUBTYPE_POWERPC_7400    ((cpu_subtype_t)10)
50 #define CPU_SUBTYPE_POWERPC_7450    ((cpu_subtype_t)11)
51 #define CPU_SUBTYPE_POWERPC_970     ((cpu_subtype_t)100)
52 #define CPU_SUBTYPE_I386_ALL        ((cpu_subtype_t)3)
53 #define CPU_SUBTYPE_486             ((cpu_subtype_t)4)
54 #define CPU_SUBTYPE_586             ((cpu_subtype_t)5)
55 #define CPU_SUBTYPE_PENTIUM_3       ((cpu_subtype_t)8)
56 #define CPU_SUBTYPE_PENTIUM_M       ((cpu_subtype_t)9)
57 #define CPU_SUBTYPE_PENTIUM_4       ((cpu_subtype_t)10)
58 #define CPU_SUBTYPE_ITANIUM         ((cpu_subtype_t)11)
59 #define CPU_SUBTYPE_XEON            ((cpu_subtype_t)12)
60 /* filetype */
61 #define MH_OBJECT   0x1     /* intermediate object file (.o) */
62 #define MH_EXECUTE  0x2     /* standard executable program */
63 #define MH_BUNDLE   0x8     /* dlopen plugin (.bundle) */
64 #define MH_DYLIB    0x6     /* dynamic shared library (.dylib) */
65 #define MH_PRELOAD  0x5     /* executable not loaded by Mac OS X kernel (ROM) */
66 #define MH_CORE     0x4     /* program crash core file */
67 #define MH_DYLINKER 0x7     /* dynamic linker shared library (dyld) */
68 #define	MH_DYLIB_STUB 0x9   /* shared library stub for static only, no section*/
69 #define MH_DSYM     0xa     /* debug symbols file (in .dSYM dir) */
70 /* flags */
71 #define MH_NOUNDEFS 0x1     /* there are no undefined references */
72 #define MH_INCRLINK 0x2     /* the object file is the output of an
73 							   incremental link against a base file and
74 							   cannot be link edited again */
75 #define MH_DYLDLINK 0x4     /* the object file is input for the dynamic
76 							   linker and cannot be staticly link edited
77 							   again */
78 #define MH_TWOLEVEL 0x80    /* the image is using two-level namespace
79 							   bindings */
80 #define MH_BINDATLOAD 0x8   /* the dynamic linker should bind the
81 							   undefined references when the file is
82 							   loaded */
83 #define MH_PREBOUND 0x10    /* the file’s undefined references are
84 							   prebound */
85 #define MH_PREBINDABLE 0x800/* the file is not prebound but can have its
86 							   prebinding redone, used only when
87 							   MH_PREBOUND is not set */
88 #define MH_NOFIXPREBINDING 0x400 /* the dynamic linker doesn’t notify
89 									the prebinding agent about this
90 									executable */
91 #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to
92 								  all two-level namespace modules of its
93 								  dependent libraries, used only when
94 								  MH_PREBINDABLE and MH_TWOLEVEL are set
95 								  */
96 #define MH_CANONICAL 0x4000  /* the file has been canonicalized by
97 								unprebinding, clearing prebinding
98 								information from the file */
99 #define MH_SPLIT_SEGS   0x20 /* the file has its read-only and
100 								read-write segments split */
101 #define MH_FORCE_FLAT  0x100 /* the executable is forcing all images to
102 								use flat namespace bindings */
103 #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* the sections of the object
104 											file can be divided into
105 											individual blocks, these
106 											blocks are dead-stripped if
107 											they are not used by other
108 											code */
109 #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees there are no
110 								multiple defintions of symbols in its
111 								subimages, as a result the two-level
112 								namespace hints can always be used */
113 
114 struct mach_header_64
115 {
116 	uint32_t magic;
117 	cpu_type_t cputype;
118 	cpu_subtype_t cpusubtype;
119 	uint32_t filetype;
120 	uint32_t ncmds;
121 	uint32_t sizeofcmds;
122 	uint32_t flags;
123 	uint32_t reserved;
124 };
125 
126 /* magic */
127 #define MH_MAGIC_64 0xfeedfacf /* same endianness 64-bits */
128 #define MH_CIGAM_64 0xcffaedfe /* the other endianness 64-bits */
129 /* cputype */
130 #define CPU_TYPE_POWERPC64  (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
131 #define CPU_TYPE_X86_64     (CPU_TYPE_I386 | CPU_ARCH_ABI64)
132 #define CPU_TYPE_ARM64      (CPU_TYPE_ARM | CPU_ARCH_ABI64)
133 
134 struct load_command
135 {
136 	uint32_t cmd;
137 	uint32_t cmdsize;
138 };
139 
140 /* features that are required to be supported are flagged, this is to
141  * make the constants below a bit more readable (although we only use it
142  * once for now) */
143 #define LC_REQ_DYLD 0x80000000
144 
145 /* cmd */
146 #define LC_UUID     0x1b    /* Specifies the 128-bit UUID for an image
147 							   or its corresponding dSYM file. */
148 #define LC_RPATH   (0x1c | LC_REQ_DYLD) /* Defines a runpath addition,
149                                used in @rpath directives in LC_LOAD_DYLIB. */
150 #define LC_SEGMENT  0x1     /* Defines a segment of this file to be
151 							   mapped into the address space of the
152 							   process that loads this file. It also
153 							   includes all the sections contained by
154 							   the segment. */
155 #define LC_SEGMENT_64  0x19 /* Defines a 64-bit segment of this file to
156 							   be mapped into the address space of the
157 							   process that loads this file. It also
158 							   includes all the sections contained by
159 							   the segment. */
160 #define LC_SYMTAB   0x2     /* Specifies the symbol table for this file.
161 							   This information is used by both static
162 							   and dynamic linkers when linking the
163 							   file, and also by debuggers to map
164 							   symbols to the original source code files
165 							   from which the symbols were generated. */
166 #define LC_DYSYMTAB 0xb     /* Specifies additional symbol table
167 							   information used by the dynamic linker. */
168 #define LC_THREAD   0x4
169 #define LC_UNIXTHREAD  0x5  /* For an executable file, the LC_UNIXTHREAD
170 							   command defines the initial thread state
171 							   of the main thread of the process.
172 							   LC_THREAD is similar to LC_UNIXTHREAD but
173 							   does not cause the kernel to allocate a
174 							   stack. */
175 #define LC_LOAD_DYLIB   0xc /* Defines the name of a dynamic shared
176 							   library that this file links against.
177 							   (needed) */
178 #define LC_ID_DYLIB 0xd     /* Specifies the install name of a dynamic
179 							   shared library. (soname) */
180 #define LC_PREBOUND_DYLIB 0x10 /* For a shared library that this
181 								  executable is linked prebound against,
182 								  specifies the modules in the shared
183 								  library that are used. */
184 #define LC_LOAD_DYLINKER 0xe/* Specifies the dynamic linker that the
185 							   kernel executes to load this file. (.interp) */
186 #define LC_ID_DYLINKER  0xf /* Identifies this file as a dynamic linker. */
187 #define LC_ROUTINES 0x11    /* Contains the address of the shared
188 							   library initialization routine (specified
189 							   by the linker’s -init option). */
190 #define LC_ROUTINES_64 0x1a /* Contains the address of the shared
191 							   library 64-bit initialization routine
192 							   (specified by the linker’s -init option). */
193 #define LC_TWOLEVEL_HINTS 0x16 /* Contains the two-level namespace
194 								  lookup hint table. */
195 #define LC_SUB_FRAMEWORK 0x12/* Identifies this file as the
196 								implementation of a subframework of an
197 								umbrella framework. The name of the
198 								umbrella framework is stored in the
199 								string parameter. */
200 #define LC_SUB_UMBRELLA 0x13/* Specifies a file that is a subumbrella of
201 							   this umbrella framework. */
202 #define LC_SUB_LIBRARY  0x15/* Identifies this file as the
203 							   implementation of a sublibrary of an
204 							   umbrella framework. The name of the
205 							   umbrella framework is stored in the
206 							   string parameter. Note that Apple has not
207 							   defined a supported location for
208 							   sublibraries. */
209 #define LC_SUB_CLIENT   0x14/* A subframework can explicitly allow
210 							   another framework or bundle to link
211 							   against it by including an LC_SUB_CLIENT
212 							   load command containing the name of the
213 							   framework or a client name for a bundle. */
214 
215 union lc_str
216 {
217 	uint32_t offset;
218 	/* The ptr field is not used in Mach-O files.
219 	char *ptr; */
220 };
221 /* offset: A byte offset from the start of the load command that
222  * contains this string to the start of the string data.
223  */
224 
225 /*
226 Defines the data used by the dynamic linker to match a shared library against the files that have linked to it.
227 */
228 struct dylib
229 {
230 	union lc_str  name;
231 	uint32_t timestamp;
232 	uint32_t current_version;
233 	uint32_t compatibility_version;
234 };
235 
236 /*
237 Defines the attributes of the LC_LOAD_DYLIB and LC_ID_DYLIB load commands.
238 */
239 struct dylib_command
240 {
241 	uint32_t cmd;
242 	uint32_t cmdsize;
243 	struct dylib dylib;
244 };
245 
246 /* cmd: set to either LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or LC_ID_DYLIB. */
247 /* cmdsize: set to sizeof(dylib_command) plus the size of the data
248  * pointed to by the name field of the dylib field. */
249 
250 struct dylinker_command {
251 	uint32_t cmd;
252 	uint32_t cmdsize;
253 	union lc_str name;
254 };
255 
256 struct rpath_command {
257     uint32_t cmd;
258     uint32_t cmdsize;
259     union lc_str path;
260 };
261 
262 struct uuid_command {
263     uint32_t cmd;
264     uint32_t cmdsize;
265     uint8_t uuid[16];
266 };
267 
268 struct fat_header
269 {
270 	uint32_t magic;
271 	uint32_t nfat_arch;
272 };
273 
274 /* magic */
275 #define FAT_MAGIC   0xcafebabe  /* big endian, how it is stored */
276 #define FAT_CIGAM   0xbebafeca  /* for intel dudes */
277 /* nfat_arch: the number of far_arch structures following */
278 
279 struct fat_arch
280 {
281 	cpu_type_t cputype;
282 	cpu_subtype_t cpusubtype;
283 	uint32_t offset;
284 	uint32_t size;
285 	uint32_t align;
286 };
287 
288 #endif
289