]> gitweb.factorcode.org Git - factor.git/blob - extra/macho/macho.factor
scryfall: better moxfield words
[factor.git] / extra / macho / macho.factor
1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.data alien.strings
4 alien.syntax classes classes.struct combinators
5 combinators.short-circuit io.encodings.ascii io.encodings.string
6 kernel literals make math sequences specialized-arrays typed
7 io.mmap formatting splitting endian ;
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        0x00
18 CONSTANT: VM_PROT_READ        0x01
19 CONSTANT: VM_PROT_WRITE       0x02
20 CONSTANT: VM_PROT_EXECUTE     0x04
21 CONSTANT: VM_PROT_DEFAULT     0x03
22 CONSTANT: VM_PROT_ALL         0x07
23 CONSTANT: VM_PROT_NO_CHANGE   0x08
24 CONSTANT: VM_PROT_COPY        0x10
25 CONSTANT: VM_PROT_WANTS_COPY  0x10
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    0xfeedface
38 CONSTANT: MH_CIGAM    0xcefaedfe
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 0xfeedfacf
51 CONSTANT: MH_CIGAM_64 0xcffaedfe
52
53 CONSTANT: MH_OBJECT       0x1
54 CONSTANT: MH_EXECUTE      0x2
55 CONSTANT: MH_FVMLIB       0x3
56 CONSTANT: MH_CORE         0x4
57 CONSTANT: MH_PRELOAD      0x5
58 CONSTANT: MH_DYLIB        0x6
59 CONSTANT: MH_DYLINKER     0x7
60 CONSTANT: MH_BUNDLE       0x8
61 CONSTANT: MH_DYLIB_STUB   0x9
62 CONSTANT: MH_DSYM         0xa
63 CONSTANT: MH_KEXT_BUNDLE  0xb
64 CONSTANT: MH_FILESET      0xc
65 CONSTANT: MH_GPU_EXECUTE  0xd
66 CONSTANT: MH_GPU_DYLIB    0xe
67
68 CONSTANT: MH_NOUNDEFS                0x1
69 CONSTANT: MH_INCRLINK                0x2
70 CONSTANT: MH_DYLDLINK                0x4
71 CONSTANT: MH_BINDATLOAD              0x8
72 CONSTANT: MH_PREBOUND                0x10
73 CONSTANT: MH_SPLIT_SEGS              0x20
74 CONSTANT: MH_LAZY_INIT               0x40
75 CONSTANT: MH_TWOLEVEL                0x80
76 CONSTANT: MH_FORCE_FLAT              0x100
77 CONSTANT: MH_NOMULTIDEFS             0x200
78 CONSTANT: MH_NOFIXPREBINDING         0x400
79 CONSTANT: MH_PREBINDABLE             0x800
80 CONSTANT: MH_ALLMODSBOUND            0x1000
81 CONSTANT: MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
82 CONSTANT: MH_CANONICAL               0x4000
83 CONSTANT: MH_WEAK_DEFINES            0x8000
84 CONSTANT: MH_BINDS_TO_WEAK           0x10000
85 CONSTANT: MH_ALLOW_STACK_EXECUTION   0x20000
86 CONSTANT: MH_ROOT_SAFE               0x40000
87 CONSTANT: MH_SETUID_SAFE             0x80000
88 CONSTANT: MH_NO_REEXPORTED_DYLIBS    0x100000
89 CONSTANT: MH_PIE                     0x200000
90 CONSTANT: MH_DEAD_STRIPPABLE_DYLIB   0x400000
91 CONSTANT: MH_HAS_TLV_DESCRIPTORS     0x800000
92 CONSTANT: MH_NO_HEAP_EXECUTION       0x1000000
93 CONSTANT: MH_APP_EXTENSION_SAFE      0x2000000
94 CONSTANT: MH_NLIST_OUTOFSYNC_WITH_DYLDINFO 0x4000000
95 CONSTANT: MH_SIM_SUPPORT             0x8000000
96 CONSTANT: MH_DYLIB_IN_CACHE          0x80000000
97
98 STRUCT: load_command
99     { cmd     uint }
100     { cmdsize uint } ;
101
102 CONSTANT: LC_REQ_DYLD 0x80000000
103
104 CONSTANT: LC_SEGMENT             0x1
105 CONSTANT: LC_SYMTAB              0x2
106 CONSTANT: LC_SYMSEG              0x3
107 CONSTANT: LC_THREAD              0x4
108 CONSTANT: LC_UNIXTHREAD          0x5
109 CONSTANT: LC_LOADFVMLIB          0x6
110 CONSTANT: LC_IDFVMLIB            0x7
111 CONSTANT: LC_IDENT               0x8
112 CONSTANT: LC_FVMFILE             0x9
113 CONSTANT: LC_PREPAGE             0xa
114 CONSTANT: LC_DYSYMTAB            0xb
115 CONSTANT: LC_LOAD_DYLIB          0xc
116 CONSTANT: LC_ID_DYLIB            0xd
117 CONSTANT: LC_LOAD_DYLINKER       0xe
118 CONSTANT: LC_ID_DYLINKER         0xf
119 CONSTANT: LC_PREBOUND_DYLIB      0x10
120 CONSTANT: LC_ROUTINES            0x11
121 CONSTANT: LC_SUB_FRAMEWORK       0x12
122 CONSTANT: LC_SUB_UMBRELLA        0x13
123 CONSTANT: LC_SUB_CLIENT          0x14
124 CONSTANT: LC_SUB_LIBRARY         0x15
125 CONSTANT: LC_TWOLEVEL_HINTS      0x16
126 CONSTANT: LC_PREBIND_CKSUM       0x17
127 CONSTANT: LC_LOAD_WEAK_DYLIB     0x80000018
128 CONSTANT: LC_SEGMENT_64          0x19
129 CONSTANT: LC_ROUTINES_64         0x1a
130 CONSTANT: LC_UUID                0x1b
131 CONSTANT: LC_RPATH               0x8000001c
132 CONSTANT: LC_CODE_SIGNATURE      0x1d
133 CONSTANT: LC_SEGMENT_SPLIT_INFO  0x1e
134 CONSTANT: LC_REEXPORT_DYLIB      0x8000001f
135 CONSTANT: LC_LAZY_LOAD_DYLIB     0x20
136 CONSTANT: LC_ENCRYPTION_INFO     0x21
137 CONSTANT: LC_DYLD_INFO           0x22
138 CONSTANT: LC_DYLD_INFO_ONLY      0x80000022
139 CONSTANT: LC_LOAD_UPWARD_DYLIB   0x80000023
140 CONSTANT: LC_VERSION_MIN_MACOSX  0x24
141 CONSTANT: LC_VERSION_MIN_IPHONEOS 0x25
142 CONSTANT: LC_FUNCTION_STARTS     0x26
143 CONSTANT: LC_DYLD_ENVIRONMENT    0x27
144 CONSTANT: LC_MAIN                0x80000028
145 CONSTANT: LC_DATA_IN_CODE        0x29
146 CONSTANT: LC_SOURCE_VERSION      0x2A
147 CONSTANT: LC_DYLIB_CODE_SIGN_DRS 0x2B
148 CONSTANT: LC_ENCRYPTION_INFO_64  0x2C
149 CONSTANT: LC_LINKER_OPTION       0x2D
150 CONSTANT: LC_LINKER_OPTIMIZATION_HINT 0x2E
151 CONSTANT: LC_VERSION_MIN_TVOS    0x2F
152 CONSTANT: LC_VERSION_MIN_WATCHOS 0x30
153 CONSTANT: LC_NOTE                0x31
154 CONSTANT: LC_BUILD_VERSION       0x32
155 CONSTANT: LC_DYLD_EXPORTS_TRIE   0x80000033
156 CONSTANT: LC_DYLD_CHAINED_FIXUPS 0x80000034
157 CONSTANT: LC_FILESET_ENTRY       0x80000035
158 CONSTANT: LC_ATOM_INFO           0x36
159
160 UNION-STRUCT: lc_str
161     { offset    uint     }
162     { ptr       char*    } ;
163
164 STRUCT: segment_command
165     { cmd            uint      }
166     { cmdsize        uint      }
167     { segname        char[16]  }
168     { vmaddr         uint      }
169     { vmsize         uint      }
170     { fileoff        uint      }
171     { filesize       uint      }
172     { maxprot        vm_prot_t }
173     { initprot       vm_prot_t }
174     { nsects         uint      }
175     { flags          uint      } ;
176
177 STRUCT: segment_command_64
178     { cmd            uint       }
179     { cmdsize        uint       }
180     { segname        char[16]   }
181     { vmaddr         ulonglong  }
182     { vmsize         ulonglong  }
183     { fileoff        ulonglong  }
184     { filesize       ulonglong  }
185     { maxprot        vm_prot_t  }
186     { initprot       vm_prot_t  }
187     { nsects         uint       }
188     { flags          uint       } ;
189
190 CONSTANT: SG_HIGHVM               0x1
191 CONSTANT: SG_FVMLIB               0x2
192 CONSTANT: SG_NORELOC              0x4
193 CONSTANT: SG_PROTECTED_VERSION_1  0x8
194 CONSTANT: SG_READ_ONLY            0x10
195
196 STRUCT: section
197     { sectname        char[16] }
198     { segname         char[16] }
199     { addr            uint     }
200     { size            uint     }
201     { offset          uint     }
202     { align           uint     }
203     { reloff          uint     }
204     { nreloc          uint     }
205     { flags           uint     }
206     { reserved1       uint     }
207     { reserved2       uint     } ;
208
209 STRUCT: section_64
210     { sectname        char[16]  }
211     { segname         char[16]  }
212     { addr            ulonglong }
213     { size            ulonglong }
214     { offset          uint      }
215     { align           uint      }
216     { reloff          uint      }
217     { nreloc          uint      }
218     { flags           uint      }
219     { reserved1       uint      }
220     { reserved2       uint      }
221     { reserved3       uint      } ;
222
223 CONSTANT: SECTION_TYPE         0x000000ff
224 CONSTANT: SECTION_ATTRIBUTES   0xffffff00
225
226 CONSTANT: S_REGULAR                       0x0
227 CONSTANT: S_ZEROFILL                      0x1
228 CONSTANT: S_CSTRING_LITERALS              0x2
229 CONSTANT: S_4BYTE_LITERALS                0x3
230 CONSTANT: S_8BYTE_LITERALS                0x4
231 CONSTANT: S_LITERAL_POINTERS              0x5
232 CONSTANT: S_NON_LAZY_SYMBOL_POINTERS      0x6
233 CONSTANT: S_LAZY_SYMBOL_POINTERS          0x7
234 CONSTANT: S_SYMBOL_STUBS                  0x8
235 CONSTANT: S_MOD_INIT_FUNC_POINTERS        0x9
236 CONSTANT: S_MOD_TERM_FUNC_POINTERS        0xa
237 CONSTANT: S_COALESCED                     0xb
238 CONSTANT: S_GB_ZEROFILL                   0xc
239 CONSTANT: S_INTERPOSING                   0xd
240 CONSTANT: S_16BYTE_LITERALS               0xe
241 CONSTANT: S_DTRACE_DOF                    0xf
242 CONSTANT: S_LAZY_DYLIB_SYMBOL_POINTERS    0x10
243 CONSTANT: S_THREAD_LOCAL_REGULAR          0x11
244 CONSTANT: S_THREAD_LOCAL_ZEROFILL         0x12
245 CONSTANT: S_THREAD_LOCAL_VARIABLES        0x13
246 CONSTANT: S_THREAD_LOCAL_VARIABLE_POINTERS 0x14
247 CONSTANT: S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15
248 CONSTANT: S_INIT_FUNC_OFFSETS             0x16
249
250 CONSTANT: SECTION_ATTRIBUTES_USR     0xff000000
251 CONSTANT: S_ATTR_PURE_INSTRUCTIONS   0x80000000
252 CONSTANT: S_ATTR_NO_TOC              0x40000000
253 CONSTANT: S_ATTR_STRIP_STATIC_SYMS   0x20000000
254 CONSTANT: S_ATTR_NO_DEAD_STRIP       0x10000000
255 CONSTANT: S_ATTR_LIVE_SUPPORT        0x08000000
256 CONSTANT: S_ATTR_SELF_MODIFYING_CODE 0x04000000
257 CONSTANT: S_ATTR_DEBUG               0x02000000
258 CONSTANT: SECTION_ATTRIBUTES_SYS     0x00ffff00
259 CONSTANT: S_ATTR_SOME_INSTRUCTIONS   0x00000400
260 CONSTANT: S_ATTR_EXT_RELOC           0x00000200
261 CONSTANT: S_ATTR_LOC_RELOC           0x00000100
262
263 CONSTANT: SEG_PAGEZERO      "__PAGEZERO"
264 CONSTANT: SEG_TEXT          "__TEXT"
265 CONSTANT: SECT_TEXT         "__text"
266 CONSTANT: SECT_FVMLIB_INIT0 "__fvmlib_init0"
267 CONSTANT: SECT_FVMLIB_INIT1 "__fvmlib_init1"
268 CONSTANT: SEG_DATA          "__DATA"
269 CONSTANT: SECT_DATA         "__data"
270 CONSTANT: SECT_BSS          "__bss"
271 CONSTANT: SECT_COMMON       "__common"
272 CONSTANT: SEG_OBJC          "__OBJC"
273 CONSTANT: SECT_OBJC_SYMBOLS "__symbol_table"
274 CONSTANT: SECT_OBJC_MODULES "__module_info"
275 CONSTANT: SECT_OBJC_STRINGS "__selector_strs"
276 CONSTANT: SECT_OBJC_REFS    "__selector_refs"
277 CONSTANT: SEG_ICON          "__ICON"
278 CONSTANT: SECT_ICON_HEADER  "__header"
279 CONSTANT: SECT_ICON_TIFF    "__tiff"
280 CONSTANT: SEG_LINKEDIT      "__LINKEDIT"
281 CONSTANT: SEG_UNIXSTACK     "__UNIXSTACK"
282 CONSTANT: SEG_IMPORT        "__IMPORT"
283
284 STRUCT: fvmlib
285     { name             lc_str   }
286     { minor_version    uint     }
287     { header_addr      uint     } ;
288
289 STRUCT: fvmlib_command
290     { cmd        uint     }
291     { cmdsize    uint     }
292     { fvmlib     fvmlib   } ;
293
294 STRUCT: dylib
295     { name                  lc_str   }
296     { timestamp             uint     }
297     { current_version       uint     }
298     { compatibility_version uint     } ;
299
300 STRUCT: dylib_command
301     { cmd        uint     }
302     { cmdsize    uint     }
303     { dylib      dylib    } ;
304
305 STRUCT: sub_framework_command
306     { cmd         uint     }
307     { cmdsize     uint     }
308     { umbrella    lc_str   } ;
309
310 STRUCT: sub_client_command
311     { cmd        uint     }
312     { cmdsize    uint     }
313     { client     lc_str   } ;
314
315 STRUCT: sub_umbrella_command
316     { cmd             uint     }
317     { cmdsize         uint     }
318     { sub_umbrella    lc_str   } ;
319
320 STRUCT: sub_library_command
321     { cmd            uint     }
322     { cmdsize        uint     }
323     { sub_library    lc_str   } ;
324
325 STRUCT: prebound_dylib_command
326     { cmd               uint     }
327     { cmdsize           uint     }
328     { name              lc_str   }
329     { nmodules          uint     }
330     { linked_modules    lc_str   } ;
331
332 STRUCT: dylinker_command
333     { cmd        uint     }
334     { cmdsize    uint     }
335     { name       lc_str   } ;
336
337 STRUCT: thread_command
338     { cmd        uint }
339     { cmdsize    uint } ;
340
341 STRUCT: routines_command
342     { cmd             uint }
343     { cmdsize         uint }
344     { init_address    uint }
345     { init_module     uint }
346     { reserved1       uint }
347     { reserved2       uint }
348     { reserved3       uint }
349     { reserved4       uint }
350     { reserved5       uint }
351     { reserved6       uint } ;
352
353 STRUCT: routines_command_64
354     { cmd             uint      }
355     { cmdsize         uint      }
356     { init_address    ulonglong }
357     { init_module     ulonglong }
358     { reserved1       ulonglong }
359     { reserved2       ulonglong }
360     { reserved3       ulonglong }
361     { reserved4       ulonglong }
362     { reserved5       ulonglong }
363     { reserved6       ulonglong } ;
364
365 STRUCT: symtab_command
366     { cmd        uint }
367     { cmdsize    uint }
368     { symoff     uint }
369     { nsyms      uint }
370     { stroff     uint }
371     { strsize    uint } ;
372
373 STRUCT: dysymtab_command
374     { cmd            uint }
375     { cmdsize        uint }
376     { ilocalsym      uint }
377     { nlocalsym      uint }
378     { iextdefsym     uint }
379     { nextdefsym     uint }
380     { iundefsym      uint }
381     { nundefsym      uint }
382     { tocoff         uint }
383     { ntoc           uint }
384     { modtaboff      uint }
385     { nmodtab        uint }
386     { extrefsymoff   uint }
387     { nextrefsyms    uint }
388     { indirectsymoff uint }
389     { nindirectsyms  uint }
390     { extreloff      uint }
391     { nextrel        uint }
392     { locreloff      uint }
393     { nlocrel        uint } ;
394
395 CONSTANT: INDIRECT_SYMBOL_LOCAL 0x80000000
396 CONSTANT: INDIRECT_SYMBOL_ABS   0x40000000
397
398 STRUCT: dylib_table_of_contents
399     { symbol_index uint }
400     { module_index uint } ;
401
402 STRUCT: dylib_module
403     { module_name           uint }
404     { iextdefsym            uint }
405     { nextdefsym            uint }
406     { irefsym               uint }
407     { nrefsym               uint }
408     { ilocalsym             uint }
409     { nlocalsym             uint }
410     { iextrel               uint }
411     { nextrel               uint }
412     { iinit_iterm           uint }
413     { ninit_nterm           uint }
414     { objc_module_info_addr uint }
415     { objc_module_info_size uint } ;
416
417 STRUCT: dylib_module_64
418     { module_name           uint      }
419     { iextdefsym            uint      }
420     { nextdefsym            uint      }
421     { irefsym               uint      }
422     { nrefsym               uint      }
423     { ilocalsym             uint      }
424     { nlocalsym             uint      }
425     { iextrel               uint      }
426     { nextrel               uint      }
427     { iinit_iterm           uint      }
428     { ninit_nterm           uint      }
429     { objc_module_info_size uint      }
430     { objc_module_info_addr ulonglong } ;
431
432 STRUCT: dylib_reference
433     { isym_flags uint } ;
434
435 STRUCT: twolevel_hints_command
436     { cmd     uint }
437     { cmdsize uint }
438     { offset  uint }
439     { nhints  uint } ;
440
441 STRUCT: twolevel_hint
442     { isub_image_itoc uint } ;
443
444 STRUCT: prebind_cksum_command
445     { cmd     uint }
446     { cmdsize uint }
447     { cksum   uint } ;
448
449 STRUCT: uuid_command
450     { cmd        uint        }
451     { cmdsize    uint        }
452     { uuid       uchar[16]   } ;
453
454 STRUCT: rpath_command
455     { cmd         uint     }
456     { cmdsize     uint     }
457     { path        lc_str   } ;
458
459 STRUCT: linkedit_data_command
460     { cmd         uint }
461     { cmdsize     uint }
462     { dataoff     uint }
463     { datasize    uint } ;
464
465 STRUCT: encryption_info_command
466     { cmd       uint }
467     { cmdsize   uint }
468     { cryptoff  uint }
469     { cryptsize uint }
470     { cryptid   uint } ;
471
472 STRUCT: dyld_info_command
473     { cmd              uint }
474     { cmdsize          uint }
475     { rebase_off       uint }
476     { rebase_size      uint }
477     { bind_off         uint }
478     { bind_size        uint }
479     { weak_bind_off    uint }
480     { weak_bind_size   uint }
481     { lazy_bind_off    uint }
482     { lazy_bind_size   uint }
483     { export_off       uint }
484     { export_size      uint } ;
485
486 STRUCT: version_min_command
487     { cmd uint32_t }
488     { cmdsize uint32_t }
489     { version uint32_t }
490     { sdk uint32_t } ;
491
492 STRUCT: build_version_command
493     { cmd uint32_t }
494     { cmdsize uint32_t }
495     { platform uint32_t }
496     { minos uint32_t }
497     { sdk uint32_t }
498     { ntools uint32_t } ;
499
500 STRUCT: build_tool_version
501     { tool uint32_t }
502     { version uint32_t } ;
503
504 CONSTANT: PLATFORM_UNKNOWN                        0
505 CONSTANT: PLATFORM_ANY                            0xFFFFFFFF
506 CONSTANT: PLATFORM_MACOS                          1
507 CONSTANT: PLATFORM_IOS                            2
508 CONSTANT: PLATFORM_TVOS                           3
509 CONSTANT: PLATFORM_WATCHOS                        4
510 CONSTANT: PLATFORM_BRIDGEOS                       5
511 CONSTANT: PLATFORM_MACCATALYST                    6
512 CONSTANT: PLATFORM_IOSSIMULATOR                   7
513 CONSTANT: PLATFORM_TVOSSIMULATOR                  8
514 CONSTANT: PLATFORM_WATCHOSSIMULATOR               9
515 CONSTANT: PLATFORM_DRIVERKIT                      10
516 CONSTANT: PLATFORM_VISIONOS                       11
517 CONSTANT: PLATFORM_VISIONOSSIMULATOR              12
518 CONSTANT: PLATFORM_FIRMWARE                       13
519 CONSTANT: PLATFORM_SEPOS                          14
520
521 CONSTANT: TOOL_CLANG           1
522 CONSTANT: TOOL_SWIFT           2
523 CONSTANT: TOOL_LD              3
524 CONSTANT: TOOL_LLD             4
525 CONSTANT: TOOL_METAL           1024
526 CONSTANT: TOOL_AIRLLD          1025
527 CONSTANT: TOOL_AIRNT           1026
528 CONSTANT: TOOL_AIRNT_PLUGIN    1027
529 CONSTANT: TOOL_AIRPACK         1028
530 CONSTANT: TOOL_GPUARCHIVER     1031
531 CONSTANT: TOOL_METAL_FRAMEWORK 1032
532
533 CONSTANT: REBASE_TYPE_POINTER                     1
534 CONSTANT: REBASE_TYPE_TEXT_ABSOLUTE32             2
535 CONSTANT: REBASE_TYPE_TEXT_PCREL32                3
536
537 CONSTANT: REBASE_OPCODE_MASK                                  0xF0
538 CONSTANT: REBASE_IMMEDIATE_MASK                               0x0F
539 CONSTANT: REBASE_OPCODE_DONE                                  0x00
540 CONSTANT: REBASE_OPCODE_SET_TYPE_IMM                          0x10
541 CONSTANT: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB           0x20
542 CONSTANT: REBASE_OPCODE_ADD_ADDR_ULEB                         0x30
543 CONSTANT: REBASE_OPCODE_ADD_ADDR_IMM_SCALED                   0x40
544 CONSTANT: REBASE_OPCODE_DO_REBASE_IMM_TIMES                   0x50
545 CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES                  0x60
546 CONSTANT: REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB               0x70
547 CONSTANT: REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB    0x80
548
549 CONSTANT: BIND_TYPE_POINTER                       1
550 CONSTANT: BIND_TYPE_TEXT_ABSOLUTE32               2
551 CONSTANT: BIND_TYPE_TEXT_PCREL32                  3
552
553 CONSTANT: BIND_SPECIAL_DYLIB_SELF                     0
554 CONSTANT: BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE          -1
555 CONSTANT: BIND_SPECIAL_DYLIB_FLAT_LOOKUP              -2
556 CONSTANT: BIND_SPECIAL_DYLIB_WEAK_LOOKUP              -3
557
558 CONSTANT: BIND_SYMBOL_FLAGS_WEAK_IMPORT                   0x1
559 CONSTANT: BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION           0x8
560
561 CONSTANT: BIND_OPCODE_MASK                                    0xF0
562 CONSTANT: BIND_IMMEDIATE_MASK                                 0x0F
563 CONSTANT: BIND_OPCODE_DONE                                    0x00
564 CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM                   0x10
565 CONSTANT: BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB                  0x20
566 CONSTANT: BIND_OPCODE_SET_DYLIB_SPECIAL_IMM                   0x30
567 CONSTANT: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM           0x40
568 CONSTANT: BIND_OPCODE_SET_TYPE_IMM                            0x50
569 CONSTANT: BIND_OPCODE_SET_ADDEND_SLEB                         0x60
570 CONSTANT: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB             0x70
571 CONSTANT: BIND_OPCODE_ADD_ADDR_ULEB                           0x80
572 CONSTANT: BIND_OPCODE_DO_BIND                                 0x90
573 CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB                   0xA0
574 CONSTANT: BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED             0xB0
575 CONSTANT: BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB        0xC0
576 CONSTANT: BIND_OPCODE_THREADED                                0xD0
577 CONSTANT: BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB 0x00
578 CONSTANT: BIND_SUBOPCODE_THREADED_APPLY                       0x01
579
580 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_MASK                   0x03
581 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_REGULAR                0x00
582 CONSTANT: EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL           0x01
583 CONSTANT: EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION             0x04
584 CONSTANT: EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION         0x08
585 CONSTANT: EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS         0x10
586 CONSTANT: EXPORT_SYMBOL_FLAGS_STATIC_RESOLVER             0x20
587
588 STRUCT: symseg_command
589     { cmd        uint }
590     { cmdsize    uint }
591     { offset     uint }
592     { size       uint } ;
593
594 STRUCT: ident_command
595     { cmd     uint }
596     { cmdsize uint } ;
597
598 STRUCT: fvmfile_command
599     { cmd            uint     }
600     { cmdsize        uint     }
601     { name           lc_str   }
602     { header_addr    uint     } ;
603
604 STRUCT: entry_point_command
605     { cmd uint32_t }
606     { cmdsize uint32_t }
607     { entryoff uint64_t }
608     { stacksize uint64_t } ;
609
610 STRUCT: source_version_command
611     { cmd uint32_t }
612     { cmdsize uint32_t }
613     { version uint64_t } ;
614
615 STRUCT: data_in_code_entry
616     { offset uint32_t }
617     { length uint16_t }
618     { kind uint16_t } ;
619
620 ! machine.h
621 CONSTANT: CPU_STATE_MAX       4
622 CONSTANT: CPU_STATE_USER      0
623 CONSTANT: CPU_STATE_SYSTEM    1
624 CONSTANT: CPU_STATE_IDLE      2
625 CONSTANT: CPU_STATE_NICE      3
626
627 CONSTANT: CPU_ARCH_MASK   0xff000000
628 CONSTANT: CPU_ARCH_ABI64  0x01000000
629
630 CONSTANT: CPU_TYPE_ANY            -1
631 CONSTANT: CPU_TYPE_VAX            1
632 CONSTANT: CPU_TYPE_MC680x0        6
633 CONSTANT: CPU_TYPE_X86            7
634 ALIAS: CPU_TYPE_I386              CPU_TYPE_X86
635 CONSTANT: CPU_TYPE_X86_64         flags{ CPU_TYPE_X86 CPU_ARCH_ABI64 }
636 CONSTANT: CPU_TYPE_MC98000        10
637 CONSTANT: CPU_TYPE_HPPA           11
638 CONSTANT: CPU_TYPE_ARM            12
639 CONSTANT: CPU_TYPE_MC88000        13
640 CONSTANT: CPU_TYPE_SPARC          14
641 CONSTANT: CPU_TYPE_I860           15
642 CONSTANT: CPU_TYPE_POWERPC        18
643 CONSTANT: CPU_TYPE_POWERPC64      flags{ CPU_TYPE_POWERPC CPU_ARCH_ABI64 }
644
645 CONSTANT: CPU_SUBTYPE_MASK    0xff000000
646 CONSTANT: CPU_SUBTYPE_LIB64   0x80000000
647
648 CONSTANT: CPU_SUBTYPE_MULTIPLE        -1
649 CONSTANT: CPU_SUBTYPE_LITTLE_ENDIAN   0
650 CONSTANT: CPU_SUBTYPE_BIG_ENDIAN      1
651
652 CONSTANT: CPU_THREADTYPE_NONE     0
653
654 CONSTANT: CPU_SUBTYPE_VAX_ALL 0
655 CONSTANT: CPU_SUBTYPE_VAX780  1
656 CONSTANT: CPU_SUBTYPE_VAX785  2
657 CONSTANT: CPU_SUBTYPE_VAX750  3
658 CONSTANT: CPU_SUBTYPE_VAX730  4
659 CONSTANT: CPU_SUBTYPE_UVAXI   5
660 CONSTANT: CPU_SUBTYPE_UVAXII  6
661 CONSTANT: CPU_SUBTYPE_VAX8200 7
662 CONSTANT: CPU_SUBTYPE_VAX8500 8
663 CONSTANT: CPU_SUBTYPE_VAX8600 9
664 CONSTANT: CPU_SUBTYPE_VAX8650 10
665 CONSTANT: CPU_SUBTYPE_VAX8800 11
666 CONSTANT: CPU_SUBTYPE_UVAXIII 12
667
668 CONSTANT: CPU_SUBTYPE_MC680x0_ALL     1
669 CONSTANT: CPU_SUBTYPE_MC68030     1
670 CONSTANT: CPU_SUBTYPE_MC68040     2
671 CONSTANT: CPU_SUBTYPE_MC68030_ONLY    3
672
673 : CPU_SUBTYPE_INTEL ( f m -- subtype ) 4 shift + ; inline
674
675 CONSTANT: CPU_SUBTYPE_I386_ALL              3
676 CONSTANT: CPU_SUBTYPE_386                   3
677 CONSTANT: CPU_SUBTYPE_486                   4
678 CONSTANT: CPU_SUBTYPE_486SX                 132
679 CONSTANT: CPU_SUBTYPE_586                   5
680 CONSTANT: CPU_SUBTYPE_PENT                  5
681 CONSTANT: CPU_SUBTYPE_PENTPRO               22
682 CONSTANT: CPU_SUBTYPE_PENTII_M3             54
683 CONSTANT: CPU_SUBTYPE_PENTII_M5             86
684 CONSTANT: CPU_SUBTYPE_CELERON               103
685 CONSTANT: CPU_SUBTYPE_CELERON_MOBILE        119
686 CONSTANT: CPU_SUBTYPE_PENTIUM_3             8
687 CONSTANT: CPU_SUBTYPE_PENTIUM_3_M           24
688 CONSTANT: CPU_SUBTYPE_PENTIUM_3_XEON        40
689 CONSTANT: CPU_SUBTYPE_PENTIUM_M             9
690 CONSTANT: CPU_SUBTYPE_PENTIUM_4             10
691 CONSTANT: CPU_SUBTYPE_PENTIUM_4_M           26
692 CONSTANT: CPU_SUBTYPE_ITANIUM               11
693 CONSTANT: CPU_SUBTYPE_ITANIUM_2             27
694 CONSTANT: CPU_SUBTYPE_XEON                  12
695 CONSTANT: CPU_SUBTYPE_XEON_MP               28
696
697 : CPU_SUBTYPE_INTEL_FAMILY ( x -- family ) 15 bitand ; inline
698
699 CONSTANT: CPU_SUBTYPE_INTEL_FAMILY_MAX    15
700
701 : CPU_SUBTYPE_INTEL_MODEL ( x -- model ) -4 shift ; inline
702
703 CONSTANT: CPU_SUBTYPE_INTEL_MODEL_ALL 0
704 CONSTANT: CPU_SUBTYPE_X86_ALL         3
705 CONSTANT: CPU_SUBTYPE_X86_64_ALL      3
706 CONSTANT: CPU_SUBTYPE_X86_ARCH1       4
707 CONSTANT: CPU_THREADTYPE_INTEL_HTT    1
708
709 CONSTANT: CPU_SUBTYPE_MIPS_ALL    0
710 CONSTANT: CPU_SUBTYPE_MIPS_R2300  1
711 CONSTANT: CPU_SUBTYPE_MIPS_R2600  2
712 CONSTANT: CPU_SUBTYPE_MIPS_R2800  3
713 CONSTANT: CPU_SUBTYPE_MIPS_R2000a 4
714 CONSTANT: CPU_SUBTYPE_MIPS_R2000  5
715 CONSTANT: CPU_SUBTYPE_MIPS_R3000a 6
716 CONSTANT: CPU_SUBTYPE_MIPS_R3000  7
717
718 CONSTANT: CPU_SUBTYPE_MC98000_ALL 0
719 CONSTANT: CPU_SUBTYPE_MC98601     1
720
721 CONSTANT: CPU_SUBTYPE_HPPA_ALL        0
722 CONSTANT: CPU_SUBTYPE_HPPA_7100       0
723 CONSTANT: CPU_SUBTYPE_HPPA_7100LC     1
724
725 CONSTANT: CPU_SUBTYPE_MC88000_ALL 0
726 CONSTANT: CPU_SUBTYPE_MC88100     1
727 CONSTANT: CPU_SUBTYPE_MC88110     2
728
729 CONSTANT: CPU_SUBTYPE_SPARC_ALL       0
730
731 CONSTANT: CPU_SUBTYPE_I860_ALL    0
732 CONSTANT: CPU_SUBTYPE_I860_860    1
733
734 CONSTANT: CPU_SUBTYPE_POWERPC_ALL     0
735 CONSTANT: CPU_SUBTYPE_POWERPC_601     1
736 CONSTANT: CPU_SUBTYPE_POWERPC_602     2
737 CONSTANT: CPU_SUBTYPE_POWERPC_603     3
738 CONSTANT: CPU_SUBTYPE_POWERPC_603e    4
739 CONSTANT: CPU_SUBTYPE_POWERPC_603ev   5
740 CONSTANT: CPU_SUBTYPE_POWERPC_604     6
741 CONSTANT: CPU_SUBTYPE_POWERPC_604e    7
742 CONSTANT: CPU_SUBTYPE_POWERPC_620     8
743 CONSTANT: CPU_SUBTYPE_POWERPC_750     9
744 CONSTANT: CPU_SUBTYPE_POWERPC_7400    10
745 CONSTANT: CPU_SUBTYPE_POWERPC_7450    11
746 CONSTANT: CPU_SUBTYPE_POWERPC_970     100
747
748 CONSTANT: CPU_SUBTYPE_ARM_ALL             0
749 CONSTANT: CPU_SUBTYPE_ARM_V4T             5
750 CONSTANT: CPU_SUBTYPE_ARM_V6              6
751 CONSTANT: CPU_SUBTYPE_ARM_V5TEJ           7
752 CONSTANT: CPU_SUBTYPE_ARM_XSCALE          8
753 CONSTANT: CPU_SUBTYPE_ARM_V7              9
754
755 CONSTANT: CPUFAMILY_UNKNOWN    0
756 CONSTANT: CPUFAMILY_POWERPC_G3 0xcee41549
757 CONSTANT: CPUFAMILY_POWERPC_G4 0x77c184ae
758 CONSTANT: CPUFAMILY_POWERPC_G5 0xed76d8aa
759 CONSTANT: CPUFAMILY_INTEL_6_13 0xaa33392b
760 CONSTANT: CPUFAMILY_INTEL_6_14 0x73d67300
761 CONSTANT: CPUFAMILY_INTEL_6_15 0x426f69ef
762 CONSTANT: CPUFAMILY_INTEL_6_23 0x78ea4fbc
763 CONSTANT: CPUFAMILY_INTEL_6_26 0x6b5a4cd2
764 CONSTANT: CPUFAMILY_ARM_9      0xe73283ae
765 CONSTANT: CPUFAMILY_ARM_11     0x8ff620d8
766 CONSTANT: CPUFAMILY_ARM_XSCALE 0x53b005f5
767 CONSTANT: CPUFAMILY_ARM_13     0x0cc90e64
768
769 ALIAS: CPUFAMILY_INTEL_YONAH   CPUFAMILY_INTEL_6_14
770 ALIAS: CPUFAMILY_INTEL_MEROM   CPUFAMILY_INTEL_6_15
771 ALIAS: CPUFAMILY_INTEL_PENRYN  CPUFAMILY_INTEL_6_23
772 ALIAS: CPUFAMILY_INTEL_NEHALEM CPUFAMILY_INTEL_6_26
773
774 ALIAS: CPUFAMILY_INTEL_CORE    CPUFAMILY_INTEL_6_14
775 ALIAS: CPUFAMILY_INTEL_CORE2   CPUFAMILY_INTEL_6_15
776
777 ! fat.h
778 CONSTANT: FAT_MAGIC 0xcafebabe
779 CONSTANT: FAT_CIGAM 0xbebafeca
780
781 STRUCT: fat_header
782     { magic        uint }
783     { nfat_arch    uint } ;
784
785 STRUCT: fat_arch
786     { cputype      cpu_type_t    }
787     { cpusubtype   cpu_subtype_t }
788     { offset       uint          }
789     { size         uint          }
790     { align        uint          } ;
791
792 ! nlist.h
793 STRUCT: nlist
794     { n_strx  int      }
795     { n_type  uchar    }
796     { n_sect  uchar    }
797     { n_desc  short    }
798     { n_value uint     } ;
799
800 STRUCT: nlist_64
801     { n_strx  uint      }
802     { n_type  uchar     }
803     { n_sect  uchar     }
804     { n_desc  ushort    }
805     { n_value ulonglong } ;
806
807 CONSTANT: N_STAB  0xe0
808 CONSTANT: N_PEXT  0x10
809 CONSTANT: N_TYPE  0x0e
810 CONSTANT: N_EXT   0x01
811
812 CONSTANT: N_UNDF  0x0
813 CONSTANT: N_ABS   0x2
814 CONSTANT: N_SECT  0xe
815 CONSTANT: N_PBUD  0xc
816 CONSTANT: N_INDR  0xa
817
818 CONSTANT: NO_SECT     0
819 CONSTANT: MAX_SECT    255
820
821 : GET_COMM_ALIGN ( n_desc -- align )
822     -8 shift 0x0f bitand ; inline
823
824 : SET_COMM_ALIGN ( n_desc align -- n_desc )
825     [ 0xf0ff bitand ]
826     [ 0x000f bitand 8 shift ] bi* bitor ; inline
827
828 CONSTANT: REFERENCE_TYPE                              7
829 CONSTANT: REFERENCE_FLAG_UNDEFINED_NON_LAZY           0
830 CONSTANT: REFERENCE_FLAG_UNDEFINED_LAZY               1
831 CONSTANT: REFERENCE_FLAG_DEFINED                      2
832 CONSTANT: REFERENCE_FLAG_PRIVATE_DEFINED              3
833 CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY   4
834 CONSTANT: REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY       5
835
836 CONSTANT: REFERENCED_DYNAMICALLY  0x0010
837
838 : GET_LIBRARY_ORDINAL ( n_desc -- ordinal )
839     -8 shift 0xff bitand ; inline
840
841 : SET_LIBRARY_ORDINAL ( n_desc ordinal -- n_desc )
842     [ 0x00ff bitand ]
843     [ 0x00ff bitand 8 shift ] bi* bitor ; inline
844
845 CONSTANT: SELF_LIBRARY_ORDINAL   0x0
846 CONSTANT: MAX_LIBRARY_ORDINAL    0xfd
847 CONSTANT: DYNAMIC_LOOKUP_ORDINAL 0xfe
848 CONSTANT: EXECUTABLE_ORDINAL     0xff
849
850 CONSTANT: N_NO_DEAD_STRIP  0x0020
851 CONSTANT: N_DESC_DISCARDED 0x0020
852 CONSTANT: N_WEAK_REF       0x0040
853 CONSTANT: N_WEAK_DEF       0x0080
854 CONSTANT: N_REF_TO_WEAK    0x0080
855 CONSTANT: N_ARM_THUMB_DEF  0x0008
856
857 ! ranlib.h
858 CONSTANT: SYMDEF        "__.SYMDEF"
859 CONSTANT: SYMDEF_SORTED "__.SYMDEF SORTED"
860
861 STRUCT: ranlib
862     { ran_strx uint }
863     { ran_off  uint } ;
864
865 ! reloc.h
866 STRUCT: relocation_info
867     { r_address                            int  }
868     { r_symbolnum_pcrel_length_extern_type uint } ;
869
870 CONSTANT: R_ABS   0
871 CONSTANT: R_SCATTERED 0x80000000
872
873 STRUCT: scattered_relocation_info_big_endian
874     { r_scattered_pcrel_length_type_address  uint }
875     { r_value                                int  } ;
876
877 STRUCT: scattered_relocation_info_little_endian
878     { r_address_type_length_pcrel_scattered uint }
879     { r_value                               int  } ;
880
881 ENUM: reloc_type_generic
882     GENERIC_RELOC_VANILLA
883     GENERIC_RELOC_PAIR
884     GENERIC_RELOC_SECTDIFF
885     GENERIC_RELOC_PB_LA_PTR
886     GENERIC_RELOC_LOCAL_SECTDIFF ;
887
888 ENUM: reloc_type_x86_64
889     X86_64_RELOC_UNSIGNED
890     X86_64_RELOC_SIGNED
891     X86_64_RELOC_BRANCH
892     X86_64_RELOC_GOT_LOAD
893     X86_64_RELOC_GOT
894     X86_64_RELOC_SUBTRACTOR
895     X86_64_RELOC_SIGNED_1
896     X86_64_RELOC_SIGNED_2
897     X86_64_RELOC_SIGNED_4 ;
898
899 ENUM: reloc_type_ppc
900     PPC_RELOC_VANILLA
901     PPC_RELOC_PAIR
902     PPC_RELOC_BR14
903     PPC_RELOC_BR24
904     PPC_RELOC_HI16
905     PPC_RELOC_LO16
906     PPC_RELOC_HA16
907     PPC_RELOC_LO14
908     PPC_RELOC_SECTDIFF
909     PPC_RELOC_PB_LA_PTR
910     PPC_RELOC_HI16_SECTDIFF
911     PPC_RELOC_LO16_SECTDIFF
912     PPC_RELOC_HA16_SECTDIFF
913     PPC_RELOC_JBSR
914     PPC_RELOC_LO14_SECTDIFF
915     PPC_RELOC_LOCAL_SECTDIFF ;
916
917 ! Low-level interface
918 SPECIALIZED-ARRAYS: section section_64 nlist nlist_64 fat_arch uchar ;
919 UNION: mach_header_32/64 mach_header mach_header_64 ;
920 UNION: segment_command_32/64 segment_command segment_command_64 ;
921 UNION: load-command segment_command segment_command_64
922     dylib_command sub_framework_command
923     sub_client_command sub_umbrella_command sub_library_command
924     prebound_dylib_command dylinker_command thread_command
925     routines_command routines_command_64 symtab_command
926     dysymtab_command twolevel_hints_command uuid_command ;
927 UNION: section_32/64 section section_64 ;
928 UNION: section_32/64-array section-array section_64-array ;
929 UNION: nlist_32/64 nlist nlist_64 ;
930 UNION: nlist_32/64-array nlist-array nlist_64-array ;
931
932 TUPLE: fat-binary-member cpu-type cpu-subtype data ;
933 ERROR: not-fat-binary ;
934
935 : fat-binary-members ( >c-ptr -- fat-binary-members )
936     fat_header memory>struct dup magic>> {
937         { FAT_MAGIC [ ] }
938         { FAT_CIGAM [ ] }
939         [ 2drop not-fat-binary ]
940     } case dup
941     [ >c-ptr fat_header heap-size swap <displaced-alien> ]
942     [ nfat_arch>> 4 >be le> ] bi
943     fat_arch <c-direct-array> [
944         {
945             [ nip cputype>> 4 >be le> ]
946             [ nip cpusubtype>> 4 >be le> ]
947             [ offset>> 4 >be le> swap >c-ptr <displaced-alien> ]
948             [ nip size>> 4 >be le> uchar <c-direct-array> ]
949         } 2cleave fat-binary-member boa
950     ] with { } map-as ;
951
952 TYPED: 64-bit? ( macho: mach_header_32/64 -- ? )
953     magic>> {
954         { MH_MAGIC_64 [ t ] }
955         { MH_CIGAM_64 [ t ] }
956         [ drop f ]
957     } case ;
958
959 : macho-header ( c-ptr -- macho: mach_header_32/64 )
960     dup mach_header_64 memory>struct 64-bit?
961     [ mach_header_64 memory>struct ]
962     [ mach_header memory>struct ] if ;
963
964 : cmd>load-command ( cmd -- load-command )
965     {
966         { LC_UUID           [ uuid_command           ] }
967         { LC_SEGMENT        [ segment_command        ] }
968         { LC_SEGMENT_64     [ segment_command_64     ] }
969         { LC_SYMTAB         [ symtab_command         ] }
970         { LC_DYSYMTAB       [ dysymtab_command       ] }
971         { LC_THREAD         [ thread_command         ] }
972         { LC_UNIXTHREAD     [ thread_command         ] }
973         { LC_LOAD_DYLIB     [ dylib_command          ] }
974         { LC_ID_DYLIB       [ dylib_command          ] }
975         { LC_PREBOUND_DYLIB [ prebound_dylib_command ] }
976         { LC_LOAD_DYLINKER  [ dylinker_command       ] }
977         { LC_ID_DYLINKER    [ dylinker_command       ] }
978         { LC_ROUTINES       [ routines_command       ] }
979         { LC_ROUTINES_64    [ routines_command_64    ] }
980         { LC_TWOLEVEL_HINTS [ twolevel_hints_command ] }
981         { LC_SUB_FRAMEWORK  [ sub_framework_command  ] }
982         { LC_SUB_UMBRELLA   [ sub_umbrella_command   ] }
983         { LC_SUB_LIBRARY    [ sub_library_command    ] }
984         { LC_SUB_CLIENT     [ sub_client_command     ] }
985         { LC_DYLD_INFO      [ dyld_info_command      ] }
986         { LC_DYLD_INFO_ONLY [ dyld_info_command      ] }
987         { LC_LOAD_UPWARD_DYLIB [ dylib_command ] }
988         { LC_VERSION_MIN_MACOSX [ version_min_command ] }
989         { LC_VERSION_MIN_IPHONEOS [ version_min_command ] }
990         { LC_FUNCTION_STARTS [ linkedit_data_command ] }
991         { LC_DYLD_ENVIRONMENT [ dylinker_command ] }
992         { LC_MAIN [ entry_point_command ] }
993         { LC_DATA_IN_CODE [ data_in_code_entry ] }
994         { LC_SOURCE_VERSION [ source_version_command ] }
995         { LC_DYLIB_CODE_SIGN_DRS [ linkedit_data_command ] }
996         { LC_BUILD_VERSION [ build_version_command ] }
997     } case ;
998
999 : read-command ( cmd -- next-cmd )
1000     dup load_command memory>struct
1001     [ cmd>> cmd>load-command memory>struct , ]
1002     [ cmdsize>> swap <displaced-alien> ] 2bi ;
1003
1004 TYPED: load-commands ( macho: mach_header_32/64 -- load-commands )
1005     [
1006         [ class-of heap-size ]
1007         [ >c-ptr <displaced-alien> ]
1008         [ ncmds>> ] tri <iota> [
1009             drop read-command
1010         ] each drop
1011     ] { } make ;
1012
1013 : segment-commands ( load-commands -- segment-commands )
1014     [ segment_command_32/64? ] filter ; inline
1015
1016 : symtab-commands ( load-commands -- segment-commands )
1017     [ symtab_command? ] filter ; inline
1018
1019 : read-array-string ( uchar-array -- string )
1020     ascii decode 0 swap remove ;
1021
1022 : segment-sections ( segment-command -- sections )
1023     {
1024         [ class-of heap-size ]
1025         [ >c-ptr <displaced-alien> ]
1026         [ nsects>> ]
1027         [ segment_command_64? ]
1028     } cleave
1029     [ section_64 <c-direct-array> ]
1030     [ section <c-direct-array> ] if ;
1031
1032 : sections-array ( segment-commands -- sections-array )
1033     [
1034         dup first segment_command_64?
1035         [ section_64 ] [ section ] if new ,
1036         segment-commands [ segment-sections [ , ] each ] each
1037     ] { } make ;
1038
1039 : symbols ( mach-header symtab-command -- symbols string-table )
1040     [ symoff>> swap >c-ptr <displaced-alien> ]
1041     [ nsyms>> swap 64-bit?
1042       [ nlist_64 <c-direct-array> ]
1043       [ nlist <c-direct-array> ] if ]
1044     [ stroff>> swap >c-ptr <displaced-alien> ] 2tri ;
1045
1046 : symbol-name ( symbol string-table -- name )
1047     [ n_strx>> ] dip <displaced-alien> ascii alien>string ;
1048
1049 : c-symbol-name ( symbol string-table -- name )
1050     symbol-name "_" ?head drop ;
1051
1052 : with-mapped-macho ( path quot -- )
1053     '[
1054         address>> macho-header @
1055     ] with-mapped-file-reader ; inline
1056
1057 : macho-nm ( path -- )
1058     [| macho |
1059         macho load-commands segment-commands sections-array :> sections
1060         macho load-commands symtab-commands [| symtab |
1061             macho symtab symbols [
1062                 [ drop n_value>> "%016x " printf ]
1063                 [
1064                     drop n_sect>> sections nth sectname>>
1065                     read-array-string "%-16s" printf
1066                 ]
1067                 [ symbol-name "%s\n" printf ] 2tri
1068             ] curry each
1069         ] each
1070     ] with-mapped-macho ;
1071
1072 : dylib-export? ( symtab-entry -- ? )
1073     n_type>> {
1074         [ N_EXT bitand zero? not ]
1075         [ N_TYPE bitand N_UNDF = not ]
1076     } 1&& ;
1077
1078 : dylib-exports ( path -- symbol-names )
1079     [| macho |
1080         macho load-commands symtab-commands [| symtab |
1081             macho symtab symbols
1082             [ [ dylib-export? ] filter ]
1083             [ [ c-symbol-name ] curry { } map-as ] bi*
1084         ] { } map-as concat
1085     ] with-mapped-macho ;