diff options
author | Mike Pall <mike> | 2014-12-08 01:58:05 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2014-12-08 01:58:05 +0100 |
commit | e03df1e3395bc719d43bd9196d0290757f992b2f (patch) | |
tree | 98a2a827c4b83900e7b330d82c5d369caf642db4 /src | |
parent | f49c61a2776ae9abeb2297dbc3b53ea2962ad750 (diff) | |
download | luajit-e03df1e3395bc719d43bd9196d0290757f992b2f.tar.gz luajit-e03df1e3395bc719d43bd9196d0290757f992b2f.tar.bz2 luajit-e03df1e3395bc719d43bd9196d0290757f992b2f.zip |
x86/x64: Call external symbols directly from interpreter code.
Except for ELF/x86 PIC, where it's easier to use wrappers.
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 2 | ||||
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/host/buildvm.c | 1 | ||||
-rw-r--r-- | src/host/buildvm.h | 1 | ||||
-rw-r--r-- | src/host/buildvm_asm.c | 23 | ||||
-rw-r--r-- | src/lj_vmmath.c | 14 | ||||
-rw-r--r-- | src/vm_x86.dasc | 16 |
7 files changed, 43 insertions, 18 deletions
diff --git a/src/.gitignore b/src/.gitignore index fc94e82c..1a30573c 100644 --- a/src/.gitignore +++ b/src/.gitignore | |||
@@ -4,4 +4,4 @@ lj_ffdef.h | |||
4 | lj_libdef.h | 4 | lj_libdef.h |
5 | lj_recdef.h | 5 | lj_recdef.h |
6 | lj_folddef.h | 6 | lj_folddef.h |
7 | lj_vm.s | 7 | lj_vm.[sS] |
diff --git a/src/Makefile b/src/Makefile index fae4c7ba..1d6145d8 100644 --- a/src/Makefile +++ b/src/Makefile | |||
@@ -439,7 +439,7 @@ BUILDVM_X= $(BUILDVM_T) | |||
439 | HOST_O= $(MINILUA_O) $(BUILDVM_O) | 439 | HOST_O= $(MINILUA_O) $(BUILDVM_O) |
440 | HOST_T= $(MINILUA_T) $(BUILDVM_T) | 440 | HOST_T= $(MINILUA_T) $(BUILDVM_T) |
441 | 441 | ||
442 | LJVM_S= lj_vm.s | 442 | LJVM_S= lj_vm.S |
443 | LJVM_O= lj_vm.o | 443 | LJVM_O= lj_vm.o |
444 | LJVM_BOUT= $(LJVM_S) | 444 | LJVM_BOUT= $(LJVM_S) |
445 | LJVM_MODE= elfasm | 445 | LJVM_MODE= elfasm |
@@ -647,7 +647,7 @@ lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c | |||
647 | $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $< | 647 | $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $< |
648 | $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $< | 648 | $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $< |
649 | 649 | ||
650 | %.o: %.s | 650 | %.o: %.S |
651 | $(E) "ASM $@" | 651 | $(E) "ASM $@" |
652 | $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $< | 652 | $(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $< |
653 | $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $< | 653 | $(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $< |
diff --git a/src/host/buildvm.c b/src/host/buildvm.c index 37b20ae2..d56c65ca 100644 --- a/src/host/buildvm.c +++ b/src/host/buildvm.c | |||
@@ -179,6 +179,7 @@ static int build_code(BuildCtx *ctx) | |||
179 | ctx->nreloc = 0; | 179 | ctx->nreloc = 0; |
180 | 180 | ||
181 | ctx->globnames = globnames; | 181 | ctx->globnames = globnames; |
182 | ctx->extnames = extnames; | ||
182 | ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *)); | 183 | ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *)); |
183 | ctx->nrelocsym = 0; | 184 | ctx->nrelocsym = 0; |
184 | for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1; | 185 | for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1; |
diff --git a/src/host/buildvm.h b/src/host/buildvm.h index f9dc8c4f..b321bbda 100644 --- a/src/host/buildvm.h +++ b/src/host/buildvm.h | |||
@@ -82,6 +82,7 @@ typedef struct BuildCtx { | |||
82 | const char *beginsym; | 82 | const char *beginsym; |
83 | /* Strings generated by DynASM. */ | 83 | /* Strings generated by DynASM. */ |
84 | const char *const *globnames; | 84 | const char *const *globnames; |
85 | const char *const *extnames; | ||
85 | const char *dasm_ident; | 86 | const char *dasm_ident; |
86 | const char *dasm_arch; | 87 | const char *dasm_arch; |
87 | /* Relocations. */ | 88 | /* Relocations. */ |
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 079e9a80..c91f5bcd 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c | |||
@@ -51,8 +51,8 @@ static const char *const jccnames[] = { | |||
51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" | 51 | "js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg" |
52 | }; | 52 | }; |
53 | 53 | ||
54 | /* Emit relocation for the incredibly stupid OSX assembler. */ | 54 | /* Emit x86/x64 text relocations. */ |
55 | static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n, | 55 | static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n, |
56 | const char *sym) | 56 | const char *sym) |
57 | { | 57 | { |
58 | const char *opname = NULL; | 58 | const char *opname = NULL; |
@@ -71,6 +71,20 @@ err: | |||
71 | exit(1); | 71 | exit(1); |
72 | } | 72 | } |
73 | emit_asm_bytes(ctx, cp, n); | 73 | emit_asm_bytes(ctx, cp, n); |
74 | if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) { | ||
75 | /* Various fixups for external symbols outside of our binary. */ | ||
76 | if (ctx->mode == BUILD_elfasm) { | ||
77 | if (LJ_32) | ||
78 | fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym); | ||
79 | fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym); | ||
80 | if (LJ_32) | ||
81 | fprintf(ctx->fp, "#endif\n"); | ||
82 | return; | ||
83 | } else if (LJ_32 && ctx->mode == BUILD_machasm) { | ||
84 | fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym); | ||
85 | return; | ||
86 | } | ||
87 | } | ||
74 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); | 88 | fprintf(ctx->fp, "\t%s %s\n", opname, sym); |
75 | } | 89 | } |
76 | #else | 90 | #else |
@@ -254,8 +268,9 @@ void emit_asm(BuildCtx *ctx) | |||
254 | BuildReloc *r = &ctx->reloc[rel]; | 268 | BuildReloc *r = &ctx->reloc[rel]; |
255 | int n = r->ofs - ofs; | 269 | int n = r->ofs - ofs; |
256 | #if LJ_TARGET_X86ORX64 | 270 | #if LJ_TARGET_X86ORX64 |
257 | if (ctx->mode == BUILD_machasm && r->type != 0) { | 271 | if (r->type != 0 && |
258 | emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | 272 | (ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) { |
273 | emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]); | ||
259 | } else { | 274 | } else { |
260 | emit_asm_bytes(ctx, ctx->code+ofs, n); | 275 | emit_asm_bytes(ctx, ctx->code+ofs, n); |
261 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); | 276 | emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]); |
diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c index 63886aa7..b60858b2 100644 --- a/src/lj_vmmath.c +++ b/src/lj_vmmath.c | |||
@@ -13,15 +13,17 @@ | |||
13 | #include "lj_ir.h" | 13 | #include "lj_ir.h" |
14 | #include "lj_vm.h" | 14 | #include "lj_vm.h" |
15 | 15 | ||
16 | /* -- Helper functions for generated machine code ------------------------- */ | 16 | /* -- Wrapper functions --------------------------------------------------- */ |
17 | 17 | ||
18 | #if LJ_TARGET_X86ORX64 | 18 | #if LJ_TARGET_X86 && __ELF__ && __PIC__ |
19 | /* Wrapper functions to avoid linker issues on OSX. */ | 19 | /* Wrapper functions to deal with the ELF/x86 PIC disaster. */ |
20 | LJ_FUNCA double lj_vm_sinh(double x) { return sinh(x); } | 20 | LJ_FUNCA double lj_wrap_sinh(double x) { return sinh(x); } |
21 | LJ_FUNCA double lj_vm_cosh(double x) { return cosh(x); } | 21 | LJ_FUNCA double lj_wrap_cosh(double x) { return cosh(x); } |
22 | LJ_FUNCA double lj_vm_tanh(double x) { return tanh(x); } | 22 | LJ_FUNCA double lj_wrap_tanh(double x) { return tanh(x); } |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | /* -- Helper functions for generated machine code ------------------------- */ | ||
26 | |||
25 | #if !LJ_TARGET_X86ORX64 | 27 | #if !LJ_TARGET_X86ORX64 |
26 | double lj_vm_foldarith(double x, double y, int op) | 28 | double lj_vm_foldarith(double x, double y, int op) |
27 | { | 29 | { |
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index a0c7cc60..cd43afbd 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc | |||
@@ -2084,7 +2084,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
2084 | | movsd FPARG1, xmm0 | 2084 | | movsd FPARG1, xmm0 |
2085 | |.endif | 2085 | |.endif |
2086 | | mov RB, BASE | 2086 | | mov RB, BASE |
2087 | | call extern lj_vm_ .. func | 2087 | | call extern func |
2088 | | mov BASE, RB | 2088 | | mov BASE, RB |
2089 | |.if X64 | 2089 | |.if X64 |
2090 | | jmp ->fff_resxmm0 | 2090 | | jmp ->fff_resxmm0 |
@@ -5962,15 +5962,21 @@ static void emit_asm_debug(BuildCtx *ctx) | |||
5962 | "LEFDEY:\n\n", fcsize); | 5962 | "LEFDEY:\n\n", fcsize); |
5963 | } | 5963 | } |
5964 | #endif | 5964 | #endif |
5965 | #if LJ_64 | 5965 | #if !LJ_64 |
5966 | fprintf(ctx->fp, "\t.subsections_via_symbols\n"); | ||
5967 | #else | ||
5968 | fprintf(ctx->fp, | 5966 | fprintf(ctx->fp, |
5969 | "\t.non_lazy_symbol_pointer\n" | 5967 | "\t.non_lazy_symbol_pointer\n" |
5970 | "L_lj_err_unwind_dwarf$non_lazy_ptr:\n" | 5968 | "L_lj_err_unwind_dwarf$non_lazy_ptr:\n" |
5971 | ".indirect_symbol _lj_err_unwind_dwarf\n" | 5969 | ".indirect_symbol _lj_err_unwind_dwarf\n" |
5972 | ".long 0\n"); | 5970 | ".long 0\n\n"); |
5971 | fprintf(ctx->fp, "\t.section __IMPORT,__jump_table,symbol_stubs,pure_instructions+self_modifying_code,5\n"); | ||
5972 | { | ||
5973 | const char *const *xn; | ||
5974 | for (xn = ctx->extnames; *xn; xn++) | ||
5975 | if (strncmp(*xn, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) | ||
5976 | fprintf(ctx->fp, "L_%s$stub:\n\t.indirect_symbol _%s\n\t.ascii \"\\364\\364\\364\\364\\364\"\n", *xn, *xn); | ||
5977 | } | ||
5973 | #endif | 5978 | #endif |
5979 | fprintf(ctx->fp, ".subsections_via_symbols\n"); | ||
5974 | } | 5980 | } |
5975 | break; | 5981 | break; |
5976 | default: /* Difficult for other modes. */ | 5982 | default: /* Difficult for other modes. */ |