aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2024-04-19 00:31:06 +0200
committerMike Pall <mike>2024-04-19 00:31:06 +0200
commit7110b935672489afd6ba3eef3e5139d2f3bd05b6 (patch)
tree7b0fddd303f542c98151f987a9dc8db99c89dd0d
parentd2fe2a6d465a3e4c74c9876db94ae606f9c6983b (diff)
downloadluajit-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
-rw-r--r--src/jit/bcsave.lua155
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
442typedef struct { 442typedef 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;
448typedef 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;
454typedef struct { 448typedef 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;
460typedef 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 {
469typedef struct { 457typedef 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;
475typedef 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;
481typedef struct
482{
483 int32_t magic, nfat_arch;
484} mach_fat_header;
485typedef struct
486{
487 int32_t cputype, cpusubtype, offset, size, align;
488} mach_fat_arch;
489typedef 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;
499typedef struct { 463typedef 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;
509typedef 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;
521typedef 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