]> gitweb.factorcode.org Git - factor.git/blob - extra/macho/macho.factor
Merge branch 'master' of github.com:erikcharlebois/factor
[factor.git] / extra / macho / macho.factor
1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See http:// factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.strings alien.syntax
4 classes classes.struct combinators io.encodings.ascii
5 io.encodings.string kernel literals make math sequences
6 specialized-arrays typed fry io.mmap formatting locals ;
7 FROM: alien.c-types => short ;
8 IN: macho
9
10 ! FFI data
11 TYPEDEF: int       integer_t
12 TYPEDEF: int       vm_prot_t
13 TYPEDEF: integer_t cpu_type_t
14 TYPEDEF: integer_t cpu_subtype_t
15 TYPEDEF: integer_t cpu_threadtype_t
16
17 CONSTANT: VM_PROT_NONE        HEX: 00
18 CONSTANT: VM_PROT_READ        HEX: 01
19 CONSTANT: VM_PROT_WRITE       HEX: 02
20 CONSTANT: VM_PROT_EXECUTE     HEX: 04
21 CONSTANT: VM_PROT_DEFAULT     HEX: 03
22 CONSTANT: VM_PROT_ALL         HEX: 07
23 CONSTANT: VM_PROT_NO_CHANGE   HEX: 08
24 CONSTANT: VM_PROT_COPY        HEX: 10
25 CONSTANT: VM_PROT_WANTS_COPY  HEX: 10
26
27 ! loader.h
28 STRUCT: mach_header
29     { magic         uint          }
30     { cputype       cpu_type_t    }
31     { cpusubtype    cpu_subtype_t }
32     { filetype      uint          }
33     { ncmds         uint          }
34     { sizeofcmds    uint          }
35     { flags         uint          } ;
36
37 CONSTANT: MH_MAGIC    HEX: feedface
38 CONSTANT: MH_CIGAM    HEX: cefaedfe
39
40 STRUCT: mach_header_64
41     { magic         uint          }
42     { cputype       cpu_type_t    }
43     { cpusubtype    cpu_subtype_t }
44     { filetype      uint          }
45     { ncmds         uint          }
46     { sizeofcmds    uint          }
47     { flags         uint          }
48     { reserved      uint          } ;
49
50 CONSTANT: MH_MAGIC_64 HEX: feedfacf
51 CONSTANT: MH_CIGAM_64 HEX: cffaedfe
52
53 CONSTANT: MH_OBJECT       HEX: 1
54 CONSTANT: MH_EXECUTE      HEX: 2
55 CONSTANT: MH_FVMLIB       HEX: 3
56 CONSTANT: MH_CORE         HEX: 4
57 CONSTANT: MH_PRELOAD      HEX: 5
58 CONSTANT: MH_DYLIB        HEX: 6
59 CONSTANT: MH_DYLINKER     HEX: 7
60 CONSTANT: MH_BUNDLE       HEX: 8
61 CONSTANT: MH_DYLIB_STUB   HEX: 9
62 CONSTANT: MH_DSYM         HEX: a
63 CONSTANT: MH_KEXT_BUNDLE  HEX: b
64
65 CONSTANT: MH_NOUNDEFS                HEX: 1
66 CONSTANT: MH_INCRLINK                HEX: 2
67 CONSTANT: MH_DYLDLINK                HEX: 4
68 CONSTANT: MH_BINDATLOAD              HEX: 8
69 CONSTANT: MH_PREBOUND                HEX: 10
70 CONSTANT: MH_SPLIT_SEGS              HEX: 20
71 CONSTANT: MH_LAZY_INIT               HEX: 40
72 CONSTANT: MH_TWOLEVEL                HEX: 80
73 CONSTANT: MH_FORCE_FLAT              HEX: 100
74 CONSTANT: MH_NOMULTIDEFS             HEX: 200
75 CONSTANT: MH_NOFIXPREBINDING         HEX: 400
76 CONSTANT: MH_PREBINDABLE             HEX: 800
77 CONSTANT: MH_ALLMODSBOUND            HEX: 1000
78 CONSTANT: MH_SUBSECTIONS_VIA_SYMBOLS HEX: 2000
79 CONSTANT: MH_CANONICAL               HEX: 4000
80 CONSTANT: MH_WEAK_DEFINES            HEX: 8000
81 CONSTANT: MH_BINDS_TO_WEAK           HEX: 10000
82 CONSTANT: MH_ALLOW_STACK_EXECUTION   HEX: 20000
83 CONSTANT: MH_DEAD_STRIPPABLE_DYLIB   HEX: 400000
84 CONSTANT: MH_ROOT_SAFE               HEX: 40000
85 CONSTANT: MH_SETUID_SAFE             HEX: 80000
86 CONSTANT: MH_NO_REEXPORTED_DYLIBS    HEX: 100000
87 CONSTANT: MH_PIE                     HEX: 200000
88
89 STRUCT: load_command
90     { cmd     uint }
91     { cmdsize uint } ;
92
93 CONSTANT: LC_REQ_DYLD HEX: 80000000
94
95 CONSTANT: LC_SEGMENT            HEX: 1
96 CONSTANT: LC_SYMTAB             HEX: 2
97 CONSTANT: LC_SYMSEG             HEX: 3
98 CONSTANT: LC_THREAD             HEX: 4
99 CONSTANT: LC_UNIXTHREAD         HEX: 5
100 CONSTANT: LC_LOADFVMLIB         HEX: 6
101 CONSTANT: LC_IDFVMLIB           HEX: 7
102 CONSTANT: LC_IDENT              HEX: 8
103 CONSTANT: LC_FVMFILE            HEX: 9
104 CONSTANT: LC_PREPAGE            HEX: a
105 CONSTANT: LC_DYSYMTAB           HEX: b
106 CONSTANT: LC_LOAD_DYLIB         HEX: c
107 CONSTANT: LC_ID_DYLIB           HEX: d
108 CONSTANT: LC_LOAD_DYLINKER      HEX: e
109 CONSTANT: LC_ID_DYLINKER        HEX: f
110 CONSTANT: LC_PREBOUND_DYLIB     HEX: 10
111 CONSTANT: LC_ROUTINES           HEX: 11
112 CONSTANT: LC_SUB_FRAMEWORK      HEX: 12
113 CONSTANT: LC_SUB_UMBRELLA       HEX: 13
114 CONSTANT: LC_SUB_CLIENT         HEX: 14
115 CONSTANT: LC_SUB_LIBRARY        HEX: 15
116 CONSTANT: LC_TWOLEVEL_HINTS     HEX: 16
117 CONSTANT: LC_PREBIND_CKSUM      HEX: 17
118 CONSTANT: LC_LOAD_WEAK_DYLIB    HEX: 80000018
119 CONSTANT: LC_SEGMENT_64         HEX: 19
120 CONSTANT: LC_ROUTINES_64        HEX: 1a
121 CONSTANT: LC_UUID               HEX: 1b
122 CONSTANT: LC_RPATH              HEX: 8000001c
123 CONSTANT: LC_CODE_SIGNATURE     HEX: 1d
124 CONSTANT: LC_SEGMENT_SPLIT_INFO HEX: 1e
125 CONSTANT: LC_REEXPORT_DYLIB     HEX: 8000001f
126 CONSTANT: LC_LAZY_LOAD_DYLIB    HEX: 20
127 CONSTANT: LC_ENCRYPTION_INFO    HEX: 21
128 CONSTANT: LC_DYLD_INFO          HEX: 22
129 CONSTANT: LC_DYLD_INFO_ONLY     HEX: 80000022
130
131 UNION-STRUCT: lc_str
132     { offset    uint     }
133     { ptr       char*    } ;
134
135 STRUCT: segment_command
136     { cmd            uint      }
137     { cmdsize        uint      }
138     { segname        char[16]  }
139     { vmaddr         uint      }
140     { vmsize         uint      }
141     { fileoff        uint      }
142     { filesize       uint      }
143     { maxprot        vm_prot_t }
144     { initprot       vm_prot_t }
145     { nsects         uint      }
146     { flags          uint      } ;
147
148 STRUCT: segment_command_64
149     { cmd            uint       }
150     { cmdsize        uint       }
151     { segname        char[16]   }
152     { vmaddr         ulonglong  }
153     { vmsize         ulonglong  }
154     { fileoff        ulonglong  }
155     { filesize       ulonglong  }
156     { maxprot        vm_prot_t  }
157     { initprot       vm_prot_t  }
158     { nsects         uint       }
159     { flags          uint       } ;
160     
161 CONSTANT: SG_HIGHVM               HEX: 1
162 CONSTANT: SG_FVMLIB               HEX: 2
163 CONSTANT: SG_NORELOC              HEX: 4
164 CONSTANT: SG_PROTECTED_VERSION_1  HEX: 8
165
166 STRUCT: section
167     { sectname        char[16] }
168     { segname         char[16] }
169     { addr            uint     }
170     { size            uint     }
171     { offset          uint     }
172     { align           uint     }
173     { reloff          uint     }
174     { nreloc          uint     }
175     { flags           uint     }
176     { reserved1       uint     }
177     { reserved2       uint     } ;
178
179 STRUCT: section_64
180     { sectname        char[16]  }
181     { segname         char[16]  }
182     { addr            ulonglong }
183     { size            ulonglong }
184     { offset          uint      }
185     { align           uint      }
186     { reloff          uint      }
187     { nreloc          uint      }
188     { flags           uint      }
189     { reserved1       uint      }
190     { reserved2       uint      }
191     { reserved3       uint      } ;
192
193 CONSTANT: SECTION_TYPE         HEX: 000000ff
194 CONSTANT: SECTION_ATTRIBUTES   HEX: ffffff00
195
196 CONSTANT: S_REGULAR                       HEX: 0
197 CONSTANT: S_ZEROFILL                      HEX: 1
198 CONSTANT: S_CSTRING_LITERALS              HEX: 2
199 CONSTANT: S_4BYTE_LITERALS                HEX: 3
200 CONSTANT: S_8BYTE_LITERALS                HEX: 4
201 CONSTANT: S_LITERAL_POINTERS              HEX: 5
202 CONSTANT: S_NON_LAZY_SYMBOL_POINTERS      HEX: 6
203 CONSTANT: S_LAZY_SYMBOL_POINTERS          HEX: 7
204 CONSTANT: S_SYMBOL_STUBS                  HEX: 8
205 CONSTANT: S_MOD_INIT_FUNC_POINTERS        HEX: 9
206 CONSTANT: S_MOD_TERM_FUNC_POINTERS        HEX: a
207 CONSTANT: S_COALESCED                     HEX: b
208 CONSTANT: S_GB_ZEROFILL                   HEX: c
209 CONSTANT: S_INTERPOSING                   HEX: d
210 CONSTANT: S_16BYTE_LITERALS               HEX: e
211 CONSTANT: S_DTRACE_DOF                    HEX: f
212 CONSTANT: S_LAZY_DYLIB_SYMBOL_POINTERS    HEX: 10
213
214 CONSTANT: SECTION_ATTRIBUTES_USR     HEX: ff000000
215 CONSTANT: S_ATTR_PURE_INSTRUCTIONS   HEX: 80000000
216 CONSTANT: S_ATTR_NO_TOC              HEX: 40000000
217 CONSTANT: S_ATTR_STRIP_STATIC_SYMS   HEX: 20000000
218 CONSTANT: S_ATTR_NO_DEAD_STRIP       HEX: 10000000
219 CONSTANT: S_ATTR_LIVE_SUPPORT        HEX: 08000000
220 CONSTANT: S_ATTR_SELF_MODIFYING_CODE HEX: 04000000
221 CONSTANT: S_ATTR_DEBUG               HEX: 02000000
222 CONSTANT: SECTION_ATTRIBUTES_SYS     HEX: 00ffff00
223 CONSTANT: S_ATTR_SOME_INSTRUCTIONS   HEX: 00000400
224 CONSTANT: S_ATTR_EXT_RELOC           HEX: 00000200
225 CONSTANT: S_ATTR_LOC_RELOC           HEX: 00000100
226
227 CONSTANT: SEG_PAGEZERO      "__PAGEZERO"
228 CONSTANT: SEG_TEXT          "__TEXT"
229 CONSTANT: SECT_TEXT         "__text"
230 CONSTANT: SECT_FVMLIB_INIT0 "__fvmlib_init0"
231 CONSTANT: SECT_FVMLIB_INIT1 "__fvmlib_init1"
232 CONSTANT: SEG_DATA          "__DATA"
233 CONSTANT: SECT_DATA         "__data"
234 CONSTANT: SECT_BSS          "__bss"
235 CONSTANT: SECT_COMMON       "__common"
236 CONSTANT: SEG_OBJC          "__OBJC"
237 CONSTANT: SECT_OBJC_SYMBOLS "__symbol_table"
238 CONSTANT: SECT_OBJC_MODULES "__module_info"
239 CONSTANT: SECT_OBJC_STRINGS "__selector_strs"
240 CONSTANT: SECT_OBJC_REFS    "__selector_refs"
241 CONSTANT: SEG_ICON          "__ICON"
242 CONSTANT: SECT_ICON_HEADER  "__header"
243 CONSTANT: SECT_ICON_TIFF    "__tiff"
244 CONSTANT: SEG_LINKEDIT      "__LINKEDIT"
245 CONSTANT: SEG_UNIXSTACK     "__UNIXSTACK"
246 CONSTANT: SEG_IMPORT        "__IMPORT"
247
248 STRUCT: fvmlib
249     { name             lc_str   }
250     { minor_version    uint     }
251     { header_addr      uint     } ;
252
253 STRUCT: fvmlib_command
254     { cmd        uint     }
255     { cmdsize    uint     }
256     { fvmlib     fvmlib   } ;
257
258 STRUCT: dylib
259     { name                  lc_str   }
260     { timestamp             uint     }
261     { current_version       uint     }
262     { compatibility_version uint     } ;
263
264 STRUCT: dylib_command
265     { cmd        uint     }
266     { cmdsize    uint     }
267     { dylib      dylib    } ;
268
269 STRUCT: sub_framework_command
270     { cmd         uint     }
271     { cmdsize     uint     }
272     { umbrella    lc_str   } ;
273
274 STRUCT: sub_client_command
275     { cmd        uint     }
276     { cmdsize    uint     }
277     { client     lc_str   } ;
278
279 STRUCT: sub_umbrella_command
280     { cmd             uint     }
281     { cmdsize         uint     }
282     { sub_umbrella    lc_str   } ;
283
284 STRUCT: sub_library_command
285     { cmd            uint     }
286     { cmdsize        uint     }
287     { sub_library    lc_str   } ;
288
289 STRUCT: prebound_dylib_command
290     { cmd               uint     }
291     { cmdsize           uint     }
292     { name              lc_str   }
293     { nmodules          uint     }
294     { linked_modules    lc_str   } ;
295
296 STRUCT: dylinker_command
297     { cmd        uint     }
298     { cmdsize    uint     }
299     { name       lc_str   } ;
300
301 STRUCT: thread_command
302     { cmd        uint }
303     { cmdsize    uint } ;
304
305 STRUCT: routines_command
306     { cmd             uint }
307     { cmdsize         uint }
308     { init_address    uint }
309     { init_module     uint }
310     { reserved1       uint }
311     { reserved2       uint }
312     { reserved3       uint }
313     { reserved4       uint }
314     { reserved5       uint }
315     { reserved6       uint } ;
316
317 STRUCT: routines_command_64
318     { cmd             uint      }
319     { cmdsize         uint      }
320     { init_address    ulonglong }
321     { init_module     ulonglong }
322     { reserved1       ulonglong }
323     { reserved2       ulonglong }
324     { reserved3       ulonglong }
325     { reserved4       ulonglong }
326     { reserved5       ulonglong }
327     { reserved6       ulonglong } ;
328
329 STRUCT: symtab_command
330     { cmd        uint }
331     { cmdsize    uint }
332     { symoff     uint }
333     { nsyms      uint }
334     { stroff     uint }
335     { strsize    uint } ;
336
337 STRUCT: dysymtab_command
338     { cmd            uint }
339     { cmdsize        uint }
340     { ilocalsym      uint }
341     { nlocalsym      uint }
342     { iextdefsym     uint }
343     { nextdefsym     uint }
344     { iundefsym      uint }
345     { nundefsym      uint }
346     { tocoff         uint }
347     { ntoc           uint }
348     { modtaboff      uint }
349     { nmodtab        uint }
350     { extrefsymoff   uint }
351     { nextrefsyms    uint }
352     { indirectsymoff uint }
353     { nindirectsyms  uint }
354     { extreloff      uint }
355     { nextrel        uint }
356     { locreloff      uint }
357     { nlocrel        uint } ;
358
359 CONSTANT: INDIRECT_SYMBOL_LOCAL HEX: 80000000
360 CONSTANT: INDIRECT_SYMBOL_ABS   HEX: 40000000
361
362 STRUCT: dylib_table_of_contents
363     { symbol_index uint }
364     { module_index uint } ;
365
366 STRUCT: dylib_module
367     { module_name           uint }
368     { iextdefsym            uint }
369     { nextdefsym            uint }
370     { irefsym               uint }
371     { nrefsym               uint }
372     { ilocalsym             uint }
373     { nlocalsym             uint }
374     { iextrel               uint }
375     { nextrel               uint }
376     { iinit_iterm           uint }
377     { ninit_nterm           uint }
378     { objc_module_info_addr uint }
379     { objc_module_info_size uint } ;
380
381 STRUCT: dylib_module_64
382     { module_name           uint      }
383     { iextdefsym            uint      }
384     { nextdefsym            uint      }
385     { irefsym               uint      }
386     { nrefsym               uint      }
387     { ilocalsym             uint      }
388     { nlocalsym             uint      }
389     { iextrel               uint      }
390     { nextrel               uint      }
391     { iinit_iterm           uint      }
392     { ninit_nterm           uint      }
393     { objc_module_info_size uint      }
394     { objc_module_info_addr ulonglong } ;
395
396 STRUCT: dylib_reference
397     { isym_flags uint } ;
398
399 STRUCT: twolevel_hints_command
400     { cmd     uint }
401     { cmdsize uint }
402     { offset  uint }
403     { nhints  uint } ;
404
405 STRUCT: twolevel_hint
406     { isub_image_itoc uint } ;
407
408 STRUCT: prebind_cksum_command
409     { cmd     uint }
410     { cmdsize uint }
411     { cksum   uint } ;
412
413 STRUCT: uuid_command
414     { cmd        uint        }
415     { cmdsize    uint        }
416     { uuid       uchar[16]   } ;
417
418 STRUCT: rpath_command
419     { cmd         uint     }
420     { cmdsize     uint     }
421     { path        lc_str   } ;
422
423 STRUCT: linkedit_data_command
424     { cmd         uint }
425     { cmdsize     uint }
426     { dataoff     uint }
427     { datasize    uint } ;
428
429 STRUCT: encryption_info_command
430     { cmd       uint }
431     { cmdsize   uint }
432     { cryptoff  uint }
433     { cryptsize uint }
434     { cryptid   uint } ;
435
436 STRUCT: dyld_info_command
437     { cmd              uint }
438     { cmdsize          uint }
439     { rebase_off       uint }
440     { rebase_size      uint }
441     { bind_off         uint }
442     { bind_size        uint }
443     { weak_bind_off    uint }
444     { weak_bind_size   uint }
445     { lazy_bind_off    uint }
446     { lazy_bind_size   uint }
447     { export_off       uint }
448     { export_size      uint } ;
449
450 CONSTANT: REBASE_TYPE_POINTER                     1
451 CONSTANT: REBASE_TYPE_TEXT_ABSOLUTE32             2
452 CONSTANT: REBASE_TYPE_TEXT_PCREL32                3
453
454 CONSTANT: REBASE_OPCODE_MASK                                  HEX: F0
455 CONSTANT: REBASE_IMMEDIATE_MASK                               HEX: 0F
456 CONSTANT: REBASE_OPCODE_DONE                                  HEX: 00
457 CONSTANT: REBASE_OPCODE_SET_TYPE_IMM                          HEX: 10
458 CONSTANT: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB           HEX: 20
459 CONSTANT: REBASE_OPCODE_ADD_ADDR_ULEB                         HEX: 30
460 CONSTANT: REBASE_OPCODE_ADD_ADDR_IMM_SCALED                   HEX: 40
461 CONSTANT: REBASE_OPCODE_DO_REBASE_IMM_TIMES                   HEX: 50
462 CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES                  HEX: 60
463 CONSTANT: REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB               HEX: 70
464 CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB    HEX: 80
465
466 CONSTANT: BIND_TYPE_POINTER                       1
467 CONSTANT: BIND_TYPE_TEXT_ABSOLUTE32               2
468 CONSTANT: BIND_TYPE_TEXT_PCREL32                  3
469
470 CONSTANT: BIND_SPECIAL_DYLIB_SELF                     0
471 CONSTANT: BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE          -1
472 CONSTANT: BIND_SPECIAL_DYLIB_FLAT_LOOKUP              -2
473
474 CONSTANT: BIND_SYMBOL_FLAGS_WEAK_IMPORT                   HEX: 1
475 CONSTANT: BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION           HEX: 8
476
477 CONSTANT: BIND_OPCODE_MASK                                    HEX: F0
478 CONSTANT: BIND_IMMEDIATE_MASK                                 HEX: 0F
479 CONSTANT: BIND_OPCODE_DONE                                    HEX: 00
480 CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM                   HEX: 10
481 CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB                  HEX: 20
482 CONSTANT: BIND_OPCODE_SET_DYLIB_SPECIAL_IMM                   HEX: 30
483 CONSTANT: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM           HEX: 40
484 CONSTANT: BIND_OPCODE_SET_TYPE_IMM                            HEX: 50
485 CONSTANT: BIND_OPCODE_SET_ADDEND_SLEB                         HEX: 60
486 CONSTANT: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB             HEX: 70
487 CONSTANT: BIND_OPCODE_ADD_ADDR_ULEB                           HEX: 80
488 CONSTANT: BIND_OPCODE_DO_BIND                                 HEX: 90
489 CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB                   HEX: A0
490 CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED             HEX: B0
491 CONSTANT: BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB        HEX: C0
492
493 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_MASK                   HEX: 03
494 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_REGULAR                HEX: 00
495 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL           HEX: 01
496 CONSTANT: EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION             HEX: 04
497 CONSTANT: EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION         HEX: 08
498 CONSTANT: EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS         HEX: 10
499
500 STRUCT: symseg_command
501     { cmd        uint }
502     { cmdsize    uint }
503     { offset     uint }
504     { size       uint } ;
505
506 STRUCT: ident_command
507     { cmd     uint }
508     { cmdsize uint } ;
509
510 STRUCT: fvmfile_command
511     { cmd            uint     }
512     { cmdsize        uint     }
513     { name           lc_str   }
514     { header_addr    uint     } ;
515
516 ! machine.h
517 CONSTANT: CPU_STATE_MAX       4
518 CONSTANT: CPU_STATE_USER      0
519 CONSTANT: CPU_STATE_SYSTEM    1
520 CONSTANT: CPU_STATE_IDLE      2
521 CONSTANT: CPU_STATE_NICE      3
522
523 CONSTANT: CPU_ARCH_MASK   HEX: ff000000
524 CONSTANT: CPU_ARCH_ABI64  HEX: 01000000
525
526 CONSTANT: CPU_TYPE_ANY            -1
527 CONSTANT: CPU_TYPE_VAX            1
528 CONSTANT: CPU_TYPE_MC680x0        6
529 CONSTANT: CPU_TYPE_X86            7
530 ALIAS: CPU_TYPE_I386              CPU_TYPE_X86
531 CONSTANT: CPU_TYPE_X86_64         flags{ CPU_TYPE_X86 CPU_ARCH_ABI64 }
532 CONSTANT: CPU_TYPE_MC98000        10
533 CONSTANT: CPU_TYPE_HPPA           11
534 CONSTANT: CPU_TYPE_ARM            12
535 CONSTANT: CPU_TYPE_MC88000        13
536 CONSTANT: CPU_TYPE_SPARC          14
537 CONSTANT: CPU_TYPE_I860           15
538 CONSTANT: CPU_TYPE_POWERPC        18
539 CONSTANT: CPU_TYPE_POWERPC64      flags{ CPU_TYPE_POWERPC CPU_ARCH_ABI64 }
540
541 CONSTANT: CPU_SUBTYPE_MASK    HEX: ff000000
542 CONSTANT: CPU_SUBTYPE_LIB64   HEX: 80000000
543
544 CONSTANT: CPU_SUBTYPE_MULTIPLE        -1
545 CONSTANT: CPU_SUBTYPE_LITTLE_ENDIAN   0
546 CONSTANT: CPU_SUBTYPE_BIG_ENDIAN      1
547
548 CONSTANT: CPU_THREADTYPE_NONE     0
549
550 CONSTANT: CPU_SUBTYPE_VAX_ALL 0
551 CONSTANT: CPU_SUBTYPE_VAX780  1
552 CONSTANT: CPU_SUBTYPE_VAX785  2
553 CONSTANT: CPU_SUBTYPE_VAX750  3
554 CONSTANT: CPU_SUBTYPE_VAX730  4
555 CONSTANT: CPU_SUBTYPE_UVAXI   5
556 CONSTANT: CPU_SUBTYPE_UVAXII  6
557 CONSTANT: CPU_SUBTYPE_VAX8200 7
558 CONSTANT: CPU_SUBTYPE_VAX8500 8
559 CONSTANT: CPU_SUBTYPE_VAX8600 9
560 CONSTANT: CPU_SUBTYPE_VAX8650 10
561 CONSTANT: CPU_SUBTYPE_VAX8800 11
562 CONSTANT: CPU_SUBTYPE_UVAXIII 12
563
564 CONSTANT: CPU_SUBTYPE_MC680x0_ALL     1
565 CONSTANT: CPU_SUBTYPE_MC68030     1
566 CONSTANT: CPU_SUBTYPE_MC68040     2
567 CONSTANT: CPU_SUBTYPE_MC68030_ONLY    3
568
569 : CPU_SUBTYPE_INTEL ( f m -- subtype ) 4 shift + ; inline
570
571 CONSTANT: CPU_SUBTYPE_I386_ALL              3
572 CONSTANT: CPU_SUBTYPE_386                   3
573 CONSTANT: CPU_SUBTYPE_486                   4
574 CONSTANT: CPU_SUBTYPE_486SX                 132
575 CONSTANT: CPU_SUBTYPE_586                   5
576 CONSTANT: CPU_SUBTYPE_PENT                  5
577 CONSTANT: CPU_SUBTYPE_PENTPRO               22
578 CONSTANT: CPU_SUBTYPE_PENTII_M3             54
579 CONSTANT: CPU_SUBTYPE_PENTII_M5             86
580 CONSTANT: CPU_SUBTYPE_CELERON               103
581 CONSTANT: CPU_SUBTYPE_CELERON_MOBILE        119
582 CONSTANT: CPU_SUBTYPE_PENTIUM_3             8
583 CONSTANT: CPU_SUBTYPE_PENTIUM_3_M           24
584 CONSTANT: CPU_SUBTYPE_PENTIUM_3_XEON        40
585 CONSTANT: CPU_SUBTYPE_PENTIUM_M             9
586 CONSTANT: CPU_SUBTYPE_PENTIUM_4             10
587 CONSTANT: CPU_SUBTYPE_PENTIUM_4_M           26
588 CONSTANT: CPU_SUBTYPE_ITANIUM               11
589 CONSTANT: CPU_SUBTYPE_ITANIUM_2             27
590 CONSTANT: CPU_SUBTYPE_XEON                  12
591 CONSTANT: CPU_SUBTYPE_XEON_MP               28
592
593 : CPU_SUBTYPE_INTEL_FAMILY ( x -- family ) 15 bitand ; inline
594
595 CONSTANT: CPU_SUBTYPE_INTEL_FAMILY_MAX    15
596
597 : CPU_SUBTYPE_INTEL_MODEL ( x -- model ) -4 shift ; inline
598
599 CONSTANT: CPU_SUBTYPE_INTEL_MODEL_ALL 0
600 CONSTANT: CPU_SUBTYPE_X86_ALL         3
601 CONSTANT: CPU_SUBTYPE_X86_64_ALL      3
602 CONSTANT: CPU_SUBTYPE_X86_ARCH1       4
603 CONSTANT: CPU_THREADTYPE_INTEL_HTT    1
604
605 CONSTANT: CPU_SUBTYPE_MIPS_ALL    0
606 CONSTANT: CPU_SUBTYPE_MIPS_R2300  1
607 CONSTANT: CPU_SUBTYPE_MIPS_R2600  2
608 CONSTANT: CPU_SUBTYPE_MIPS_R2800  3
609 CONSTANT: CPU_SUBTYPE_MIPS_R2000a 4
610 CONSTANT: CPU_SUBTYPE_MIPS_R2000  5
611 CONSTANT: CPU_SUBTYPE_MIPS_R3000a 6
612 CONSTANT: CPU_SUBTYPE_MIPS_R3000  7
613
614 CONSTANT: CPU_SUBTYPE_MC98000_ALL 0
615 CONSTANT: CPU_SUBTYPE_MC98601     1
616
617 CONSTANT: CPU_SUBTYPE_HPPA_ALL        0
618 CONSTANT: CPU_SUBTYPE_HPPA_7100       0
619 CONSTANT: CPU_SUBTYPE_HPPA_7100LC     1
620
621 CONSTANT: CPU_SUBTYPE_MC88000_ALL 0
622 CONSTANT: CPU_SUBTYPE_MC88100     1
623 CONSTANT: CPU_SUBTYPE_MC88110     2
624
625 CONSTANT: CPU_SUBTYPE_SPARC_ALL       0
626
627 CONSTANT: CPU_SUBTYPE_I860_ALL    0
628 CONSTANT: CPU_SUBTYPE_I860_860    1
629
630 CONSTANT: CPU_SUBTYPE_POWERPC_ALL     0
631 CONSTANT: CPU_SUBTYPE_POWERPC_601     1
632 CONSTANT: CPU_SUBTYPE_POWERPC_602     2
633 CONSTANT: CPU_SUBTYPE_POWERPC_603     3
634 CONSTANT: CPU_SUBTYPE_POWERPC_603e    4
635 CONSTANT: CPU_SUBTYPE_POWERPC_603ev   5
636 CONSTANT: CPU_SUBTYPE_POWERPC_604     6
637 CONSTANT: CPU_SUBTYPE_POWERPC_604e    7
638 CONSTANT: CPU_SUBTYPE_POWERPC_620     8
639 CONSTANT: CPU_SUBTYPE_POWERPC_750     9
640 CONSTANT: CPU_SUBTYPE_POWERPC_7400    10
641 CONSTANT: CPU_SUBTYPE_POWERPC_7450    11
642 CONSTANT: CPU_SUBTYPE_POWERPC_970     100
643
644 CONSTANT: CPU_SUBTYPE_ARM_ALL             0
645 CONSTANT: CPU_SUBTYPE_ARM_V4T             5
646 CONSTANT: CPU_SUBTYPE_ARM_V6              6
647 CONSTANT: CPU_SUBTYPE_ARM_V5TEJ           7
648 CONSTANT: CPU_SUBTYPE_ARM_XSCALE          8
649 CONSTANT: CPU_SUBTYPE_ARM_V7              9
650
651 CONSTANT: CPUFAMILY_UNKNOWN    0
652 CONSTANT: CPUFAMILY_POWERPC_G3 HEX: cee41549
653 CONSTANT: CPUFAMILY_POWERPC_G4 HEX: 77c184ae
654 CONSTANT: CPUFAMILY_POWERPC_G5 HEX: ed76d8aa
655 CONSTANT: CPUFAMILY_INTEL_6_13 HEX: aa33392b
656 CONSTANT: CPUFAMILY_INTEL_6_14 HEX: 73d67300
657 CONSTANT: CPUFAMILY_INTEL_6_15 HEX: 426f69ef
658 CONSTANT: CPUFAMILY_INTEL_6_23 HEX: 78ea4fbc
659 CONSTANT: CPUFAMILY_INTEL_6_26 HEX: 6b5a4cd2
660 CONSTANT: CPUFAMILY_ARM_9      HEX: e73283ae
661 CONSTANT: CPUFAMILY_ARM_11     HEX: 8ff620d8
662 CONSTANT: CPUFAMILY_ARM_XSCALE HEX: 53b005f5
663 CONSTANT: CPUFAMILY_ARM_13     HEX: 0cc90e64
664
665 ALIAS: CPUFAMILY_INTEL_YONAH   CPUFAMILY_INTEL_6_14
666 ALIAS: CPUFAMILY_INTEL_MEROM   CPUFAMILY_INTEL_6_15
667 ALIAS: CPUFAMILY_INTEL_PENRYN  CPUFAMILY_INTEL_6_23
668 ALIAS: CPUFAMILY_INTEL_NEHALEM CPUFAMILY_INTEL_6_26
669
670 ALIAS: CPUFAMILY_INTEL_CORE    CPUFAMILY_INTEL_6_14
671 ALIAS: CPUFAMILY_INTEL_CORE2   CPUFAMILY_INTEL_6_15
672
673 ! fat.h
674 CONSTANT: FAT_MAGIC HEX: cafebabe
675 CONSTANT: FAT_CIGAM HEX: bebafeca
676
677 STRUCT: fat_header
678     { magic        uint }
679     { nfat_arch    uint } ;
680
681 STRUCT: fat_arch
682     { cputype      cpu_type_t    }
683     { cpusubtype   cpu_subtype_t }
684     { offset       uint          }
685     { size         uint          }
686     { align        uint          } ;
687
688 ! nlist.h
689 STRUCT: nlist
690     { n_strx  int      }
691     { n_type  uchar    }
692     { n_sect  uchar    }
693     { n_desc  short    }
694     { n_value uint     } ;
695
696 STRUCT: nlist_64
697     { n_strx  uint      }
698     { n_type  uchar     }
699     { n_sect  uchar     }
700     { n_desc  ushort    }
701     { n_value ulonglong } ;
702
703 CONSTANT: N_STAB  HEX: e0
704 CONSTANT: N_PEXT  HEX: 10
705 CONSTANT: N_TYPE  HEX: 0e
706 CONSTANT: N_EXT   HEX: 01
707
708 CONSTANT: N_UNDF  HEX: 0
709 CONSTANT: N_ABS   HEX: 2
710 CONSTANT: N_SECT  HEX: e
711 CONSTANT: N_PBUD  HEX: c
712 CONSTANT: N_INDR  HEX: a
713
714 CONSTANT: NO_SECT     0
715 CONSTANT: MAX_SECT    255
716
717 : GET_COMM_ALIGN ( n_desc -- align )
718     -8 shift HEX: 0f bitand ; inline
719
720 : SET_COMM_ALIGN ( n_desc align -- n_desc )
721     [ HEX: f0ff bitand ]
722     [ HEX: 000f bitand 8 shift ] bi* bitor ; inline
723
724 CONSTANT: REFERENCE_TYPE                              7
725 CONSTANT: REFERENCE_FLAG_UNDEFINED_NON_LAZY           0
726 CONSTANT: REFERENCE_FLAG_UNDEFINED_LAZY               1
727 CONSTANT: REFERENCE_FLAG_DEFINED                      2
728 CONSTANT: REFERENCE_FLAG_PRIVATE_DEFINED              3
729 CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY   4
730 CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY       5
731
732 CONSTANT: REFERENCED_DYNAMICALLY  HEX: 0010
733
734 : GET_LIBRARY_ORDINAL ( n_desc -- ordinal )
735     -8 shift HEX: ff bitand ; inline
736
737 : SET_LIBRARY_ORDINAL ( n_desc ordinal -- n_desc )
738     [ HEX: 00ff bitand ]
739     [ HEX: 00ff bitand 8 shift ] bi* bitor ; inline
740
741 CONSTANT: SELF_LIBRARY_ORDINAL   HEX: 0
742 CONSTANT: MAX_LIBRARY_ORDINAL    HEX: fd
743 CONSTANT: DYNAMIC_LOOKUP_ORDINAL HEX: fe
744 CONSTANT: EXECUTABLE_ORDINAL     HEX: ff
745
746 CONSTANT: N_NO_DEAD_STRIP  HEX: 0020
747 CONSTANT: N_DESC_DISCARDED HEX: 0020
748 CONSTANT: N_WEAK_REF       HEX: 0040
749 CONSTANT: N_WEAK_DEF       HEX: 0080
750 CONSTANT: N_REF_TO_WEAK    HEX: 0080
751 CONSTANT: N_ARM_THUMB_DEF  HEX: 0008
752
753 ! ranlib.h
754 CONSTANT: SYMDEF        "__.SYMDEF"
755 CONSTANT: SYMDEF_SORTED "__.SYMDEF SORTED"
756
757 STRUCT: ranlib
758     { ran_strx uint }
759     { ran_off  uint } ;
760
761 ! reloc.h
762 STRUCT: relocation_info
763     { r_address                            int  }
764     { r_symbolnum_pcrel_length_extern_type uint } ;
765
766 CONSTANT: R_ABS   0
767 CONSTANT: R_SCATTERED HEX: 80000000
768
769 STRUCT: scattered_relocation_info_big_endian
770     { r_scattered_pcrel_length_type_address  uint }
771     { r_value                                int  } ;
772
773 STRUCT: scattered_relocation_info_little_endian
774     { r_address_type_length_pcrel_scattered uint }
775     { r_value                               int  } ;
776
777 C-ENUM: reloc_type_generic
778     GENERIC_RELOC_VANILLA
779     GENERIC_RELOC_PAIR
780     GENERIC_RELOC_SECTDIFF
781     GENERIC_RELOC_PB_LA_PTR
782     GENERIC_RELOC_LOCAL_SECTDIFF ;
783
784 C-ENUM: reloc_type_x86_64
785     X86_64_RELOC_UNSIGNED
786     X86_64_RELOC_SIGNED
787     X86_64_RELOC_BRANCH
788     X86_64_RELOC_GOT_LOAD
789     X86_64_RELOC_GOT
790     X86_64_RELOC_SUBTRACTOR
791     X86_64_RELOC_SIGNED_1
792     X86_64_RELOC_SIGNED_2
793     X86_64_RELOC_SIGNED_4 ;
794
795 C-ENUM: reloc_type_ppc
796     PPC_RELOC_VANILLA
797     PPC_RELOC_PAIR
798     PPC_RELOC_BR14
799     PPC_RELOC_BR24
800     PPC_RELOC_HI16
801     PPC_RELOC_LO16
802     PPC_RELOC_HA16
803     PPC_RELOC_LO14
804     PPC_RELOC_SECTDIFF
805     PPC_RELOC_PB_LA_PTR
806     PPC_RELOC_HI16_SECTDIFF
807     PPC_RELOC_LO16_SECTDIFF
808     PPC_RELOC_HA16_SECTDIFF
809     PPC_RELOC_JBSR
810     PPC_RELOC_LO14_SECTDIFF
811     PPC_RELOC_LOCAL_SECTDIFF ;
812
813 ! Low-level interface
814 SPECIALIZED-ARRAYS: section section_64 nlist nlist_64 ;
815 UNION: mach_header_32/64 mach_header mach_header_64 ;
816 UNION: segment_command_32/64 segment_command segment_command_64 ;
817 UNION: load-command segment_command segment_command_64
818     dylib_command sub_framework_command
819     sub_client_command sub_umbrella_command sub_library_command
820     prebound_dylib_command dylinker_command thread_command
821     routines_command routines_command_64 symtab_command
822     dysymtab_command twolevel_hints_command uuid_command ;
823 UNION: section_32/64 section section_64 ;
824 UNION: section_32/64-array section-array section_64-array ;
825 UNION: nlist_32/64 nlist nlist_64 ;
826 UNION: nlist_32/64-array nlist-array nlist_64-array ;
827
828 TYPED: 64-bit? ( macho: mach_header_32/64 -- ? )
829     magic>> {
830         { MH_MAGIC_64 [ t ] }
831         { MH_CIGAM_64 [ t ] }
832         [ drop f ]
833     } case ;
834
835 TYPED: macho-header ( c-ptr -- macho: mach_header_32/64 )
836     dup mach_header_64 memory>struct 64-bit?
837     [ mach_header_64 memory>struct ]
838     [ mach_header memory>struct ] if ;
839
840 : cmd>load-command ( cmd -- load-command )
841     {
842         { LC_UUID           [ uuid_command           ] }
843         { LC_SEGMENT        [ segment_command        ] }
844         { LC_SEGMENT_64     [ segment_command_64     ] }
845         { LC_SYMTAB         [ symtab_command         ] }
846         { LC_DYSYMTAB       [ dysymtab_command       ] }
847         { LC_THREAD         [ thread_command         ] }
848         { LC_UNIXTHREAD     [ thread_command         ] }
849         { LC_LOAD_DYLIB     [ dylib_command          ] }
850         { LC_ID_DYLIB       [ dylib_command          ] }
851         { LC_PREBOUND_DYLIB [ prebound_dylib_command ] }
852         { LC_LOAD_DYLINKER  [ dylinker_command       ] }
853         { LC_ID_DYLINKER    [ dylinker_command       ] }
854         { LC_ROUTINES       [ routines_command       ] }
855         { LC_ROUTINES_64    [ routines_command_64    ] }
856         { LC_TWOLEVEL_HINTS [ twolevel_hints_command ] }
857         { LC_SUB_FRAMEWORK  [ sub_framework_command  ] }
858         { LC_SUB_UMBRELLA   [ sub_umbrella_command   ] }
859         { LC_SUB_LIBRARY    [ sub_library_command    ] }
860         { LC_SUB_CLIENT     [ sub_client_command     ] }
861         { LC_DYLD_INFO      [ dyld_info_command      ] }
862         { LC_DYLD_INFO_ONLY [ dyld_info_command      ] }
863     } case ;
864
865 : read-command ( cmd -- next-cmd )
866     dup load_command memory>struct
867     [ cmd>> cmd>load-command memory>struct , ]
868     [ cmdsize>> swap <displaced-alien> ] 2bi ;
869
870 TYPED: load-commands ( macho: mach_header_32/64 -- load-commands )
871     [
872         [ class heap-size ]
873         [ >c-ptr <displaced-alien> ]
874         [ ncmds>> ] tri iota [
875             drop read-command
876         ] each drop
877     ] { } make ;
878
879 : segment-commands ( load-commands -- segment-commands )
880     [ segment_command_32/64? ] filter ; inline
881
882 : symtab-commands ( load-commands -- segment-commands )
883     [ symtab_command? ] filter ; inline
884
885 : read-array-string ( uchar-array -- string )
886     ascii decode [ 0 = not ] filter ;
887
888 : segment-sections ( segment-command -- sections )
889     {
890         [ class heap-size ]
891         [ >c-ptr <displaced-alien> ]
892         [ nsects>> ]
893         [ segment_command_64? ]
894     } cleave
895     [ <direct-section_64-array> ]
896     [ <direct-section-array> ] if ;
897
898 : sections-array ( segment-commands -- sections-array )
899     [
900         dup first segment_command_64?
901         [ section_64 ] [ section ] if <struct> ,
902         segment-commands [ segment-sections [ , ] each ] each
903     ] { } make ;
904
905 : symbols ( mach-header symtab-command -- symbols string-table )
906     [ symoff>> swap >c-ptr <displaced-alien> ]
907     [ nsyms>> swap 64-bit?
908       [ <direct-nlist_64-array> ]
909       [ <direct-nlist-array> ] if ]
910     [ stroff>> swap >c-ptr <displaced-alien> ] 2tri ;
911     
912 : symbol-name ( symbol string-table -- name )
913     [ n_strx>> ] dip <displaced-alien> ascii alien>string ;
914
915 : with-mapped-macho ( path quot -- )
916     '[
917         address>> macho-header @
918     ] with-mapped-file ; inline
919
920 : macho-nm ( path -- )
921     [| macho |
922         macho load-commands segment-commands sections-array :> sections
923         
924         macho load-commands symtab-commands [| symtab |
925             macho symtab symbols [
926                 [ drop n_value>> "%016x " printf ]
927                 [ drop n_sect>> sections nth sectname>>
928                   read-array-string "%-16s" printf ]
929                 [ symbol-name "%s\n" printf ] 2tri
930             ] curry each
931         ] each
932     ] with-mapped-macho ;