diff options
| author | Mike Pall <mike> | 2024-04-19 00:31:06 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2024-04-19 00:31:06 +0200 |
| commit | 7110b935672489afd6ba3eef3e5139d2f3bd05b6 (patch) | |
| tree | 7b0fddd303f542c98151f987a9dc8db99c89dd0d /src | |
| parent | d2fe2a6d465a3e4c74c9876db94ae606f9c6983b (diff) | |
| download | luajit-7110b935672489afd6ba3eef3e5139d2f3bd05b6.tar.gz luajit-7110b935672489afd6ba3eef3e5139d2f3bd05b6.tar.bz2 luajit-7110b935672489afd6ba3eef3e5139d2f3bd05b6.zip | |
OSX/iOS: Always generate 64 bit non-FAT Mach-O object files.
Reported by Sergey Bronnikov. #1181
Diffstat (limited to 'src')
| -rw-r--r-- | src/jit/bcsave.lua | 155 |
1 files changed, 34 insertions, 121 deletions
diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua index 131bf39b..0d79a70e 100644 --- a/src/jit/bcsave.lua +++ b/src/jit/bcsave.lua | |||
| @@ -442,23 +442,11 @@ typedef struct | |||
| 442 | typedef struct { | 442 | typedef struct { |
| 443 | uint32_t cmd, cmdsize; | 443 | uint32_t cmd, cmdsize; |
| 444 | char segname[16]; | 444 | char segname[16]; |
| 445 | uint32_t vmaddr, vmsize, fileoff, filesize; | ||
| 446 | uint32_t maxprot, initprot, nsects, flags; | ||
| 447 | } mach_segment_command; | ||
| 448 | typedef struct { | ||
| 449 | uint32_t cmd, cmdsize; | ||
| 450 | char segname[16]; | ||
| 451 | uint64_t vmaddr, vmsize, fileoff, filesize; | 445 | uint64_t vmaddr, vmsize, fileoff, filesize; |
| 452 | uint32_t maxprot, initprot, nsects, flags; | 446 | uint32_t maxprot, initprot, nsects, flags; |
| 453 | } mach_segment_command_64; | 447 | } mach_segment_command_64; |
| 454 | typedef struct { | 448 | typedef struct { |
| 455 | char sectname[16], segname[16]; | 449 | char sectname[16], segname[16]; |
| 456 | uint32_t addr, size; | ||
| 457 | uint32_t offset, align, reloff, nreloc, flags; | ||
| 458 | uint32_t reserved1, reserved2; | ||
| 459 | } mach_section; | ||
| 460 | typedef struct { | ||
| 461 | char sectname[16], segname[16]; | ||
| 462 | uint64_t addr, size; | 450 | uint64_t addr, size; |
| 463 | uint32_t offset, align, reloff, nreloc, flags; | 451 | uint32_t offset, align, reloff, nreloc, flags; |
| 464 | uint32_t reserved1, reserved2, reserved3; | 452 | uint32_t reserved1, reserved2, reserved3; |
| @@ -469,130 +457,55 @@ typedef struct { | |||
| 469 | typedef struct { | 457 | typedef struct { |
| 470 | int32_t strx; | 458 | int32_t strx; |
| 471 | uint8_t type, sect; | 459 | uint8_t type, sect; |
| 472 | int16_t desc; | ||
| 473 | uint32_t value; | ||
| 474 | } mach_nlist; | ||
| 475 | typedef struct { | ||
| 476 | int32_t strx; | ||
| 477 | uint8_t type, sect; | ||
| 478 | uint16_t desc; | 460 | uint16_t desc; |
| 479 | uint64_t value; | 461 | uint64_t value; |
| 480 | } mach_nlist_64; | 462 | } mach_nlist_64; |
| 481 | typedef struct | ||
| 482 | { | ||
| 483 | int32_t magic, nfat_arch; | ||
| 484 | } mach_fat_header; | ||
| 485 | typedef struct | ||
| 486 | { | ||
| 487 | int32_t cputype, cpusubtype, offset, size, align; | ||
| 488 | } mach_fat_arch; | ||
| 489 | typedef struct { | ||
| 490 | struct { | ||
| 491 | mach_header hdr; | ||
| 492 | mach_segment_command seg; | ||
| 493 | mach_section sec; | ||
| 494 | mach_symtab_command sym; | ||
| 495 | } arch[1]; | ||
| 496 | mach_nlist sym_entry; | ||
| 497 | uint8_t space[4096]; | ||
| 498 | } mach_obj; | ||
| 499 | typedef struct { | 463 | typedef struct { |
| 500 | struct { | 464 | mach_header_64 hdr; |
| 501 | mach_header_64 hdr; | 465 | mach_segment_command_64 seg; |
| 502 | mach_segment_command_64 seg; | 466 | mach_section_64 sec; |
| 503 | mach_section_64 sec; | 467 | mach_symtab_command sym; |
| 504 | mach_symtab_command sym; | ||
| 505 | } arch[1]; | ||
| 506 | mach_nlist_64 sym_entry; | 468 | mach_nlist_64 sym_entry; |
| 507 | uint8_t space[4096]; | 469 | uint8_t space[4096]; |
| 508 | } mach_obj_64; | 470 | } mach_obj_64; |
| 509 | typedef struct { | ||
| 510 | mach_fat_header fat; | ||
| 511 | mach_fat_arch fat_arch[2]; | ||
| 512 | struct { | ||
| 513 | mach_header hdr; | ||
| 514 | mach_segment_command seg; | ||
| 515 | mach_section sec; | ||
| 516 | mach_symtab_command sym; | ||
| 517 | } arch[2]; | ||
| 518 | mach_nlist sym_entry; | ||
| 519 | uint8_t space[4096]; | ||
| 520 | } mach_fat_obj; | ||
| 521 | typedef struct { | ||
| 522 | mach_fat_header fat; | ||
| 523 | mach_fat_arch fat_arch[2]; | ||
| 524 | struct { | ||
| 525 | mach_header_64 hdr; | ||
| 526 | mach_segment_command_64 seg; | ||
| 527 | mach_section_64 sec; | ||
| 528 | mach_symtab_command sym; | ||
| 529 | } arch[2]; | ||
| 530 | mach_nlist_64 sym_entry; | ||
| 531 | uint8_t space[4096]; | ||
| 532 | } mach_fat_obj_64; | ||
| 533 | ]] | 471 | ]] |
| 534 | local symname = '_'..LJBC_PREFIX..ctx.modname | 472 | local symname = '_'..LJBC_PREFIX..ctx.modname |
| 535 | local isfat, is64, align, mobj = false, false, 4, "mach_obj" | 473 | local cputype, cpusubtype = 0x01000007, 3 |
| 536 | if ctx.arch == "x64" then | 474 | if ctx.arch ~= "x64" then |
| 537 | is64, align, mobj = true, 8, "mach_obj_64" | 475 | check(ctx.arch == "arm64", "unsupported architecture for OSX") |
| 538 | elseif ctx.arch == "arm" then | 476 | cputype, cpusubtype = 0x0100000c, 0 |
| 539 | isfat, mobj = true, "mach_fat_obj" | ||
| 540 | elseif ctx.arch == "arm64" then | ||
| 541 | is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64" | ||
| 542 | else | ||
| 543 | check(ctx.arch == "x86", "unsupported architecture for OSX") | ||
| 544 | end | 477 | end |
| 545 | local function aligned(v, a) return bit.band(v+a-1, -a) end | 478 | local function aligned(v, a) return bit.band(v+a-1, -a) end |
| 546 | local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE. | ||
| 547 | 479 | ||
| 548 | -- Create Mach-O object and fill in header. | 480 | -- Create Mach-O object and fill in header. |
| 549 | local o = ffi.new(mobj) | 481 | local o = ffi.new("mach_obj_64") |
| 550 | local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align) | 482 | local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8) |
| 551 | local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch] | ||
| 552 | local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch] | ||
| 553 | if isfat then | ||
| 554 | o.fat.magic = be32(0xcafebabe) | ||
| 555 | o.fat.nfat_arch = be32(#cpusubtype) | ||
| 556 | end | ||
| 557 | 483 | ||
| 558 | -- Fill in sections and symbols. | 484 | -- Fill in sections and symbols. |
| 559 | for i=0,#cpusubtype-1 do | 485 | o.hdr.magic = 0xfeedfacf |
| 560 | local ofs = 0 | 486 | o.hdr.cputype = cputype |
| 561 | if isfat then | 487 | o.hdr.cpusubtype = cpusubtype |
| 562 | local a = o.fat_arch[i] | 488 | o.hdr.filetype = 1 |
| 563 | a.cputype = be32(cputype[i+1]) | 489 | o.hdr.ncmds = 2 |
| 564 | a.cpusubtype = be32(cpusubtype[i+1]) | 490 | o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym) |
| 565 | -- Subsequent slices overlap each other to share data. | 491 | o.seg.cmd = 0x19 |
| 566 | ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0]) | 492 | o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec) |
| 567 | a.offset = be32(ofs) | 493 | o.seg.vmsize = #s |
| 568 | a.size = be32(mach_size-ofs+#s) | 494 | o.seg.fileoff = mach_size |
| 569 | end | 495 | o.seg.filesize = #s |
| 570 | local a = o.arch[i] | 496 | o.seg.maxprot = 1 |
| 571 | a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface | 497 | o.seg.initprot = 1 |
| 572 | a.hdr.cputype = cputype[i+1] | 498 | o.seg.nsects = 1 |
| 573 | a.hdr.cpusubtype = cpusubtype[i+1] | 499 | ffi.copy(o.sec.sectname, "__data") |
| 574 | a.hdr.filetype = 1 | 500 | ffi.copy(o.sec.segname, "__DATA") |
| 575 | a.hdr.ncmds = 2 | 501 | o.sec.size = #s |
| 576 | a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym) | 502 | o.sec.offset = mach_size |
| 577 | a.seg.cmd = is64 and 0x19 or 0x1 | 503 | o.sym.cmd = 2 |
| 578 | a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec) | 504 | o.sym.cmdsize = ffi.sizeof(o.sym) |
| 579 | a.seg.vmsize = #s | 505 | o.sym.symoff = ffi.offsetof(o, "sym_entry") |
| 580 | a.seg.fileoff = mach_size-ofs | 506 | o.sym.nsyms = 1 |
| 581 | a.seg.filesize = #s | 507 | o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry) |
| 582 | a.seg.maxprot = 1 | 508 | o.sym.strsize = aligned(#symname+2, 8) |
| 583 | a.seg.initprot = 1 | ||
| 584 | a.seg.nsects = 1 | ||
| 585 | ffi.copy(a.sec.sectname, "__data") | ||
| 586 | ffi.copy(a.sec.segname, "__DATA") | ||
| 587 | a.sec.size = #s | ||
| 588 | a.sec.offset = mach_size-ofs | ||
| 589 | a.sym.cmd = 2 | ||
| 590 | a.sym.cmdsize = ffi.sizeof(a.sym) | ||
| 591 | a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs | ||
| 592 | a.sym.nsyms = 1 | ||
| 593 | a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs | ||
| 594 | a.sym.strsize = aligned(#symname+2, align) | ||
| 595 | end | ||
| 596 | o.sym_entry.type = 0xf | 509 | o.sym_entry.type = 0xf |
| 597 | o.sym_entry.sect = 1 | 510 | o.sym_entry.sect = 1 |
| 598 | o.sym_entry.strx = 1 | 511 | o.sym_entry.strx = 1 |
