summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-02-11 17:58:06 +0100
committerMike Pall <mike>2013-02-11 17:58:06 +0100
commit339b77ee050389f0f28584d373c53bd3ed81e24a (patch)
tree637bcb1d38a90babeacba09f53f5f7db56ce5d48
parent250b24f93728e04851385cce5665eeae26dc60a1 (diff)
downloadluajit-339b77ee050389f0f28584d373c53bd3ed81e24a.tar.gz
luajit-339b77ee050389f0f28584d373c53bd3ed81e24a.tar.bz2
luajit-339b77ee050389f0f28584d373c53bd3ed81e24a.zip
OSX: Add support for Mach-O object files to -b option.
Thanks to Adam Strzelecki.
-rw-r--r--src/jit/bcsave.lua160
1 files changed, 159 insertions, 1 deletions
diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua
index 08e54454..1c511112 100644
--- a/src/jit/bcsave.lua
+++ b/src/jit/bcsave.lua
@@ -12,6 +12,7 @@
12 12
13local jit = require("jit") 13local jit = require("jit")
14assert(jit.version_num == 20000, "LuaJIT core/library version mismatch") 14assert(jit.version_num == 20000, "LuaJIT core/library version mismatch")
15local bit = require("bit")
15 16
16-- Symbol name prefix for LuaJIT bytecode. 17-- Symbol name prefix for LuaJIT bytecode.
17local LJBC_PREFIX = "luaJIT_BC_" 18local LJBC_PREFIX = "luaJIT_BC_"
@@ -398,7 +399,164 @@ typedef struct {
398end 399end
399 400
400local function bcsave_machobj(ctx, output, s, ffi) 401local function bcsave_machobj(ctx, output, s, ffi)
401 check(false, "NYI: no support for writing OSX object files") 402 ffi.cdef[[
403typedef struct
404{
405 uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
406} mach_header;
407typedef struct
408{
409 mach_header; uint32_t reserved;
410} mach_header_64;
411typedef struct {
412 uint32_t cmd, cmdsize;
413 char segname[16];
414 uint32_t vmaddr, vmsize, fileoff, filesize;
415 uint32_t maxprot, initprot, nsects, flags;
416} mach_segment_command;
417typedef struct {
418 uint32_t cmd, cmdsize;
419 char segname[16];
420 uint64_t vmaddr, vmsize, fileoff, filesize;
421 uint32_t maxprot, initprot, nsects, flags;
422} mach_segment_command_64;
423typedef struct {
424 char sectname[16], segname[16];
425 uint32_t addr, size;
426 uint32_t offset, align, reloff, nreloc, flags;
427 uint32_t reserved1, reserved2;
428} mach_section;
429typedef struct {
430 char sectname[16], segname[16];
431 uint64_t addr, size;
432 uint32_t offset, align, reloff, nreloc, flags;
433 uint32_t reserved1, reserved2, reserved3;
434} mach_section_64;
435typedef struct {
436 uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
437} mach_symtab_command;
438typedef struct {
439 int32_t strx;
440 uint8_t type, sect;
441 int16_t desc;
442 uint32_t value;
443} mach_nlist;
444typedef struct {
445 uint32_t strx;
446 uint8_t type, sect;
447 uint16_t desc;
448 uint64_t value;
449} mach_nlist_64;
450typedef struct
451{
452 uint32_t magic, nfat_arch;
453} mach_fat_header;
454typedef struct
455{
456 uint32_t cputype, cpusubtype, offset, size, align;
457} mach_fat_arch;
458typedef struct {
459 struct {
460 mach_header hdr;
461 mach_segment_command seg;
462 mach_section sec;
463 mach_symtab_command sym;
464 } arch[1];
465 mach_nlist sym_entry;
466 uint8_t space[4096];
467} mach_obj;
468typedef struct {
469 struct {
470 mach_header_64 hdr;
471 mach_segment_command_64 seg;
472 mach_section_64 sec;
473 mach_symtab_command sym;
474 } arch[1];
475 mach_nlist_64 sym_entry;
476 uint8_t space[4096];
477} mach_obj_64;
478typedef struct {
479 mach_fat_header fat;
480 mach_fat_arch fat_arch[4];
481 struct {
482 mach_header hdr;
483 mach_segment_command seg;
484 mach_section sec;
485 mach_symtab_command sym;
486 } arch[4];
487 mach_nlist sym_entry;
488 uint8_t space[4096];
489} mach_fat_obj;
490]]
491 local symname = '_'..LJBC_PREFIX..ctx.modname
492 local isfat, is64, align, mobj = false, false, 4, "mach_obj"
493 if ctx.arch == "x64" then
494 is64, align, mobj = true, 8, "mach_obj_64"
495 elseif ctx.arch == "arm" then
496 isfat, mobj = true, "mach_fat_obj"
497 else
498 check(ctx.arch == "x86", "unsupported architecture for OSX")
499 end
500 local function aligned(v, a) return bit.band(v+a-1, -a) end
501 local be32 = bit.bswap -- Mach-O FAT is BE, supported archs are LE.
502
503 -- Create Mach-O object and fill in header.
504 local o = ffi.new(mobj)
505 local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
506 local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12,12,12} })[ctx.arch]
507 local cpusubtype = ({ x86={3}, x64={3}, arm={3,6,9,11} })[ctx.arch]
508 if isfat then
509 o.fat.magic = be32(0xcafebabe)
510 o.fat.nfat_arch = be32(#cpusubtype)
511 end
512
513 -- Fill in sections and symbols.
514 for i=0,#cpusubtype-1 do
515 local ofs = 0
516 if isfat then
517 local a = o.fat_arch[i]
518 a.cputype = be32(cputype[i+1])
519 a.cpusubtype = be32(cpusubtype[i+1])
520 -- Subsequent slices overlap each other to share data.
521 ofs = ffi.offsetof(o, "arch") + i*ffi.sizeof(o.arch[0])
522 a.offset = be32(ofs)
523 a.size = be32(mach_size-ofs+#s)
524 end
525 local a = o.arch[i]
526 a.hdr.magic = is64 and 0xfeedfacf or 0xfeedface
527 a.hdr.cputype = cputype[i+1]
528 a.hdr.cpusubtype = cpusubtype[i+1]
529 a.hdr.filetype = 1
530 a.hdr.ncmds = 2
531 a.hdr.sizeofcmds = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)+ffi.sizeof(a.sym)
532 a.seg.cmd = is64 and 0x19 or 0x1
533 a.seg.cmdsize = ffi.sizeof(a.seg)+ffi.sizeof(a.sec)
534 a.seg.vmsize = #s
535 a.seg.fileoff = mach_size-ofs
536 a.seg.filesize = #s
537 a.seg.maxprot = 1
538 a.seg.initprot = 1
539 a.seg.nsects = 1
540 ffi.copy(a.sec.sectname, "__data")
541 ffi.copy(a.sec.segname, "__DATA")
542 a.sec.size = #s
543 a.sec.offset = mach_size-ofs
544 a.sym.cmd = 2
545 a.sym.cmdsize = ffi.sizeof(a.sym)
546 a.sym.symoff = ffi.offsetof(o, "sym_entry")-ofs
547 a.sym.nsyms = 1
548 a.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)-ofs
549 a.sym.strsize = aligned(#symname+2, align)
550 end
551 o.sym_entry.type = 0xf
552 o.sym_entry.sect = 1
553 o.sym_entry.strx = 1
554 ffi.copy(o.space+1, symname)
555
556 -- Write Macho-O object file.
557 local fp = savefile(output, "wb")
558 fp:write(ffi.string(o, mach_size))
559 bcsave_tail(fp, output, s)
402end 560end
403 561
404local function bcsave_obj(ctx, output, s) 562local function bcsave_obj(ctx, output, s)