Upx_Doxygen
https://github.com/upx/upx
p_mach.h
1 /* p_mach.h --
2 
3  This file is part of the UPX executable compressor.
4 
5  Copyright (C) 1996-2016 Markus Franz Xaver Johannes Oberhumer
6  Copyright (C) 1996-2016 Laszlo Molnar
7  All Rights Reserved.
8 
9  UPX and the UCL library are free software; you can redistribute them
10  and/or modify them under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of
12  the License, or (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; see the file COPYING.
21  If not, write to the Free Software Foundation, Inc.,
22  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24  Markus F.X.J. Oberhumer Laszlo Molnar
25  <markus@oberhumer.com> <ezerotven+github@gmail.com>
26  */
27 
28 
29 #ifndef __UPX_P_MACHO_H
30 #define __UPX_P_MACHO_H 1
31 
32 
33 __packed_struct(Mach_fat_header)
34  BE32 magic;
35  enum { // note conflict with java bytecode PackLinuxI386
36  FAT_MAGIC = 0xcafebabe,
37  FAT_MAGIC_SWAB = 0xbebafeca
38  };
39  BE32 nfat_arch; // Number of Mach_fat_arch which follow.
40 __packed_struct_end()
41 
42 __packed_struct(Mach_fat_arch)
43  BE32 cputype;
44  BE32 cpusubtype;
45  BE32 offset;
46  BE32 size;
47  BE32 align; /* shift count; log base 2 */
48 __packed_struct_end()
49 
50 /*************************************************************************
51 // Mach Mach Object executable; all structures are target-endian
52 // 'otool' is the Mach analog of 'readelf' (convert executable file to ASCII).
53 **************************************************************************/
54 
55 namespace N_Mach {
56 
57 // integral types
58 template <class TWord, class TXword, class TAddr, class TOff>
59 struct MachITypes
60 {
61  typedef TWord Word;
62  typedef TXword Xword;
63  typedef TAddr Addr;
64  typedef TOff Off;
65 };
66 
67 template <class TMachITypes>
68 __packed_struct(Mach_header)
69  typedef typename TMachITypes::Word Word;
70 
71  Word magic;
72  Word cputype;
73  Word cpusubtype;
74  Word filetype;
75  Word ncmds;
76  Word sizeofcmds;
77  Word flags;
78 #define WANT_MACH_HEADER_ENUM 1
79 #include "p_mach_enum.h"
80 __packed_struct_end()
81 
82 template <class TMachITypes>
83 __packed_struct(Mach_header64)
84  // only difference is padding to 0 mod 8
85  typedef typename TMachITypes::Word Word;
86 
87  Word magic;
88  Word cputype;
89  Word cpusubtype;
90  Word filetype;
91  Word ncmds;
92  Word sizeofcmds;
93  Word flags;
94  Word reserved; // pad to 0 mod 8
95 #define WANT_MACH_HEADER_ENUM 1
96 #include "p_mach_enum.h"
97 __packed_struct_end()
98 
99 template <class TMachITypes>
100 __packed_struct(Mach_command) // generic prefix
101  typedef typename TMachITypes::Word Word;
102 
103  Word cmd;
104  Word cmdsize;
105  Word data[2]; // because cmdsize >= 16
106 #define WANT_MACH_SEGMENT_ENUM 1
107 #include "p_mach_enum.h"
108 __packed_struct_end();
109 
110 template <class TMachITypes>
111 __packed_struct(Mach_segment_command)
112  typedef typename TMachITypes::Word Word;
113  typedef typename TMachITypes::Addr Addr;
114  typedef typename TMachITypes::Off Off;
115 
116  Word cmd;
117  Word cmdsize;
118  char segname[16];
119  Addr vmaddr;
120  Addr vmsize;
121  Off fileoff;
122  Off filesize;
123  Word maxprot;
124  Word initprot;
125  Word nsects;
126  Word flags;
127 #define WANT_MACH_SEGMENT_ENUM 1
128 #include "p_mach_enum.h"
129 __packed_struct_end()
130 
131 template <class TMachITypes>
132 __packed_struct(Mach_section_command)
133  typedef typename TMachITypes::Word Word;
134  typedef typename TMachITypes::Addr Addr;
135  typedef typename TMachITypes::Off Off;
136 
137  char sectname[16];
138  char segname[16];
139  Addr addr; /* memory address */
140  Addr size; /* size in bytes */
141  Word offset; /* file offset */
142  Word align; /* power of 2 */
143  Word reloff; /* file offset of relocation entries */
144  Word nreloc; /* number of relocation entries */
145  Word flags; /* section type and attributes */
146  Word reserved1; /* for offset or index */
147  Word reserved2; /* for count or sizeof */
148 #define WANT_MACH_SECTION_ENUM 1
149 #include "p_mach_enum.h"
150 __packed_struct_end()
151 
152 template <class TMachITypes>
153 __packed_struct(Mach_section_command_64)
154  typedef typename TMachITypes::Word Word;
155  typedef typename TMachITypes::Addr Addr;
156  typedef typename TMachITypes::Off Off;
157  typedef typename TMachITypes::Word Off32;
158  typedef typename TMachITypes::Xword Xword;
159 
160  char sectname[16];
161  char segname[16];
162  Addr addr; /* memory address */
163  Addr size; /* size in bytes */
164  Off32 offset; /* file offset */
165  Word align; /* power of 2 */
166  Word reloff; /* file offset of relocation entries */
167  Word nreloc; /* number of relocation entries */
168  Word flags; /* section type and attributes */
169  Word reserved1; /* for offset or index */
170  Word reserved2; /* for count or sizeof */
171  Word reserved3; /* NOT IN 32-bit VERSION!! */
172 #define WANT_MACH_SECTION_ENUM 1
173 #include "p_mach_enum.h"
174 __packed_struct_end()
175 
176 template <class TMachITypes>
177 __packed_struct(Mach_symtab_command)
178  typedef typename TMachITypes::Word Word;
179  typedef typename TMachITypes::Off Off;
180  typedef typename TMachITypes::Word Off32;
181 
182  Word cmd; /* LC_SYMTAB */
183  Word cmdsize; /* sizeof(struct Mach_symtab_command) */
184  Off32 symoff; /* symbol table offset */
185  Word nsyms; /* number of symbol table entries */
186  Off32 stroff; /* string table offset */
187  Word strsize; /* string table size in bytes */
188 __packed_struct_end()
189 
190 template <class TMachITypes>
191 __packed_struct(Mach_dysymtab_command)
192  typedef typename TMachITypes::Word Word;
193  typedef typename TMachITypes::Off Off;
194  typedef typename TMachITypes::Word Off32;
195 
196  Word cmd; /* LC_DYSYMTAB */
197  Word cmdsize; /* sizeof(struct Mach_dysymtab_command) */
198  Word ilocalsym; /* index to local symbols */
199  Word nlocalsym; /* number of local symbols */
200  Word iextdefsym; /* index to externally defined symbols */
201  Word nextdefsym; /* number of externally defined symbols */
202  Word iundefsym; /* index to undefined symbols */
203  Word nundefsym; /* number of undefined symbols */
204  Off32 tocoff; /* file offset to table of contents */
205  Word ntoc; /* number of entries in table of contents */
206  Off32 modtaboff; /* file offset to module table */
207  Word nmodtab; /* number of module table entries */
208  Off32 extrefsymoff; /* offset to referenced symbol table */
209  Word nextrefsymoff; /* number of referenced symbol table entries */
210  Off32 indirectsymoff; /* file offset to the indirect symbol table */
211  Word nindirectsyms; /* number of indirect symbol table entries */
212  Off32 extreloff; /* offset to external relocation entries */
213  Word nextrel; /* number of external relocation entries */
214  Off32 locreloff; /* offset to local relocation entries */
215  Word nlocrel; /* number of local relocation entries */
216 __packed_struct_end()
217 
218 template <class TMachITypes>
219 __packed_struct(Mach_segsplit_info_command)
220  typedef typename TMachITypes::Word Word;
221  typedef typename TMachITypes::Off Off;
222 
223  Word cmd; /* LC_SEGMENT_SPLIT_INFO */
224  Word cmdsize; /* sizeof(struct Mach_segsplit_info_command) */
225  Off dataoff;
226  Word datasize;
227 __packed_struct_end()
228 
229 template <class TMachITypes>
230 __packed_struct(Mach_routines_command)
231  typedef typename TMachITypes::Word Word;
232  typedef typename TMachITypes::Addr Addr;
233 
234  Word cmd;
235  Word cmdsize;
236  Addr init_address;
237  Word init_module;
238  Word reserved1;
239  Word reserved2;
240  Word reserved3;
241  Word reserved4;
242  Word reserved5;
243  Word reserved6;
244 #define WANT_MACH_SEGMENT_ENUM 1
245 #include "p_mach_enum.h"
246 __packed_struct_end()
247 
248 template <class TMachITypes>
249 __packed_struct(Mach_routines_command_64)
250  typedef typename TMachITypes::Word Word;
251  typedef typename TMachITypes::Addr Addr;
252  typedef typename TMachITypes::Xword Xword;
253 
254  Word cmd;
255  Word cmdsize;
256  Addr init_address;
257  Xword init_module;
258  Xword reserved1;
259  Xword reserved2;
260  Xword reserved3;
261  Xword reserved4;
262  Xword reserved5;
263  Xword reserved6;
264 #define WANT_MACH_SEGMENT_ENUM 1
265 #include "p_mach_enum.h"
266 __packed_struct_end()
267 
268 template <class TMachITypes>
269 __packed_struct(Mach_twolevel_hints_command)
270  typedef typename TMachITypes::Word Word;
271  typedef typename TMachITypes::Off Off;
272 
273  Word cmd;
274  Word cmdsize;
275  Off offset; /* offset to the hint table */
276  Word nhints; /* number of hints */
277 #define WANT_MACH_SEGMENT_ENUM 1
278 #include "p_mach_enum.h"
279 __packed_struct_end()
280 
281 template <class TMachITypes>
282 __packed_struct(Mach_linkedit_data_command)
283  typedef typename TMachITypes::Word Word;
284 
285  Word cmd;
286  Word cmdsize;
287  Word dataoff; // file offset of data in __LINKEDIT segment
288  Word datasize; // file size of data in __LINKEDIT segment
289 __packed_struct_end()
290 
291 template <class TMachITypes>
292 __packed_struct(Mach_uuid_command)
293  typedef typename TMachITypes::Word Word;
294 
295  Word cmd; // LC_UUID
296  Word cmdsize; // 24
297  unsigned char uuid[16];
298 __packed_struct_end()
299 
300 template <class TMachITypes, class TMachThreadState>
301 __packed_struct(Mach_thread_command)
302  typedef typename TMachITypes::Word Word;
303 
304  Word cmd; /* LC_THREAD or LC_UNIXTHREAD */
305  Word cmdsize; /* total size of this command */
306  Word flavor;
307  Word count; /* sizeof(following_thread_state)/4 */
308  TMachThreadState state;
309 #define WANT_MACH_THREAD_ENUM 1
310 #include "p_mach_enum.h"
311 __packed_struct_end()
312 
313 template <class TMachITypes>
314 __packed_struct(Mach_main_command)
315  typedef typename TMachITypes::Word Word;
316  typedef typename TMachITypes::Xword Xword;
317 
318  Word cmd; // LC_MAIN; MH_EXECUTE only
319  Word cmdsize; // 24
320  Xword entryoff; // file offset of main() [expected in __TEXT]
321  Xword stacksize; // non-default initial stack size
322 __packed_struct_end()
323 
324 template <class TMachITypes>
325 __packed_struct(Mach_source_version_command)
326  typedef typename TMachITypes::Word Word;
327 
328  Word cmd; // LC_SOURCE_VERSION
329  Word cmdsize; // 16
330  Word version;
331 __packed_struct_end()
332 
333 template <class TMachITypes>
334 __packed_struct(Mach_version_min_command)
335  typedef typename TMachITypes::Word Word;
336 
337  Word cmd; // LC_VERSION_MIN_MACOSX
338  Word cmdsize; // 16
339  Word version; // X.Y.Z ==> xxxx.yy.zz
340  Word sdk; // X.Y.Z ==> xxxx.yy.zz
341 __packed_struct_end()
342 
343 template <class TMachITypes>
344 __packed_struct(Mach_dyld_info_only_command)
345  typedef typename TMachITypes::Word Word;
346 
347  Word cmd; // LC_DYLD_INFO_ONLY
348  Word cmdsize; // 48
349  Word rebase_off;
350  Word rebase_size;
351  Word bind_off;
352  Word bind_size;
353  Word weak_bind_off;
354  Word weak_bind_size;
355  Word lazy_bind_off;
356  Word lazy_bind_size;
357  Word export_off;
358  Word export_size;
359 __packed_struct_end()
360 
361 template <class TMachITypes>
362 __packed_struct(Mach_load_dylinker_command)
363  typedef typename TMachITypes::Word Word;
364 
365  Word cmd;
366  Word cmdsize;
367  Word name;
368 __packed_struct_end()
369 
370 template <class TMachITypes>
371 __packed_struct(Mach_dylib)
372  typedef typename TMachITypes::Word Word;
373 
374  Word name; /* library's path name */
375  Word timestamp; /* library's build time stamp */
376  Word current_version; /* library's current version number */
377  Word compatibility_version; /* library's compatibility vers number*/
378 __packed_struct_end()
379 
380 template <class TMachITypes>
381 __packed_struct(Mach_load_dylib_command)
382  typedef typename TMachITypes::Word Word;
383 
384  Word cmd;
385  Word cmdsize;
386  Mach_dylib<TMachITypes> dylib;
387 __packed_struct_end()
388 
389 template <class TMachITypes>
390 __packed_struct(Mach_function_starts_command)
391  typedef typename TMachITypes::Word Word;
392 
393  Word cmd;
394  Word cmdsize;
395  Word dataoff;
396  Word datasize;
397 __packed_struct_end()
398 
399 template <class TMachITypes>
400 __packed_struct(Mach_data_in_code_command)
401  typedef typename TMachITypes::Word Word;
402 
403  Word cmd;
404  Word cmdsize;
405  Word dataoff;
406  Word datasize;
407 __packed_struct_end()
408 
409 } // namespace N_Mach
410 
411 namespace N_Mach32 {
412 
413 template <class TMachITypes>
414 __packed_struct(Mach_ppc_thread_state)
415  typedef typename TMachITypes::Addr Addr;
416 
417  Addr srr0; /* Instruction address register (PC; entry addr) */
418  Addr srr1; /* Machine state register (supervisor) */
419  Addr r0, r1, r2, r3, r4, r5, r6, r7;
420  Addr r8, r9,r10,r11,r12,r13,r14,r15;
421  Addr r16,r17,r18,r19,r20,r21,r22,r23;
422  Addr r24,r25,r26,r27,r28,r29,r30,r31;
423 
424  Addr cr; /* Condition register */ // FIXME: Word?
425  Addr xer; /* User's integer exception register */
426  Addr lr; /* Link register */
427  Addr ctr; /* Count register */
428  Addr mq; /* MQ register (601 only) */
429 
430  Addr vrsave; /* Vector Save Register */
431 __packed_struct_end()
432 
433 template <class TMachITypes>
434 __packed_struct(Mach_i386_thread_state)
435  typedef typename TMachITypes::Word Word;
436 
437  Word eax, ebx, ecx, edx;
438  Word edi, esi, ebp;
439  Word esp, ss;
440  Word eflags;
441  Word eip, cs;
442  Word ds, es, fs, gs;
443 __packed_struct_end()
444 
445 template <class TMachITypes>
446 __packed_struct(Mach_ARM_thread_state)
447  typedef typename TMachITypes::Word Word;
448 
449  Word r[13]; // r0-r12
450  Word sp; // r13
451  Word lr; // r14
452  Word pc; // r15
453  Word cpsr;
454 __packed_struct_end()
455 
456 } // namespace N_Mach32
457 
458 namespace N_Mach64 {
459 
460 template <class TMachITypes>
461 __packed_struct(Mach_AMD64_thread_state)
462  typedef typename TMachITypes::Xword Xword;
463 
464  Xword rax, rbx, rcx, rdx;
465  Xword rdi, rsi, rbp, rsp;
466  Xword r8, r9, r10, r11;
467  Xword r12, r13, r14, r15;
468  Xword rip, rflags;
469  Xword cs, fs, gs;
470 __packed_struct_end()
471 
472 template <class TMachITypes>
473 __packed_struct(Mach_ppc_thread_state64)
474  typedef typename TMachITypes::Word Word;
475  typedef typename TMachITypes::Xword Xword;
476 
477  Xword srr0; /* Instruction address register (PC; entry addr) */
478  Xword srr1; /* Machine state register (supervisor) */
479  Xword r0, r1, r2, r3, r4, r5, r6, r7;
480  Xword r8, r9,r10,r11,r12,r13,r14,r15;
481  Xword r16,r17,r18,r19,r20,r21,r22,r23;
482  Xword r24,r25,r26,r27,r28,r29,r30,r31;
483 
484  Word cr; /* Condition register */ // FIXME: Xword?
485  Xword xer; /* User's integer exception register */
486  Xword lr; /* Link register */
487  Xword ctr; /* Count register */
488 
489  Word vrsave; /* Vector Save Register */
490 __packed_struct_end()
491 
492 template <class TMachITypes>
493 __packed_struct(Mach_ppcle_thread_state64)
494  typedef typename TMachITypes::Word Word;
495  typedef typename TMachITypes::Xword Xword;
496 
497  Xword srr0; /* Instruction address register (PC; entry addr) */
498  Xword srr1; /* Machine state register (supervisor) */
499  Xword r0, r1, r2, r3, r4, r5, r6, r7;
500  Xword r8, r9,r10,r11,r12,r13,r14,r15;
501  Xword r16,r17,r18,r19,r20,r21,r22,r23;
502  Xword r24,r25,r26,r27,r28,r29,r30,r31;
503 
504  Word cr; /* Condition register */ // FIXME: Xword?
505  Xword xer; /* User's integer exception register */
506  Xword lr; /* Link register */
507  Xword ctr; /* Count register */
508 
509  Word vrsave; /* Vector Save Register */
510 __packed_struct_end()
511 
512 template <class TMachITypes> __packed_struct(Mach_ARM64_thread_state)
513  typedef typename TMachITypes::Xword Xword;
514  typedef typename TMachITypes::Word Word;
515 
516  Xword x0, x1, x2, x3;
517  Xword x4, x5, x6, x7;
518  Xword x8, x9, x10, x11;
519  Xword x12, x13, x14, x15;
520  Xword x16, x17, x18, x19;
521  Xword x20, x21, x22, x23;
522  Xword x24, x25, x26, x27;
523  Xword x28, fp, lr, sp;
524  Xword pc;
525  Word cpsr;
526 __packed_struct_end()
527 
528 } // namespace N_Mach64
529 
530 namespace N_Mach {
531 
532 template <class TP>
534 {
535  typedef TP BeLePolicy;
536 
537  // integral types (target endianness)
538  typedef typename TP::U16 TE16;
539  typedef typename TP::U32 TE32;
540  typedef typename TP::U64 TE64;
541  typedef N_Mach::MachITypes<TE32, TE64, TE32, TE32> MachITypes;
542  typedef typename MachITypes::Addr Addr;
543 
544  // Mach types
545  typedef N_Mach::Mach_header<MachITypes> Mach_header;
546  typedef N_Mach::Mach_command<MachITypes> Mach_command;
547  typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
548  typedef N_Mach::Mach_section_command<MachITypes> Mach_section_command;
549  typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
550  typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
551  typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
552  typedef N_Mach::Mach_routines_command<MachITypes> Mach_routines_command;
553  typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
554  typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
555  typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
556  typedef N_Mach::Mach_data_in_code_command<MachITypes> Mach_data_in_code_command;
557  typedef N_Mach::Mach_function_starts_command<MachITypes> Mach_function_starts_command;
558  typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
559  typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
560  typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
561  typedef N_Mach::Mach_dyld_info_only_command<MachITypes> Mach_dyld_info_only_command;
562  typedef N_Mach::Mach_version_min_command<MachITypes> Mach_version_min_command;
563  typedef N_Mach::Mach_source_version_command<MachITypes> Mach_source_version_command;
564  typedef N_Mach::Mach_main_command<MachITypes> Mach_main_command;
565 
566  typedef N_Mach32::Mach_ppc_thread_state<MachITypes> Mach_ppc_thread_state;
567  typedef N_Mach32::Mach_i386_thread_state<MachITypes> Mach_i386_thread_state;
568  typedef N_Mach32::Mach_ARM_thread_state<MachITypes> Mach_ARM_thread_state;
569 
570  static void compileTimeAssertions() {
571  BeLePolicy::compileTimeAssertions();
572  COMPILE_TIME_ASSERT(sizeof(Addr) == 4)
573  }
574 };
575 
576 template <class TP>
578 {
579  typedef TP BeLePolicy;
580 
581  // integral types (target endianness)
582  typedef typename TP::U16 TE16;
583  typedef typename TP::U32 TE32;
584  typedef typename TP::U64 TE64;
585  typedef N_Mach::MachITypes<TE32, TE64, TE64, TE64> MachITypes;
586  typedef typename MachITypes::Addr Addr;
587 
588  // Mach types
589  typedef N_Mach::Mach_header64<MachITypes> Mach_header;
590  typedef N_Mach::Mach_command<MachITypes> Mach_command;
591  typedef N_Mach::Mach_segment_command<MachITypes> Mach_segment_command;
592  typedef N_Mach::Mach_section_command_64<MachITypes> Mach_section_command;
593  typedef N_Mach::Mach_symtab_command<MachITypes> Mach_symtab_command;
594  typedef N_Mach::Mach_dysymtab_command<MachITypes> Mach_dysymtab_command;
595  typedef N_Mach::Mach_segsplit_info_command<MachITypes> Mach_segsplit_info_command;
596  typedef N_Mach::Mach_routines_command_64<MachITypes> Mach_routines_command;
597  typedef N_Mach::Mach_twolevel_hints_command<MachITypes> Mach_twolevel_hints_command;
598  typedef N_Mach::Mach_linkedit_data_command<MachITypes> Mach_linkedit_data_command;
599  typedef N_Mach::Mach_uuid_command<MachITypes> Mach_uuid_command;
600  typedef N_Mach::Mach_data_in_code_command<MachITypes> Mach_data_in_code_command;
601  typedef N_Mach::Mach_function_starts_command<MachITypes> Mach_function_starts_command;
602  typedef N_Mach::Mach_load_dylib_command<MachITypes> Mach_load_dylib_command;
603  typedef N_Mach::Mach_dylib<MachITypes> Mach_dylib;
604  typedef N_Mach::Mach_load_dylinker_command<MachITypes> Mach_load_dylinker_command;
605  typedef N_Mach::Mach_dyld_info_only_command<MachITypes> Mach_dyld_info_only_command;
606  typedef N_Mach::Mach_version_min_command<MachITypes> Mach_version_min_command;
607  typedef N_Mach::Mach_source_version_command<MachITypes> Mach_source_version_command;
608  typedef N_Mach::Mach_main_command<MachITypes> Mach_main_command;
609 
610  typedef N_Mach64::Mach_ppcle_thread_state64<MachITypes> Mach_ppcle_thread_state64;
611  typedef N_Mach64::Mach_AMD64_thread_state<MachITypes> Mach_AMD64_thread_state;
612  typedef N_Mach64::Mach_ARM64_thread_state<MachITypes> Mach_ARM64_thread_state;
613 
614  static void compileTimeAssertions() {
615  BeLePolicy::compileTimeAssertions();
616  COMPILE_TIME_ASSERT(sizeof(Addr) == 8)
617  }
618 };
619 
620 } // namespace N_Mach
621 
628 
629 // shortcuts
630 typedef MachClass_Host32::Mach_segment_command Mach32_segment_command;
631 typedef MachClass_Host32::Mach_section_command Mach32_section_command;
632 typedef MachClass_Host32::Mach_symtab_command Mach32_symtab_command;
633 typedef MachClass_Host32::Mach_dysymtab_command Mach32_dysymtab_command;
634 typedef MachClass_Host32::Mach_segsplit_info_command Mach32_segsplit_info_command;
635 typedef MachClass_Host32::Mach_routines_command Mach32_routines_command;
636 typedef MachClass_Host32::Mach_twolevel_hints_command Mach32_twolevel_hints_command;
637 typedef MachClass_Host32::Mach_linkedit_data_command Mach32_linkedit_data_command;
638 typedef MachClass_Host32::Mach_uuid_command Mach32_uuid_command;
639 typedef MachClass_Host32::Mach_main_command Mach32_main_command;
640 typedef MachClass_Host32::Mach_data_in_code_command Mach32_data_in_code_command;
641 typedef MachClass_Host32::Mach_function_starts_command Mach32_function_starts_command;
642 typedef MachClass_Host32::Mach_load_dylib_command Mach32_load_dylib_command;
643 typedef MachClass_Host32::Mach_dylib Mach32_dylib;
644 typedef MachClass_Host32::Mach_load_dylinker_command Mach32_load_dylinker_command;
645 typedef MachClass_Host32::Mach_dyld_info_only_command Mach32_dyld_info_only_command;
646 typedef MachClass_Host32::Mach_version_min_command Mach32_version_min_command;
647 typedef MachClass_Host32::Mach_source_version_command Mach32_source_version_command;
648 
649 typedef MachClass_Host64::Mach_segment_command Mach64_segment_command;
650 typedef MachClass_Host64::Mach_section_command Mach64_section_command;
651 typedef MachClass_Host64::Mach_symtab_command Mach64_symtab_command;
652 typedef MachClass_Host64::Mach_dysymtab_command Mach64_dysymtab_command;
653 typedef MachClass_Host64::Mach_segsplit_info_command Mach64_segsplit_info_command;
654 typedef MachClass_Host64::Mach_routines_command Mach64_routines_command;
655 typedef MachClass_Host64::Mach_twolevel_hints_command Mach64_twolevel_hints_command;
656 typedef MachClass_Host64::Mach_linkedit_data_command Mach64_linkedit_data_command;
657 typedef MachClass_Host64::Mach_uuid_command Mach64_uuid_command;
658 typedef MachClass_Host64::Mach_main_command Mach64_main_command;
659 typedef MachClass_Host64::Mach_data_in_code_command Mach64_data_in_code_command;
660 typedef MachClass_Host64::Mach_function_starts_command Mach64_function_starts_command;
661 typedef MachClass_Host64::Mach_load_dylib_command Mach64_load_dylib_command;
662 typedef MachClass_Host64::Mach_dylib Mach64_dylib;
663 typedef MachClass_Host64::Mach_load_dylinker_command Mach64_load_dylinker_command;
664 typedef MachClass_Host64::Mach_dyld_info_only_command Mach64_dyld_info_only_command;
665 typedef MachClass_Host64::Mach_version_min_command Mach64_version_min_command;
666 typedef MachClass_Host64::Mach_source_version_command Mach64_source_version_command;
667 
668 typedef MachClass_BE32::Mach_segment_command MachBE32_segment_command;
669 typedef MachClass_BE32::Mach_section_command MachBE32_section_command;
670 typedef MachClass_BE32::Mach_symtab_command MachBE32_symtab_command;
671 typedef MachClass_BE32::Mach_dysymtab_command MachBE32_dysymtab_command;
672 typedef MachClass_BE32::Mach_segsplit_info_command MachBE32_segsplit_info_command;
673 typedef MachClass_BE32::Mach_routines_command MachBE32_routines_command;
674 typedef MachClass_BE32::Mach_twolevel_hints_command MachBE32_twolevel_hints_command;
675 typedef MachClass_BE32::Mach_linkedit_data_command MachBE32_linkedit_data_command;
676 typedef MachClass_BE32::Mach_uuid_command MachBE32_uuid_command;
677 typedef MachClass_BE32::Mach_main_command MachBE32_main_command;
678 typedef MachClass_BE32::Mach_data_in_code_command MachBE32_data_in_code_command;
679 typedef MachClass_BE32::Mach_function_starts_command MachBE32_function_starts_command;
680 typedef MachClass_BE32::Mach_load_dylib_command MachBE32_load_dylib_command;
681 typedef MachClass_BE32::Mach_dylib MachBE32_dylib;
682 typedef MachClass_BE32::Mach_load_dylinker_command MachBE32_load_dylinker_command;
683 typedef MachClass_BE32::Mach_dyld_info_only_command MachBE32_dyld_info_only_command;
684 typedef MachClass_BE32::Mach_version_min_command MachBE32_version_min_command;
685 typedef MachClass_BE32::Mach_source_version_command MachBE32_source_version_command;
686 
687 typedef MachClass_BE64::Mach_segment_command MachBE64_segment_command;
688 typedef MachClass_BE64::Mach_section_command MachBE64_section_command;
689 typedef MachClass_BE64::Mach_symtab_command MachBE64_symtab_command;
690 typedef MachClass_BE64::Mach_dysymtab_command MachBE64_dysymtab_command;
691 typedef MachClass_BE64::Mach_segsplit_info_command MachBE64_segsplit_info_command;
692 typedef MachClass_BE64::Mach_routines_command MachBE64_routines_command;
693 typedef MachClass_BE64::Mach_twolevel_hints_command MachBE64_twolevel_hints_command;
694 typedef MachClass_BE64::Mach_linkedit_data_command MachBE64_linkedit_data_command;
695 typedef MachClass_BE64::Mach_uuid_command MachBE64_uuid_command;
696 typedef MachClass_BE64::Mach_main_command MachBE64_main_command;
697 typedef MachClass_BE64::Mach_data_in_code_command MachBE64_data_in_code_command;
698 typedef MachClass_BE64::Mach_function_starts_command MachBE64_function_starts_command;
699 typedef MachClass_BE64::Mach_load_dylib_command MachBE64_load_dylib_command;
700 typedef MachClass_BE64::Mach_dylib MachBE64_dylib;
701 typedef MachClass_BE64::Mach_load_dylinker_command MachBE64_load_dylinker_command;
702 typedef MachClass_BE64::Mach_dyld_info_only_command MachBE64_dyld_info_only_command;
703 typedef MachClass_BE64::Mach_version_min_command MachBE64_version_min_command;
704 typedef MachClass_BE64::Mach_source_version_command MachBE64_source_version_command;
705 
706 typedef MachClass_LE32::Mach_segment_command MachLE32_segment_command;
707 typedef MachClass_LE32::Mach_section_command MachLE32_section_command;
708 typedef MachClass_LE32::Mach_symtab_command MachLE32_symtab_command;
709 typedef MachClass_LE32::Mach_dysymtab_command MachLE32_dysymtab_command;
710 typedef MachClass_LE32::Mach_segsplit_info_command MachLE32_segsplit_info_command;
711 typedef MachClass_LE32::Mach_routines_command MachLE32_routines_command;
712 typedef MachClass_LE32::Mach_twolevel_hints_command MachLE32_twolevel_hints_command;
713 typedef MachClass_LE32::Mach_linkedit_data_command MachLE32_linkedit_data_command;
714 typedef MachClass_LE32::Mach_uuid_command MachLE32_uuid_command;
715 typedef MachClass_LE32::Mach_main_command MachLE32_main_command;
716 typedef MachClass_LE32::Mach_data_in_code_command MachLE32_data_in_code_command;
717 typedef MachClass_LE32::Mach_function_starts_command MachLE32_function_starts_command;
718 typedef MachClass_LE32::Mach_load_dylib_command MachLE32_load_dylib_command;
719 typedef MachClass_LE32::Mach_dylib MachLE32_dylib;
720 typedef MachClass_LE32::Mach_load_dylinker_command MachLE32_load_dylinker_command;
721 typedef MachClass_LE32::Mach_dyld_info_only_command MachLE32_dyld_info_only_command;
722 typedef MachClass_LE32::Mach_version_min_command MachLE32_version_min_command;
723 typedef MachClass_LE32::Mach_source_version_command MachLE32_source_version_command;
724 
725 typedef MachClass_LE64::Mach_segment_command MachLE64_segment_command;
726 typedef MachClass_LE64::Mach_section_command MachLE64_section_command;
727 typedef MachClass_LE64::Mach_symtab_command MachLE64_symtab_command;
728 typedef MachClass_LE64::Mach_dysymtab_command MachLE64_dysymtab_command;
729 typedef MachClass_LE64::Mach_segsplit_info_command MachLE64_segsplit_info_command;
730 typedef MachClass_LE64::Mach_routines_command MachLE64_routines_command;
731 typedef MachClass_LE64::Mach_twolevel_hints_command MachLE64_twolevel_hints_command;
732 typedef MachClass_LE64::Mach_linkedit_data_command MachLE64_linkedit_data_command;
733 typedef MachClass_LE64::Mach_uuid_command MachLE64_uuid_command;
734 typedef MachClass_LE64::Mach_main_command MachLE64_main_command;
735 typedef MachClass_LE64::Mach_data_in_code_command MachLE64_data_in_code_command;
736 typedef MachClass_LE64::Mach_function_starts_command MachLE64_function_starts_command;
737 typedef MachClass_LE64::Mach_load_dylib_command MachLE64_load_dylib_command;
738 typedef MachClass_LE64::Mach_dylib MachLE64_dylib;
739 typedef MachClass_LE64::Mach_load_dylinker_command MachLE64_load_dylinker_command;
740 typedef MachClass_LE64::Mach_dyld_info_only_command MachLE64_dyld_info_only_command;
741 typedef MachClass_LE64::Mach_version_min_command MachLE64_version_min_command;
742 typedef MachClass_LE64::Mach_source_version_command MachLE64_source_version_command;
743 
744 typedef MachClass_BE32::Mach_ppc_thread_state Mach_ppc_thread_state;
745 typedef MachClass_LE64::Mach_ppcle_thread_state64 Mach_ppcle_thread_state64;
746 typedef MachClass_LE32::Mach_i386_thread_state Mach_i386_thread_state;
747 typedef MachClass_LE64::Mach_AMD64_thread_state Mach_AMD64_thread_state;
748 typedef MachClass_LE64::Mach_ARM64_thread_state Mach_ARM64_thread_state;
749 typedef MachClass_LE32::Mach_ARM_thread_state Mach_ARM_thread_state;
750 #include "p_unix.h"
751 
752 
753 template <class TMachClass>
754 class PackMachBase : public PackUnix
755 {
756  typedef PackUnix super;
757 protected:
758  typedef TMachClass MachClass;
759  typedef typename MachClass::BeLePolicy BeLePolicy;
760  typedef typename MachClass::MachITypes MachITypes;
761  // integral types (target endianness)
762  typedef typename MachClass::TE16 TE16;
763  typedef typename MachClass::TE32 TE32;
764  typedef typename MachClass::TE64 TE64;
765  typedef typename MachClass::Addr Addr;
766  // Mach types
767  typedef typename MachClass::Mach_header Mach_header;
768  typedef typename MachClass::Mach_command Mach_command;
769  typedef typename MachClass::Mach_segment_command Mach_segment_command;
770  typedef typename MachClass::Mach_section_command Mach_section_command;
771  typedef typename MachClass::Mach_symtab_command Mach_symtab_command;
772  typedef typename MachClass::Mach_dysymtab_command Mach_dysymtab_command;
773  typedef typename MachClass::Mach_segsplit_info_command Mach_segsplit_info_command;
774  typedef typename MachClass::Mach_routines_command Mach_routines_command;
775  typedef typename MachClass::Mach_twolevel_hints_command Mach_twolevel_hints_command;
776  typedef typename MachClass::Mach_linkedit_data_command Mach_linkedit_data_command;
777  typedef typename MachClass::Mach_uuid_command Mach_uuid_command;
778  typedef typename MachClass::Mach_main_command Mach_main_command;
779  typedef typename MachClass::Mach_data_in_code_command Mach_data_in_code_command;
780  typedef typename MachClass::Mach_function_starts_command Mach_function_starts_command;
781  typedef typename MachClass::Mach_load_dylib_command Mach_load_dylib_command;
782  typedef typename MachClass::Mach_dylib Mach_dylib;
783  typedef typename MachClass::Mach_load_dylinker_command Mach_load_dylinker_command;
784  typedef typename MachClass::Mach_dyld_info_only_command Mach_dyld_info_only_command;
785  typedef typename MachClass::Mach_version_min_command Mach_version_min_command;
786  typedef typename MachClass::Mach_source_version_command Mach_source_version_command;
787 
788 public:
789  PackMachBase(InputFile *, unsigned cpuid, unsigned filetype,
790  unsigned t_flavor, unsigned ts_word_cnt, unsigned tc_size);
791  virtual ~PackMachBase();
792  virtual int getVersion() const { return 13; }
793  virtual const int *getCompressionMethods(int method, int level) const;
794 
795  // called by the generic pack()
796  virtual void pack1(OutputFile *, Filter &); // generate executable header
797  virtual int pack2(OutputFile *, Filter &); // append compressed data
798  virtual void pack3(OutputFile *, Filter &) /*= 0*/; // append loader
799  virtual void pack4(OutputFile *, Filter &) /*= 0*/; // append PackHeader
800 
801  virtual void pack4dylib(OutputFile *, Filter &, Addr init_address);
802 
803  virtual int threado_size() const = 0;
804  virtual void threado_setPC(upx_uint64_t pc) = 0;
805  virtual void threado_rewrite(OutputFile *) = 0;
806  virtual void threado_write(OutputFile *) = 0;
807  virtual void pack1_setup_threado(OutputFile *const fo) = 0;
808  virtual void unpack(OutputFile *fo);
809 
810  virtual bool canPack();
811  virtual int canUnpack();
812  virtual unsigned find_SEGMENT_gap(unsigned const k, unsigned pos_eof);
813 
814 protected:
815  virtual void patchLoader();
816  virtual void patchLoaderChecksum();
817  virtual void updateLoader(OutputFile *);
818  virtual void buildLoader(const Filter *ft);
819  virtual void buildMachLoader(
820  upx_byte const *const proto,
821  unsigned const szproto,
822  upx_byte const *const fold,
823  unsigned const szfold,
824  Filter const *ft );
825  virtual void defineSymbols(Filter const *);
826  virtual void addStubEntrySections(Filter const *);
827 
828  static int __acc_cdecl_qsort compare_segment_command(void const *aa, void const *bb);
829 
830  virtual upx_uint64_t threadc_getPC(void /*MachThreadCommand*/ const *) = 0;
831 
832  upx_uint64_t entryVMA;
833  unsigned my_cputype;
834  unsigned my_cpusubtype;
835  unsigned my_filetype;
836  unsigned my_thread_flavor;
837  unsigned my_thread_state_word_count;
838  unsigned my_thread_command_size;
839 
840  unsigned n_segment;
841  unsigned sz_segment;
842  unsigned sz_mach_headers;
843  unsigned sz_stub_entry;
844  unsigned sz_stub_fold;
845  unsigned sz_stub_main;
846  upx_byte const *stub_entry;
847  upx_byte const *stub_fold;
848  upx_byte const *stub_main;
849  Mach_segment_command *rawmseg; // as input, with sections
850  Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
851  unsigned o_routines_cmd; // file offset to LC_ROUINTES
852  upx_uint64_t prev_init_address;
853  Mach_header mhdri;
854 
855  Mach_header mhdro;
856  Mach_segment_command segZERO;
857  Mach_segment_command segXHDR; // location to put eXtra headers
858  Mach_section_command secXHDR;
859  Mach_segment_command segTEXT;
860  Mach_section_command secTEXT;
861  Mach_segment_command segLINK;
862  Mach_linkedit_data_command linkitem;
863  Mach_uuid_command cmdUUID; // copied from input, then incremented
864  Mach_source_version_command cmdSRCVER; // copied from input
865  Mach_version_min_command cmdVERMIN; // copied from input
866 
867  __packed_struct(b_info) // 12-byte header before each compressed block
868  TE32 sz_unc; // uncompressed_size
869  TE32 sz_cpr; // compressed_size
870  unsigned char b_method; // compression algorithm
871  unsigned char b_ftid; // filter id
872  unsigned char b_cto8; // filter parameter
873  unsigned char b_unused;
874  __packed_struct_end()
875 
876  __packed_struct(l_info) // 12-byte trailer in header for loader
877  TE32 l_checksum;
878  LE32 l_magic;
879  TE16 l_lsize;
880  unsigned char l_version;
881  unsigned char l_format;
882  __packed_struct_end()
883 
884  __packed_struct(p_info) // 12-byte packed program header
885  TE32 p_progid;
886  TE32 p_filesize;
887  TE32 p_blocksize;
888  __packed_struct_end()
889 
890  struct l_info linfo;
891 
892  static void compileTimeAssertions() {
893  MachClass::compileTimeAssertions();
894  COMPILE_TIME_ASSERT(sizeof(b_info) == 12)
895  COMPILE_TIME_ASSERT(sizeof(l_info) == 12)
896  COMPILE_TIME_ASSERT(sizeof(p_info) == 12)
897  COMPILE_TIME_ASSERT_ALIGNED1(b_info)
898  COMPILE_TIME_ASSERT_ALIGNED1(l_info)
899  COMPILE_TIME_ASSERT_ALIGNED1(p_info)
900  }
901 };
902 
903 
904 class PackMachPPC32 : public PackMachBase<MachClass_BE32>
905 {
907 
908 public:
910 
911  virtual int getFormat() const { return UPX_F_MACH_PPC32; }
912  virtual const char *getName() const { return "macho/ppc32"; }
913  virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.macho"; }
914 
915 protected:
916  virtual const int *getFilters() const;
917 
918  virtual void pack1_setup_threado(OutputFile *const fo);
919  virtual Linker* newLinker() const;
920  virtual void addStubEntrySections(Filter const *);
921 
922  __packed_struct(Mach_thread_command)
923  TE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
924  TE32 cmdsize; /* total size of this command */
925  TE32 flavor;
926  TE32 count; /* sizeof(following_thread_state)/4 */
927  Mach_ppc_thread_state state;
928  #define WANT_MACH_THREAD_ENUM 1
929  #include "p_mach_enum.h"
930  __packed_struct_end()
931 
932  Mach_thread_command threado;
933  int threado_size() const { return sizeof(threado); }
934  void threado_setPC(upx_uint64_t pc) {
935  memset(&threado, 0, sizeof(threado));
936  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
937  threado.cmdsize = sizeof(threado);
938  threado.flavor = my_thread_flavor;
939  threado.count = my_thread_state_word_count;
940  threado.state.srr0 = pc;
941  }
942  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
943  void threado_write(OutputFile *fo) { fo->write(&threado, sizeof(threado)); }
944 
945  upx_uint64_t threadc_getPC(void const *ptr) {
946  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
947  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
948  || tc->cmdsize!=sizeof(threado)
949  || tc->flavor!=my_thread_flavor
950  || tc->count!=my_thread_state_word_count) {
951  return ~0ull;
952  }
953  return tc->state.srr0;
954  }
955 };
956 
957 class PackMachPPC64LE : public PackMachBase<MachClass_LE64>
958 {
960 
961 public:
963 
964  virtual int getFormat() const { return UPX_F_MACH_PPC64LE; }
965  virtual const char *getName() const { return "macho/ppc64le"; }
966  virtual const char *getFullName(const options_t *) const { return "powerpc64le-darwin.macho"; }
967 
968 protected:
969  virtual const int *getFilters() const;
970 
971  virtual void pack1_setup_threado(OutputFile *const fo);
972  virtual Linker* newLinker() const;
973 
974  __packed_struct(Mach_thread_command)
975  LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
976  LE32 cmdsize; /* total size of this command */
977  LE32 flavor;
978  LE32 count; /* sizeof(following_thread_state)/4 */
979  Mach_ppcle_thread_state64 state64;
980  #define WANT_MACH_THREAD_ENUM 1
981  #include "p_mach_enum.h"
982  __packed_struct_end()
983 
984  Mach_thread_command threado;
985  int threado_size() const { return sizeof(threado); }
986  void threado_setPC(upx_uint64_t pc) {
987  memset(&threado, 0, sizeof(threado));
988  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
989  threado.cmdsize = sizeof(threado);
990  threado.flavor = my_thread_flavor;
991  threado.count = my_thread_state_word_count;
992  threado.state64.srr0 = pc;
993  }
994  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
995  void threado_write(OutputFile *fo) { fo->write(&threado, sizeof(threado)); }
996 
997  upx_uint64_t threadc_getPC(void const *ptr) {
998  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
999  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
1000  || tc->cmdsize!=sizeof(threado)
1001  || tc->flavor!=my_thread_flavor
1002  || tc->count!=my_thread_state_word_count) {
1003  return ~0ull;
1004  }
1005  return tc->state64.srr0;
1006  }
1007 };
1008 
1010 {
1011  typedef PackMachPPC32 super;
1012 
1013 public:
1015 
1016  virtual int getFormat() const { return UPX_F_DYLIB_PPC32; }
1017  virtual const char *getName() const { return "dylib/ppc32"; }
1018  virtual const char *getFullName(const options_t *) const { return "powerpc-darwin.dylib"; }
1019 protected:
1020  virtual void pack3(OutputFile *, Filter &); // append loader
1021  virtual void pack4(OutputFile *, Filter &); // append PackHeader
1022 };
1023 
1025 {
1026  typedef PackMachPPC64LE super;
1027 
1028 public:
1030 
1031  virtual int getFormat() const { return UPX_F_DYLIB_PPC64LE; }
1032  virtual const char *getName() const { return "dylib/ppc64le"; }
1033  virtual const char *getFullName(const options_t *) const { return "powerpc64le-darwin.dylib"; }
1034 protected:
1035  virtual void pack3(OutputFile *, Filter &); // append loader
1036  virtual void pack4(OutputFile *, Filter &); // append PackHeader
1037 };
1038 
1039 class PackMachI386 : public PackMachBase<MachClass_LE32>
1040 {
1042 
1043 public:
1044  PackMachI386(InputFile *f);
1045 
1046  virtual int getFormat() const { return UPX_F_MACH_i386; }
1047  virtual const char *getName() const { return "macho/i386"; }
1048  virtual const char *getFullName(const options_t *) const { return "i386-darwin.macho"; }
1049 protected:
1050  virtual const int *getFilters() const;
1051 
1052  virtual void pack1_setup_threado(OutputFile *const fo);
1053  virtual Linker* newLinker() const;
1054  virtual void addStubEntrySections(Filter const *);
1055 
1056  __packed_struct(Mach_thread_command)
1057  LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
1058  LE32 cmdsize; /* total size of this command */
1059  LE32 flavor;
1060  LE32 count; /* sizeof(following_thread_state)/4 */
1061  Mach_i386_thread_state state;
1062  #define WANT_MACH_THREAD_ENUM 1
1063  #include "p_mach_enum.h"
1064  __packed_struct_end()
1065 
1066  Mach_thread_command threado;
1067  int threado_size() const { return sizeof(threado); }
1068  void threado_setPC(upx_uint64_t pc) {
1069  memset(&threado, 0, sizeof(threado));
1070  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
1071  threado.cmdsize = sizeof(threado);
1072  threado.flavor = my_thread_flavor;
1073  threado.count = my_thread_state_word_count;
1074  threado.state.eip = pc;
1075  }
1076  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
1077  void threado_write(OutputFile *fo) { fo->write(&threado, sizeof(threado)); }
1078 
1079  upx_uint64_t threadc_getPC(void const *ptr) {
1080  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
1081  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
1082  || tc->cmdsize!=sizeof(threado)
1083  || tc->flavor!=my_thread_flavor
1084  || tc->count!=my_thread_state_word_count) {
1085  return ~0ull;
1086  }
1087  return tc->state.eip;
1088  }
1089 };
1090 
1092 {
1093  typedef PackMachI386 super;
1094 
1095 public:
1097 
1098  virtual int getFormat() const { return UPX_F_DYLIB_i386; }
1099  virtual const char *getName() const { return "dylib/i386"; }
1100  virtual const char *getFullName(const options_t *) const { return "i386-darwin.dylib"; }
1101 protected:
1102  virtual void pack3(OutputFile *, Filter &); // append loader
1103  virtual void pack4(OutputFile *, Filter &); // append PackHeader
1104 };
1105 
1106 class PackMachAMD64 : public PackMachBase<MachClass_LE64>
1107 {
1109 
1110 public:
1112 
1113  virtual int getFormat() const { return UPX_F_MACH_AMD64; }
1114  virtual const char *getName() const { return "macho/amd64"; }
1115  virtual const char *getFullName(const options_t *) const { return "amd64-darwin.macho"; }
1116 protected:
1117  virtual const int *getFilters() const;
1118 
1119  virtual void pack1_setup_threado(OutputFile *const fo);
1120  virtual Linker* newLinker() const;
1121  virtual void addStubEntrySections(Filter const *);
1122 
1123  __packed_struct(Mach_thread_command)
1124  typedef MachITypes::Word Word;
1125  Word cmd; /* LC_THREAD or LC_UNIXTHREAD */
1126  Word cmdsize; /* total size of this command */
1127  Word flavor;
1128  Word count; /* sizeof(following_thread_state)/4 */
1129  Mach_AMD64_thread_state state;
1130  #define WANT_MACH_THREAD_ENUM 1
1131  #include "p_mach_enum.h"
1132  __packed_struct_end()
1133 
1134  Mach_thread_command threado;
1135  int threado_size() const { return sizeof(threado); }
1136  void threado_setPC(upx_uint64_t pc) {
1137  memset(&threado, 0, sizeof(threado));
1138  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
1139  threado.cmdsize = sizeof(threado);
1140  threado.flavor = my_thread_flavor;
1141  threado.count = my_thread_state_word_count;
1142  threado.state.rip = pc;
1143  }
1144  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
1145  void threado_write(OutputFile *fo) { fo->write(&threado, sizeof(threado)); }
1146 
1147  upx_uint64_t threadc_getPC(void const *ptr) {
1148  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
1149  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
1150  || tc->cmdsize!=sizeof(threado)
1151  || tc->flavor!=my_thread_flavor
1152  || tc->count!=my_thread_state_word_count) {
1153  return ~0ull;
1154  }
1155  return tc->state.rip;
1156  }
1157 };
1158 
1160 {
1161  typedef PackMachAMD64 super;
1162 
1163 public:
1165 
1166  virtual int getFormat() const { return UPX_F_DYLIB_AMD64; }
1167  virtual const char *getName() const { return "dylib/amd64"; }
1168  virtual const char *getFullName(const options_t *) const { return "amd64-darwin.dylib"; }
1169 protected:
1170  virtual void pack3(OutputFile *, Filter &); // append loader
1171  virtual void pack4(OutputFile *, Filter &); // append PackHeader
1172 };
1173 
1174 class PackMachARMEL : public PackMachBase<MachClass_LE32>
1175 {
1177 
1178 public:
1180 
1181  virtual int getFormat() const { return UPX_F_MACH_ARMEL; }
1182  virtual const char *getName() const { return "macho/arm"; }
1183  virtual const char *getFullName(const options_t *) const { return "arm-darwin.macho"; }
1184 protected:
1185  virtual const int *getCompressionMethods(int method, int level) const;
1186  virtual const int *getFilters() const;
1187 
1188  virtual void pack1_setup_threado(OutputFile *const fo);
1189  virtual Linker* newLinker() const;
1190  virtual void addStubEntrySections(Filter const *);
1191 
1192  __packed_struct(Mach_thread_command)
1193  LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
1194  LE32 cmdsize; /* total size of this command */
1195  LE32 flavor;
1196  LE32 count; /* sizeof(following_thread_state)/4 */
1197  Mach_ARM_thread_state state;
1198  #define WANT_MACH_THREAD_ENUM 1
1199  #include "p_mach_enum.h"
1200  __packed_struct_end()
1201 
1202  Mach_thread_command threado;
1203  int threado_size() const { return sizeof(threado); }
1204  void threado_setPC(upx_uint64_t pc) {
1205  memset(&threado, 0, sizeof(threado));
1206  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
1207  threado.cmdsize = sizeof(threado);
1208  threado.flavor = my_thread_flavor;
1209  threado.count = my_thread_state_word_count;
1210  threado.state.pc = pc;
1211  }
1212  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
1213  void threado_write(OutputFile *fo) { return fo->write(&threado, sizeof(threado)); }
1214 
1215  upx_uint64_t threadc_getPC(void const *ptr) {
1216  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
1217  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
1218  || tc->cmdsize!=sizeof(threado)
1219  || tc->flavor!=my_thread_flavor
1220  || tc->count!=my_thread_state_word_count) {
1221  return ~0ull;
1222  }
1223  return tc->state.pc;
1224  }
1225 };
1226 
1227 class PackMachARM64EL : public PackMachBase<MachClass_LE64>
1228 {
1230 
1231 public:
1233 
1234  virtual int getFormat() const { return UPX_F_MACH_ARM64EL; }
1235  virtual const char *getName() const { return "macho/arm64"; }
1236  virtual const char *getFullName(const options_t *) const { return "arm64-darwin.macho"; }
1237 protected:
1238  virtual const int *getCompressionMethods(int method, int level) const;
1239  virtual const int *getFilters() const;
1240 
1241  virtual void pack1_setup_threado(OutputFile *const fo);
1242  virtual Linker* newLinker() const;
1243  virtual void addStubEntrySections(Filter const *);
1244 
1245  __packed_struct(Mach_thread_command)
1246  LE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
1247  LE32 cmdsize; /* total size of this command */
1248  LE32 flavor;
1249  LE32 count; /* sizeof(following_thread_state)/4 */
1250  Mach_ARM64_thread_state state;
1251  #define WANT_MACH_THREAD_ENUM 1
1252  #include "p_mach_enum.h"
1253  __packed_struct_end()
1254 
1255  Mach_thread_command threado;
1256  int threado_size() const { return sizeof(threado); }
1257  void threado_setPC(upx_uint64_t pc) {
1258  memset(&threado, 0, sizeof(threado));
1259  threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
1260  threado.cmdsize = sizeof(threado);
1261  threado.flavor = my_thread_flavor;
1262  threado.count = my_thread_state_word_count;
1263  threado.state.pc = pc;
1264  }
1265  void threado_rewrite(OutputFile *fo) { fo->rewrite(&threado, sizeof(threado)); }
1266  void threado_write(OutputFile *fo) { fo->write(&threado, sizeof(threado)); }
1267 
1268  upx_uint64_t threadc_getPC(void const *ptr) {
1269  Mach_thread_command const *tc = (Mach_thread_command const *)ptr;
1270  if (tc->cmd!=Mach_segment_command::LC_UNIXTHREAD
1271  || tc->cmdsize!=sizeof(threado)
1272  || tc->flavor!=my_thread_flavor
1273  || tc->count!=my_thread_state_word_count) {
1274  return ~0ull;
1275  }
1276  return tc->state.pc;
1277  }
1278 };
1279 
1280 class PackMachFat : public Packer
1281 {
1282  typedef Packer super;
1283 public:
1284  PackMachFat(InputFile *f);
1285  virtual ~PackMachFat();
1286 
1287  virtual int getVersion() const { return 13; }
1288  virtual int getFormat() const { return UPX_F_MACH_FAT; }
1289  virtual const char *getName() const { return "macho/fat"; }
1290  virtual const char *getFullName(const options_t *) const { return "fat-darwin.macho"; }
1291  virtual const int *getCompressionMethods(int method, int level) const;
1292  virtual const int *getFilters() const;
1293 
1294 protected:
1295  // implementation
1296  virtual unsigned check_fat_head(); // number of architectures
1297  virtual void pack(OutputFile *fo);
1298  virtual void unpack(OutputFile *fo);
1299  virtual void list();
1300 
1301 public:
1302  virtual bool canPack();
1303  virtual int canUnpack();
1304 
1305 protected:
1306  // loader core
1307  virtual void buildLoader(const Filter *ft);
1308  virtual Linker* newLinker() const;
1309 
1310  enum { N_FAT_ARCH = 5 };
1311 protected:
1312  __packed_struct(Fat_head)
1313  struct Mach_fat_header fat;
1314  struct Mach_fat_arch arch[N_FAT_ARCH];
1315  __packed_struct_end()
1316 
1317  Fat_head fat_head;
1318 
1319  // UI handler
1320  UiPacker *uip;
1321 
1322  // linker
1323  Linker *linker;
1324 #define WANT_MACH_HEADER_ENUM 1
1325 #include "p_mach_enum.h"
1326 };
1327 
1328 #endif /* already included */
1329 
1330 /* vim:set ts=4 sw=4 et: */
Definition: p_mach.h:1280
Definition: linker.h:35
Definition: options.h:45
Definition: p_unix.h:38
Definition: file.h:89
Definition: p_mach.h:1091
Definition: packer.h:115
Definition: p_mach.h:533
Definition: p_mach.h:1174
Definition: p_mach.h:1024
Definition: p_mach.h:530
Definition: p_mach.h:577
Definition: p_mach.h:458
Definition: p_mach.h:1009
Definition: p_mach.h:411
Definition: file.h:121
Definition: p_mach.h:1106
Definition: ui.h:40
Definition: p_mach.h:1227
Definition: filter.h:53
Definition: p_mach.h:904
Definition: p_mach.h:1159
Definition: p_mach.h:957
Definition: p_mach.h:754
Definition: p_mach.h:1039