/red-system/formats/Mach-O.r
R | 679 lines | 616 code | 63 blank | 0 comment | 26 complexity | dc255b26e0fe856cf0342ae5613d7ffe MD5 | raw file
1REBOL [ 2 Title: "Red/System Mach-O format emitter" 3 Author: "Nenad Rakocevic" 4 File: %Mach-O.r 5 Rights: "Copyright (C) 2011 Nenad Rakocevic. All rights reserved." 6 License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt" 7] 8 9;; Reference doc: http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html 10 11context [ 12 defs: compose [ 13 extensions [ 14 exe %"" 15 obj %.o 16 lib %.a 17 dll %.dylib 18 ] 19 20 base-address 0 21 page-size 4096 ;-- target-dependent 22 23 file-type [ ;-- Constants for the filetype field of the mach_header 24 object 1 ; relocatable object file 25 execute 2 ; demand paged executable file 26 fvmlib 3 ; fixed VM shared library file 27 core 4 ; core file 28 preload 5 ; preloaded executable file 29 dylib 6 ; dynamically bound shared library 30 dylinker 7 ; dynamic link editor 31 bundle 8 ; dynamically bound bundle file 32 dylib_stub 9 ; shared library stub for static 33 dsym 10 ; file that store symbol information for a corresponding binary file 34 ] 35 flags [ ;-- Constants for the flags field of the mach_header 36 noundefs 1 ; no undefined references 37 incrlink 2 ; output of an incremental link against a base file 38 dyldlink 4 ; input for the dynamic linker 39 bindatload 8 ; undefined references are bound by the dynamic linker when loaded 40 prebound 16 ; dynamic undefined references prebound 41 split_segs 32 ; read-only and read-write segments split 42 lazy_init 64 ; (obsolete) shared library init routine run lazily 43 twolevel 128 ; the image is using two-level name space bindings 44 force_flat 256 ; forcing all images to use flat name space bindings 45 nomultidefs 512 ; no multiple defintions of symbols in its sub-images 46 nofixprebinding 1024 ; do not have dyld notify the prebinding agent about this executable 47 prebindable 2048 ; not prebound but can have its prebinding redone 48 allmodsbound 4096 ; binds to all two-level namespace modules of its dependent libraries 49 subsections 8192 ; sections of the object file can be divided into individual blocks 50 canonical 16384 ; canonicalized via the unprebind operation 51 weakdefs 32768 ; ?? (MH_WEAK_DEFINES) 52 bindstoweak 65536 ; ?? (MH_BINDS_TO_WEAK) 53 allowstackexec 131072 ; ?? (MH_ALLOW_STACK_EXECUTION) 54 validflags 262143 ; ?? 0003ffff (mask) 55 ] 56 load-type [ ;-- Constants for the cmd field of all load commands 57 req_dyld -2147483648 58 segment 1 ; segment of this file to be mapped 59 symtab 2 ; link-edit stab symbol table info 60 symseg 3 ; link-edit gdb symbol table info (obsolete) 61 thread 4 ; thread 62 unixthread 5 ; unix thread (includes a stack) 63 loadfvmlib 6 ; load a specified fixed VM shared library 64 idfvmlib 7 ; fixed VM shared library identification 65 ident 8 ; (obsolete) object identification info 66 fvmfile 9 ; (internal use) fixed VM file inclusion 67 prepage 10 ; (internal use) prepage command 68 dysymtab 11 ; dynamic link-edit symbol table info 69 load_dylib 12 ; load a dynamically linked shared library 70 id_dylib 13 ; dynamically linked shared lib ident 71 load_dylinker 14 ; load a dynamic linker 72 id_dylinker 15 ; dynamic linker identification 73 prebound_dylib 16 ; modules prebound for a dynamically linked shared library 74 routines 17 ; image routines 75 sub_framework 18 ; sub framework 76 sub_umbrella 19 ; sub umbrella 77 sub_client 20 ; sub client 78 sub_library 21 ; sub library 79 twolevel_hints 22 ; two-level namespace lookup hints 80 prebind_cksum 23 ; prebind checksum 81 uuid 27 82 load_weak_dylib -2147483624 ; (0x18 | REQ_DYLD) 83 ] 84 rights [ 85 none 0 86 read 1 87 write 2 88 execute 4 89 ] 90 sect-type [ ;-- Constants for the type of a section 91 regular #{00000000} ; regular section 92 zerofill #{00000001} ; zero fill on demand section 93 cstring_literals #{00000002} ; section with only literal C strings 94 _4byte_literals #{00000003} ; section with only 4 byte literals 95 _8byte_literals #{00000004} ; section with only 8 byte literals 96 literal_pointers #{00000005} ; section with only pointers to 97 non_lazy_symbol_pointers #{00000006} ; section with only non-lazy 98 lazy_symbol_pointers #{00000007} ; section with only lazy symbol 99 symbol_stubs #{00000008} ; section with only symbol 100 mod_init_func_pointers #{00000009} ; section with only function 101 mod_term_func_pointers #{0000000a} ; section with only function 102 coalesced #{0000000b} ; section contains symbols that 103 section_attributes_usr #{ff000000} ; User setable attributes 104 attr_self_modifying_code #{04000000} ; section contains self-modifying code 105 attr_pure_instructions #{80000000} ; section contains only true 106 attr_no_toc #{40000000} ; section contains coalesced 107 attr_strip_static_syms #{20000000} ; ok to strip static symbols 108 section_attributes_sys #{00ffff00} ; system setable attributes 109 attr_some_instructions #{00000400} ; section contains some machine instructions 110 attr_ext_reloc #{00000200} ; section has external relocation entries 111 attr_loc_reloc #{00000100} ; section has local relocation entries 112 ] 113 sym-type [ 114 n-stab #{E0} ; stab entry 115 n-pext #{10} ; private extern bit 116 n-type #{0E} ; type of the symbol 117 n-ext #{01} ; external symbol 118 ;-- n-type flags -- 119 n-undf #{00} ; undefined symbol 120 n-abs #{02} ; absolute symbol 121 n-sect #{0E} ; symbol defined in section n-sect 122 n-pbud #{0C} ; prebound valud for an undefined symbol 123 n-indr #{0A} ; alias symbol (n-value points to reference symbol) 124 ] 125 sym-desc [ 126 undef-non-lazy #{00} ; reference to an external non-lazy (data) symbol 127 undef-lazy #{01} ; external lazy symbol—that is, to a function call 128 defined #{02} ; symbol is defined in this module 129 priv-def #{03} ; defined in module, but private 130 priv-def-non-lazy #{04} ; private, defined, non-lazy symbol 131 priv-def-lazy #{05} ; private, defined, lazy symbol 132 ref-dynamically #{10} ; set for any defined symbol that is referenced by dynamic-loader APIs 133 desc-discarded #{20} ; do not set this bit in a fully linked image 134 no-dead-strip #{20} ; indicates to the static linker to never dead-strip the symbo 135 weak-ref #{40} ; symbol is a weak reference 136 weak-def #{80} ; symbol is a weak definition 137 ] 138 ] 139 140 ;; Mach-O Structures 141 142 mach-header: make-struct [ 143 magic [integer!] ;; 0xfeedface 144 cpu-type [integer!] ;; CPU_TYPE_I386 = 7 145 cpu-sub-type [integer!] ;; CPU_SUBTYPE_I386_ALL = 3 146 file-type [integer!] 147 nb-cmds [integer!] ;; number of load commands 148 sz-cmds [integer!] 149 flags [integer!] 150 ] none 151 152 segment-command: make-struct [ 153 cmd [integer!] ; load-type/segment 154 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 155 segname1 [decimal!] ; char segname[16] 156 segname2 [decimal!] 157 vmaddr [integer!] ; starting virtual memory address of this segment 158 vmsize [integer!] ; number of bytes of virtual memory occupied by this segment 159 fileoff [integer!] ; offset in this file of the data to be mapped at vmaddr 160 filesize [integer!] ; number of bytes occupied by this segment on disk 161 maxprot [integer!] ; maximum permitted virtual memory protections of this segment 162 initprot [integer!] ; initial virtual memory protections of this segment 163 nsects [integer!] ; number of section data structures following this load command 164 flags [integer!] ; 165 ] none 166 167 unix-thread-cmd: make-struct [ 168 cmd [integer!] ; load-type/segment 169 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 170 flavor [integer!] ; x86_THREAD_STATE32 = 1 171 count [integer!] ; nb of thread state 32-bit entries (16) 172 eax [integer!] 173 ebx [integer!] 174 ecx [integer!] 175 edx [integer!] 176 edi [integer!] 177 esi [integer!] 178 ebp [integer!] 179 esp [integer!] 180 ss [integer!] 181 eflags [integer!] 182 eip [integer!] 183 cs [integer!] 184 ds [integer!] 185 es [integer!] 186 fs [integer!] 187 gs [integer!] 188 ] none 189 190 load-dylib-cmd: make-struct [ 191 cmd [integer!] ; load-type/segment 192 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 193 offset [integer!] ; = 24 (from the start of the load cmd) 194 timestamp [integer!] ; date and time when the shared library was built 195 version [integer!] ; current version of the shared library 196 compat [integer!] ; compatibility version of the shared library 197 ] none 198 199 dylinker-cmd: make-struct [ 200 cmd [integer!] ; load-type/segment 201 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 202 offset [integer!] ; = 12 (from the start of the load cmd) 203 ] none 204 205 section-header: make-struct [ 206 sectname1 [decimal!] ; char sectname[16] 207 sectname2 [decimal!] 208 segname1 [decimal!] ; char segname[16] 209 segname2 [decimal!] 210 addr [integer!] ; virtual memory address of this section 211 size [integer!] ; size in bytes of the virtual memory occupied by this section 212 offset [integer!] ; offset to this section in the file 213 align [integer!] ; section’s byte alignment as power of two 214 reloff [integer!] ; file offset of the first relocation entry for this section. 215 nreloc [integer!] ; number of relocation entries located at reloff for this section. 216 flags [integer!] 217 reserved1 [integer!] 218 reserved2 [integer!] 219 ] none 220 221 symtab-cmd: make-struct [ 222 cmd [integer!] ; load-type/segment 223 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 224 symoff [integer!] ; symbol table file offset (from head of file) 225 nsyms [integer!] ; nb of symbol entries 226 stroff [integer!] ; string table file offset (from head of file) 227 strsize [integer!] ; size of string table in bytes 228 ] none 229 230 dysymtab-cmd: make-struct [ 231 cmd [integer!] ; load-type/segment 232 size [integer!] ; sizeof(segment_command + (sizeof(section) * segment->nsect)) 233 ilocalsym [integer!] ; index of the first symbol in the group of local symbols 234 nlocalsym [integer!] ; total number of symbols in the group of local symbols 235 iextdefsym [integer!] ; index of the first symbol in the group of defined external symbols 236 nextdefsym [integer!] ; total number of symbols in the group of defined external symbols 237 iundefsym [integer!] ; index of the first symbol in the group of undefined external symbols 238 nundefsym [integer!] ; total number of symbols in the group of undefined external symbols 239 tocoff [integer!] ; byte offset from the start of the file to the table of contents data 240 ntoc [integer!] ; number of entries in the table of contents 241 modtaboff [integer!] ; byte offset from the start of the file to the module table data 242 nmodtab [integer!] ; number of entries in the module table 243 extrefsymoff [integer!] ; byte offset from the start of the file to the external reference table data 244 nextrefsyms [integer!] ; number of entries in the external reference table 245 indirectsymoff [integer!] ; byte offset from the start of the file to the indirect symbol table data 246 nindirectsyms [integer!] ; number of entries in the indirect symbol table 247 extreloff [integer!] ; byte offset from the start of the file to the external relocation table data 248 nextrel [integer!] ; number of entries in the external relocation table 249 locreloff [integer!] ; byte offset from the start of the file to the local relocation table data 250 nlocrel [integer!] ; number of entries in the local relocation table 251 ] none 252 253 nlist: make-struct [ 254 n-strx [integer!] ; index in the string table 255 n-type [char!] ; bit flags 256 n-sect [char!] ; NO-SECT (if external) or section index (one-based) 257 n-desc [short] ; nature of symbol (for non-stab symbols) 258 n-value [integer!] ; symbol type specific value 259 ] none 260 261 pointer: make-struct [ 262 value [integer!] ;-- 32/64-bit, watch out for endianess!! 263 ] none 264 265 ;-- Globals -- 266 267 segments: [ 268 ;-- class ------ name ------ mem --- file - rights - payload - memalign 269 ; - off sz off sz - 270 segment __PAGEZERO 0 page 0 0 [] - page [] 271 segment __TEXT ? ? ? ? [r x] - page [ 272 section __text ? ? ? ? - code word 273 ] 274 segment __DATA ? ? ? ? [r w] - page [ 275 section __data ? ? ? ? - data word 276 ] 277 uthread - - - - - - - - [] 278 ] 279 280 imports-refs: make block! 10 ;-- [ptr [refs] ...] 281 dylink?: no ;-- yes => dynamic library linking required 282 segment-sz: length? form-struct segment-command 283 section-sz: length? form-struct section-header 284 load-cmds-nb: 0 285 load-cmds-sz: 0 286 stub-size: 5 ;-- imported functions slot size 287 288 ;-- Mach-O structure builders -- 289 290 to-c-string: func [value][join value null] 291 292 pad4: func [s [string!] /local rem][ 293 unless zero? rem: (length? s) // 4 [ 294 insert/dup tail s #"^@" 4 - rem 295 ] 296 s 297 ] 298 299 get-ceiling: func [type [word!]][ 300 switch/default type [ 301 page [defs/page-size] 302 word [4] ;-- 4 => 32-bit, 8 => 64-bit @@ 303 byte [1] 304 ][4] ;-- 4 => 32-bit, 8 => 64-bit @@ 305 ] 306 307 sections?: func [list [block!]][(length? list) / 9] 308 309 get-struct-size: func [type [word!]][ 310 switch type [ 311 segment [segment-sz] 312 uthread [length? form-struct unix-thread-cmd] 313 dylinker [length? form-struct dylinker-cmd] 314 lddylib [length? form-struct load-dylib-cmd] 315 symtab [length? form-struct symtab-cmd] 316 dysymtab [length? form-struct dysymtab-cmd] 317 ] 318 ] 319 320 get-rights?: func [spec [block!] /local flags][ 321 flags: 0 322 foreach flag spec [ 323 flags: flags + defs/rights/(select [r read w write x execute] flag) 324 ] 325 flags 326 ] 327 328 get-flags: func [type [word!] /local flags][ 329 flags: defs/sect-type 330 to integer! switch/default type [ 331 code [ 332 flags/attr_pure_instructions 333 or flags/attr_some_instructions 334 ] 335 jmptbl [ 336 flags/attr_pure_instructions 337 or flags/attr_some_instructions 338 or flags/attr_self_modifying_code 339 or flags/symbol_stubs 340 ] 341 ][flags/regular] 342 ] 343 344 get-section-addr: func [name [word!] /local addr][ 345 parse segments [some [into [thru name set addr skip | none] | skip]] 346 addr 347 ] 348 349 get-segment-info: func [name [word!] /local addr][ 350 next find segments name 351 ] 352 353 process-debug-info: func [job [object!]][ 354 linker/build-debug-lines job get-section-addr '__text pointer 355 ] 356 357 prepare-headers: func [ 358 job [object!] 359 /local seg sec addr fpos get-value size sz header-sz hd-sz 360 ][ 361 get-value: func [n value][ 362 switch/default seg/:n [? [value] page [defs/page-size]][seg/:n] 363 ] 364 365 load-cmds-sz: 0 366 seg: segments 367 until [ 368 load-cmds-sz: load-cmds-sz + get-struct-size seg/1 369 if string? seg/2 [load-cmds-sz: load-cmds-sz + length? seg/2] ;-- account for load-dylib path 370 load-cmds-nb: load-cmds-nb + 1 371 unless empty? seg/10 [ 372 load-cmds-sz: load-cmds-sz + (section-sz * sections? seg/10) 373 ] 374 tail? seg: skip seg 10 375 ] 376 377 header-sz: load-cmds-sz + length? form-struct mach-header 378 addr: 0 379 fpos: header-sz 380 381 seg: segments 382 until [ 383 if seg/1 = 'segment [ 384 seg/3: addr: round/ceiling/to get-value 3 addr get-ceiling seg/9 ;-- offset in memory (segment) 385 seg/5: fpos: round/ceiling/to get-value 5 fpos get-ceiling seg/9 ;-- offset in file (segment) 386 387 sec: seg/10 388 hd-sz: either seg/2 = '__TEXT [header-sz][0] ;-- account for headers 389 size: either seg/8 = '- [0][length? job/sections/(seg/8)/2] 390 while [not tail? sec][ 391 sz: length? job/sections/(sec/8)/2 392 sec/3: addr: round/ceiling/to addr + hd-sz get-ceiling sec/9 ;-- offset in memory (section) 393 sec/4: sz ;-- size in memory (section) 394 sec/5: fpos: round/ceiling/to fpos + hd-sz get-ceiling sec/9 ;-- offset in file (section) 395 sec/6: sz ;-- size in file (section) 396 size: size + sz + hd-sz 397 addr: addr + sz 398 fpos: fpos + sz 399 sec: skip sec 9 400 ] 401 size: round/ceiling/to size defs/page-size 402 seg/4: get-value 4 size ;-- size in memory (segment) 403 seg/6: get-value 6 size ;-- size in file (segment) 404 if zero? size [ 405 addr: addr + seg/4 406 fpos: fpos + seg/6 407 ] 408 if all [seg/2 = '__TEXT job/debug?][ 409 process-debug-info job 410 ] 411 ] 412 tail? seg: skip seg 10 413 ] 414 ] 415 416 emit-page-aligned: func [buf [binary!] data [binary!] /local page rem][ 417 append buf data 418 unless zero? rem: (length? buf) // page: defs/page-size [ 419 insert/dup tail buf null page - rem 420 ] 421 ] 422 423 resolve-data-refs: func [job [object!] /local cbuf dbuf data code][ 424 cbuf: job/sections/code/2 425 dbuf: job/sections/data/2 426 forskip segments 10 [ 427 switch segments/2 [ 428 __TEXT [code: get-section-addr '__text] 429 __DATA [data: segments/3] 430 ] 431 ] 432 linker/resolve-symbol-refs job cbuf dbuf code data pointer 433 ] 434 435 resolve-import-refs: func [job [object!] /local code base][ 436 code: job/sections/code/2 437 base: get-section-addr '__jump_table 438 439 foreach [ptr reloc] imports-refs [ 440 pointer/value: ptr: base + ptr 441 foreach ref reloc [ 442 change at code ref form-struct pointer ;TBD: check endianness + x-compilation 443 ] 444 ] 445 ] 446 447 build-imports: func [ 448 job [object!] 449 /local sym-tbl dy-sym-tbl lib cnt entry 450 ][ 451 sym-tbl: make binary! 1024 452 dy-sym-tbl: make binary! 1024 453 str-tbl: make binary! 1024 454 append str-tbl #{00000000} ;-- start with 4 null bytes @@ 455 456 insert find segments 'uthread [ 457 segment __IMPORT ? ? ? ? [r w x] - page [ 458 section __jump_table ? ? ? ? - jmptbl byte 459 ] 460 segment __LINKEDIT ? ? ? ? [r] symbols page [] 461 dylinker - - - - - - - - [] 462 symtab - - - - - - - - [] 463 dysymtab - - - - - - - - [] 464 ;twolvlhints - - - - - - - - [] 465 ] 466 segments/dylinker: pad4 to-c-string "/usr/lib/dyld" 467 468 lib: 1 ;-- one-based index 469 cnt: 0 470 foreach [name list] job/sections/import/3 [ 471 name: to-c-string name 472 if name/1 <> slash [insert name "/usr/lib/"] 473 insert find segments 'symtab compose [ 474 lddylib (pad4 name) - - - - - - - [] 475 ] 476 foreach [def reloc] list [ 477 entry: make-struct nlist none 478 entry/n-strx: length? str-tbl 479 entry/n-type: to integer! defs/sym-type/n-undf or defs/sym-type/n-ext 480 entry/n-sect: 0 ;-- NO_SECT 481 entry/n-desc: (to integer! defs/sym-desc/undef-lazy) or shift/left lib 8 482 entry/n-value: 0 483 append sym-tbl form-struct entry 484 485 pointer/value: cnt 486 append dy-sym-tbl form-struct pointer 487 488 repend imports-refs [cnt * stub-size reloc] ;-- store symbol jump table offset 489 490 append str-tbl join "_" to-c-string def 491 cnt: cnt + 1 492 ] 493 lib: lib + 1 494 ] 495 repend job/sections [ 496 'jmptbl reduce [ 497 '- head insert/dup make binary! cnt * stub-size #{F4F4F4F4F4} cnt 498 ] 499 'symbols reduce [ 500 reduce [cnt length? sym-tbl length? dy-sym-tbl length? str-tbl] 501 rejoin [sym-tbl dy-sym-tbl str-tbl] 502 ] 503 ] 504 ] 505 506 build-dysymtab-command: func [job [object!] spec [block!] /local sc sym-info][ 507 sym-info: job/sections/symbols/1 508 509 sc: make-struct dysymtab-cmd none 510 sc/cmd: defs/load-type/dysymtab 511 sc/size: get-struct-size 'dysymtab 512 sc/ilocalsym: 0 513 sc/nlocalsym: 0 514 sc/iextdefsym: 0 515 sc/nextdefsym: 0 516 sc/iundefsym: 0 517 sc/nundefsym: sym-info/1 518 sc/tocoff: 0 519 sc/ntoc: 0 520 sc/modtaboff: 0 521 sc/nmodtab: 0 522 sc/extrefsymoff: 0 523 sc/nextrefsyms: 0 524 sc/indirectsymoff: (third get-segment-info '__LINKEDIT) + sym-info/2 525 sc/nindirectsyms: sym-info/1 526 sc/extreloff: 0 527 sc/nextrel: 0 528 sc/locreloff: 0 529 sc/nlocrel: 0 530 sc: form-struct sc 531 sc 532 ] 533 534 build-symtab-command: func [job [object!] spec [block!] /local sc sym-info][ 535 sym-info: job/sections/symbols/1 536 537 sc: make-struct symtab-cmd none 538 sc/cmd: defs/load-type/symtab 539 sc/size: get-struct-size 'symtab 540 sc/symoff: third get-segment-info '__LINKEDIT 541 sc/nsyms: sym-info/1 542 sc/stroff: sc/symoff + sym-info/2 + sym-info/3 543 sc/strsize: sym-info/4 544 sc: form-struct sc 545 sc 546 ] 547 548 build-lddylib-command: func [job [object!] spec [block!] /local lc][ 549 lc: make-struct load-dylib-cmd none 550 lc/cmd: defs/load-type/load_dylib 551 lc/size: (get-struct-size 'lddylib) + length? spec/2 552 lc/offset: 24 553 lc/timestamp: 2 554 lc/version: to integer! #{007D0000} ;-- 128.0.0 555 lc/compat: to integer! #{00000000} ;-- 0.0.0 @@ should be configurable 556 lc: form-struct lc 557 append lc spec/2 558 lc 559 ] 560 561 build-dylinker-command: func [job [object!] spec [block!] /local dl][ 562 dl: make-struct dylinker-cmd none 563 dl/cmd: defs/load-type/load_dylinker 564 dl/size: (get-struct-size 'dylinker) + length? spec/2 565 dl/offset: 12 566 dl: form-struct dl 567 append dl spec/2 568 dl 569 ] 570 571 build-uthread-command: func [job [object!] spec [block!] /local ut][ 572 ut: make-struct unix-thread-cmd none 573 ut/cmd: defs/load-type/unixthread 574 ut/size: get-struct-size 'uthread 575 ut/flavor: 1 ;-- x86_THREAD_STATE32 576 ut/count: 16 577 ut/eip: get-section-addr '__text 578 form-struct ut 579 ] 580 581 build-section-header: func [spec [block!] seg-name [word!] /local sh][ 582 sh: make-struct section-header none 583 sh/addr: spec/3 584 sh/size: spec/6 585 sh/offset: spec/5 586 sh/align: to integer! log-2 select [byte 1 word 4 dword 8] spec/9 ;-- 32/64-bit @@ 587 sh/reloff: 0 588 sh/nreloc: 0 589 sh/flags: get-flags spec/8 590 sh/reserved1: 0 591 sh/reserved2: either spec/2 = '__jump_table [stub-size][0] 592 sh: form-struct sh 593 change sh to-c-string spec/2 594 change at sh 17 to-c-string seg-name 595 sh 596 ] 597 598 build-segment-command: func [job [object!] spec [block!] /local sc][ 599 sc: make-struct segment-command none 600 sc/cmd: defs/load-type/segment 601 sc/size: segment-sz + (section-sz * sections? spec/10) 602 sc/vmaddr: spec/3 603 sc/vmsize: spec/4 604 sc/fileoff: spec/5 605 sc/filesize: spec/6 606 sc/maxprot: either empty? spec/7 [0][get-rights? [r w x]] 607 sc/initprot: get-rights? spec/7 608 sc/nsects: sections? spec/10 609 sc/flags: 4 ;-- SG_NORELOC 610 sc: form-struct sc 611 change at sc 9 to-c-string spec/2 612 sc 613 ] 614 615 build-mach-header: func [job [object!] /local mh][ 616 mh: make-struct mach-header none 617 mh/magic: to integer! #{FEEDFACE} 618 mh/cpu-type: 7 ;-- CPU_TYPE_I386 619 mh/cpu-sub-type: 3 ;-- CPU_SUBTYPE_I386_ALL 620 mh/file-type: defs/file-type/execute 621 mh/nb-cmds: load-cmds-nb 622 mh/sz-cmds: load-cmds-sz 623 mh/flags: defs/flags/noundefs 624 if dylink? [ 625 mh/flags: mh/flags 626 or defs/flags/dyldlink 627 or defs/flags/subsections 628 ;or defs/flags/bindatload 629 ] 630 form-struct mh 631 ] 632 633 build: func [ 634 job [object!] 635 /local 636 base-address dynamic-linker out sections 637 638 ] [ 639 base-address: any [job/base-address defs/base-address] 640 dynamic-linker: any [job/dynamic-linker ""] 641 642 dylink?: not empty? job/sections/import/3 643 644 clear imports-refs 645 if dylink? [build-imports job] 646 647 prepare-headers job 648 649 out: job/buffer 650 append out build-mach-header job 651 seg: segments 652 forskip seg 10 [ 653 append out switch seg/1 [ 654 segment [build-segment-command job seg] 655 uthread [build-uthread-command job seg] 656 dylinker [build-dylinker-command job seg] 657 lddylib [build-lddylib-command job seg] 658 symtab [build-symtab-command job seg] 659 dysymtab [build-dysymtab-command job seg] 660 ] 661 unless empty? sections: seg/10 [ 662 forskip sections 9 [ 663 append out build-section-header sections seg/2 664 ] 665 ] 666 ] 667 668 if dylink? [resolve-import-refs job] 669 resolve-data-refs job 670 671 emit-page-aligned out job/sections/code/2 672 emit-page-aligned out job/sections/data/2 673 674 if dylink? [ 675 emit-page-aligned out job/sections/jmptbl/2 676 emit-page-aligned out job/sections/symbols/2 677 ] 678 ] 679]