From 27eab0b83688f20b3b8282b6a31e8a54bbada17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Herczeg?= Date: Thu, 5 Jan 2017 10:01:29 +0000 Subject: [PATCH] JIT compiler update. --- src/sljit/sljitLir.c | 35 ++++------- src/sljit/sljitLir.h | 34 +++++++---- src/sljit/sljitNativeARM_32.c | 93 +++++++++++++++++------------ src/sljit/sljitNativeARM_64.c | 38 +++++++----- src/sljit/sljitNativeARM_T2_32.c | 40 ++++++++----- src/sljit/sljitNativeMIPS_32.c | 14 +++-- src/sljit/sljitNativeMIPS_64.c | 18 +++--- src/sljit/sljitNativeMIPS_common.c | 35 ++++++----- src/sljit/sljitNativePPC_32.c | 14 +++-- src/sljit/sljitNativePPC_64.c | 14 +++-- src/sljit/sljitNativePPC_common.c | 46 ++++++++------ src/sljit/sljitNativeSPARC_32.c | 14 +++-- src/sljit/sljitNativeSPARC_common.c | 33 ++++++---- src/sljit/sljitNativeTILEGX_64.c | 10 ++-- src/sljit/sljitNativeX86_32.c | 4 +- src/sljit/sljitNativeX86_common.c | 25 +++++--- 16 files changed, 271 insertions(+), 196 deletions(-) diff --git a/src/sljit/sljitLir.c b/src/sljit/sljitLir.c index a6ecc01..6b3f4eb 100644 --- a/src/sljit/sljitLir.c +++ b/src/sljit/sljitLir.c @@ -251,6 +251,12 @@ #endif +#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) +#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset)) +#else +#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) +#endif + /* Argument checking features. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -289,13 +295,6 @@ } \ } while (0) -#define CHECK_DYN_CODE_MOD(extra_check) \ - if ((extra_check) && !sljit_is_dyn_code_modification_enabled()) \ - { \ - compiler->error = SLJIT_ERR_DYN_CODE_MOD; \ - return NULL; \ - } - #elif (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Assertion failure occures if an invalid argument is passed. */ @@ -308,7 +307,6 @@ #define CHECK(x) x #define CHECK_PTR(x) x #define CHECK_REG_INDEX(x) x -#define CHECK_DYN_CODE_MOD(extra_check) SLJIT_ASSERT(!(extra_check) || sljit_is_dyn_code_modification_enabled()) #elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -318,7 +316,6 @@ #define CHECK(x) x #define CHECK_PTR(x) x #define CHECK_REG_INDEX(x) x -#define CHECK_DYN_CODE_MOD(extra_check) #else @@ -326,7 +323,6 @@ #define CHECK(x) #define CHECK_PTR(x) #define CHECK_REG_INDEX(x) -#define CHECK_DYN_CODE_MOD(extra_check) #endif /* SLJIT_ARGUMENT_CHECKS */ @@ -457,15 +453,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi compiler->error = SLJIT_ERR_ALLOC_FAILED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void) -{ -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \ - && (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) - return 0; -#endif - return 1; -} - #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { @@ -1626,7 +1613,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler sljit_sw tmp_srcw; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); condition = type & 0xff; @@ -1707,7 +1693,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile sljit_s32 flags, condition; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); condition = type & 0xff; @@ -2055,17 +2040,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return NULL; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_addr); + SLJIT_UNUSED_ARG(new_target); + SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(addr); SLJIT_UNUSED_ARG(new_constant); + SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT_STOP(); } diff --git a/src/sljit/sljitLir.h b/src/sljit/sljitLir.h index facddb6..f24f556 100644 --- a/src/sljit/sljitLir.h +++ b/src/sljit/sljitLir.h @@ -325,7 +325,9 @@ struct sljit_compiler { sljit_s32 local_size; /* Code size. */ sljit_uw size; - /* For statistical purposes. */ + /* Relative offset of the executable mapping from the writable mapping. */ + sljit_uw executable_offset; + /* Executable size for statistical purposes. */ sljit_uw executable_size; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -457,10 +459,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); #endif -/* Returns with non-zero if dynamic code modification is enabled. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void); - /* Create executable code from the sljit instruction stream. This is the final step of the code generation so no more instructions can be added after this call. @@ -473,10 +471,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); /* - After the machine code generation is finished we can retrieve the allocated - executable memory size, although this area may not be fully filled with - instructions depending on some optimizations. This function is useful only - for statistical purposes. + When the protected executable allocator is used the JIT code is mapped + twice. The first mapping has read/write and the second mapping has read/exec + permissions. This function returns with the relative offset of the executable + mapping using the writable mapping as the base after the machine code is + successfully generated. The returned value is always 0 for the normal executable + allocator, since it uses only one mapping with read/write/exec permissions. + Dynamic code modifications requires this value. + + Before a successful code generation, this function returns with 0. +*/ +static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; } + +/* + The executable memory consumption of the generated code can be retrieved by + this function. The returned value can be used for statistical purposes. Before a successful code generation, this function returns with 0. */ @@ -1100,9 +1109,10 @@ static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { r static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; } -/* Only the address is required to rewrite the code. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant); +/* Only the address and executable offset are required to perform dynamic + code modifications. See sljit_get_executable_offset function. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset); +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset); /* --------------------------------------------------------------------- */ /* Miscellaneous utility functions */ diff --git a/src/sljit/sljitNativeARM_32.c b/src/sljit/sljitNativeARM_32.c index 5a82a60..09701d5 100644 --- a/src/sljit/sljitNativeARM_32.c +++ b/src/sljit/sljitNativeARM_32.c @@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s3 #endif -static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset) { sljit_sw diff; @@ -401,7 +401,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw code_ptr--; if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); + diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); @@ -426,7 +426,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw } #else if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr); + diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr); @@ -446,26 +446,28 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw return 0; } -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_s32 flush) +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw*)addr; - sljit_uw *inst = (sljit_uw*)ptr[0]; + sljit_uw *ptr = (sljit_uw *)jump_ptr; + sljit_uw *inst = (sljit_uw *)ptr[0]; sljit_uw mov_pc = ptr[1]; sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); - sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); + sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2); if (diff <= 0x7fffff && diff >= -0x800000) { /* Turn to branch. */ if (!bl) { inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); inst[1] = NOP; - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -479,12 +481,14 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, if (*inst != mov_pc) { inst[0] = mov_pc; if (!bl) { - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[1] = BLX | RM(TMP_REG1); - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -492,11 +496,12 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, *ptr = new_addr; } #else - sljit_uw *inst = (sljit_uw*)addr; + sljit_uw *inst = (sljit_uw*)jump_ptr; SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } #endif @@ -504,7 +509,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, static sljit_uw get_imm(sljit_uw imm); -static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_s32 flush) +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_sw new_constant, sljit_s32 flush_cache) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; @@ -515,7 +520,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, src2 = get_imm(new_constant); if (src2) { *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -524,7 +530,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, src2 = get_imm(~new_constant); if (src2) { *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -537,7 +544,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, if (*inst != ldr_literal) { *inst = ldr_literal; - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } @@ -547,7 +555,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); - if (flush) { + if (flush_cache) { + inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } #endif @@ -562,6 +571,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_uw *buf_end; sljit_uw size; sljit_uw word_count; + sljit_sw executable_offset; + sljit_sw jump_addr; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw cpool_size; sljit_uw cpool_skip_alignment; @@ -602,14 +613,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; if (label && label->size == 0) { - label->addr = (sljit_uw)code; - label->size = 0; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); label = label->next; } @@ -636,7 +647,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil cpool_size = 0; if (label && label->size == word_count) { /* Points after the current instruction. */ - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -652,19 +663,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!const_ || const_->addr >= word_count); if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (detect_jump_type(jump, code_ptr, code)) + if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr--; jump->addr = (sljit_uw)code_ptr; #else jump->addr = (sljit_uw)(code_ptr - 2); - if (detect_jump_type(jump, code_ptr, code)) + if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr -= 2; #endif jump = jump->next; } if (label && label->size == word_count) { /* code_ptr can be affected above. */ - label->addr = (sljit_uw)(code_ptr + 1); + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); label->size = (code_ptr + 1) - code; label = label->next; } @@ -729,17 +740,18 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { - buf_ptr = (sljit_uw*)jump->addr; + buf_ptr = (sljit_uw *)jump->addr; if (jump->flags & PATCH_B) { + jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); if (!(jump->flags & JUMP_ADDR)) { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff; } else { - SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff; } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { @@ -747,10 +759,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump->addr = (sljit_uw)code_ptr; code_ptr[0] = (sljit_uw)buf_ptr; code_ptr[1] = *buf_ptr; - inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); code_ptr += 2; #else - inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); #endif } else { @@ -763,7 +775,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr += 1; *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; #else - inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); #endif } jump = jump->next; @@ -782,7 +794,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else buf_ptr += 1; /* Set the value again (can be a simple constant). */ - inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0); + inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0); code_ptr += 2; const_ = const_->next; @@ -792,7 +804,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size); compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); + + code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + SLJIT_CACHE_FLUSH(code, code_ptr); return code; } @@ -2402,7 +2419,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile struct sljit_jump *jump; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -2535,7 +2551,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi sljit_s32 reg; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2557,12 +2572,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { - inline_set_jump_addr(addr, new_addr, 1); + inline_set_jump_addr(addr, executable_offset, new_target, 1); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - inline_set_const(addr, new_constant, 1); + inline_set_const(addr, executable_offset, new_constant, 1); } diff --git a/src/sljit/sljitNativeARM_64.c b/src/sljit/sljitNativeARM_64.c index 71f7c73..2062d80 100644 --- a/src/sljit/sljitNativeARM_64.c +++ b/src/sljit/sljitNativeARM_64.c @@ -151,7 +151,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); } -static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; @@ -165,9 +165,10 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4); + + diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset; if (jump->flags & IS_COND) { diff += sizeof(sljit_ins); @@ -211,6 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_sw executable_offset; sljit_uw addr; sljit_s32 dst; @@ -228,6 +230,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); + label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; @@ -242,13 +246,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!jump || jump->addr >= word_count); SLJIT_ASSERT(!const_ || const_->addr >= word_count); if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } if (jump && jump->addr == word_count) { jump->addr = (sljit_uw)(code_ptr - 4); - code_ptr -= detect_jump_type(jump, code_ptr, code); + code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); jump = jump->next; } if (const_ && const_->addr == word_count) { @@ -263,7 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } while (buf); if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -277,9 +281,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; + buf_ptr = (sljit_ins *)jump->addr; + if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - jump->addr) >> 2; + addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000); buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff); if (jump->flags & IS_COND) @@ -287,7 +292,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil break; } if (jump->flags & PATCH_COND) { - addr = (sljit_sw)(addr - jump->addr) >> 2; + addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000); buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5); break; @@ -308,7 +313,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + + code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + SLJIT_CACHE_FLUSH(code, code_ptr); return code; } @@ -1882,7 +1892,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile struct sljit_jump *jump; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -2021,7 +2030,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2037,16 +2045,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins* inst = (sljit_ins*)addr; - modify_imm64_const(inst, new_addr); + modify_imm64_const(inst, new_target); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { sljit_ins* inst = (sljit_ins*)addr; modify_imm64_const(inst, new_constant); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } diff --git a/src/sljit/sljitNativeARM_T2_32.c b/src/sljit/sljitNativeARM_T2_32.c index 4b864c0..95afc52 100644 --- a/src/sljit/sljitNativeARM_T2_32.c +++ b/src/sljit/sljitNativeARM_T2_32.c @@ -221,7 +221,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm) inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); } -static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset) { sljit_sw diff; @@ -232,7 +232,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u1 /* Branch to ARM code is not optimized yet. */ if (!(jump->u.target & 0x1)) return 0; - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; + diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1; } else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); @@ -276,7 +276,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u1 return 0; } -static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) +static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset) { sljit_s32 type = (jump->flags >> 4) & 0xf; sljit_sw diff; @@ -290,10 +290,12 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) if (jump->flags & JUMP_ADDR) { SLJIT_ASSERT(jump->u.target & 0x1); - diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; + diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1; + } + else { + SLJIT_ASSERT(jump->u.label->addr & 0x1); + diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1; } - else - diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; jump_inst = (sljit_u16*)jump->addr; switch (type) { @@ -347,6 +349,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_u16 *buf_ptr; sljit_u16 *buf_end; sljit_uw half_count; + sljit_sw executable_offset; struct sljit_label *label; struct sljit_jump *jump; @@ -362,6 +365,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; half_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); + label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; @@ -376,13 +381,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!jump || jump->addr >= half_count); SLJIT_ASSERT(!const_ || const_->addr >= half_count); if (label && label->size == half_count) { - label->addr = ((sljit_uw)code_ptr) | 0x1; + label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1; label->size = code_ptr - code; label = label->next; } if (jump && jump->addr == half_count) { jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); - code_ptr -= detect_jump_type(jump, code_ptr, code); + code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); jump = jump->next; } if (const_ && const_->addr == half_count) { @@ -397,7 +402,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } while (buf); if (label && label->size == half_count) { - label->addr = ((sljit_uw)code_ptr) | 0x1; + label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1; label->size = code_ptr - code; label = label->next; } @@ -409,12 +414,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { - set_jump_instruction(jump); + set_jump_instruction(jump, executable_offset); jump = jump->next; } compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16); + + code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + SLJIT_CACHE_FLUSH(code, code_ptr); /* Set thumb mode flag. */ return (void*)((sljit_uw)code | 0x1); @@ -1917,7 +1927,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile sljit_ins cc; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -2061,7 +2070,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi sljit_s32 dst_r; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2077,16 +2085,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_u16 *inst = (sljit_u16*)addr; - modify_imm32_const(inst, new_addr); + modify_imm32_const(inst, new_target); + inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { sljit_u16 *inst = (sljit_u16*)addr; modify_imm32_const(inst, new_constant); + inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 4); } diff --git a/src/sljit/sljitNativeMIPS_32.c b/src/sljit/sljitNativeMIPS_32.c index 5096e4f..b15a57d 100644 --- a/src/sljit/sljitNativeMIPS_32.c +++ b/src/sljit/sljitNativeMIPS_32.c @@ -347,20 +347,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } diff --git a/src/sljit/sljitNativeMIPS_64.c b/src/sljit/sljitNativeMIPS_64.c index c7ee8c9..8b96d5b 100644 --- a/src/sljit/sljitNativeMIPS_64.c +++ b/src/sljit/sljitNativeMIPS_64.c @@ -446,24 +446,26 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); + inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff); + inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 6); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 6); } diff --git a/src/sljit/sljitNativeMIPS_common.c b/src/sljit/sljitNativeMIPS_common.c index e4739c0..fe37e3e 100644 --- a/src/sljit/sljitNativeMIPS_common.c +++ b/src/sljit/sljitNativeMIPS_common.c @@ -218,7 +218,7 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags) return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; @@ -237,9 +237,10 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - inst = (sljit_ins*)jump->addr; + + inst = (sljit_ins *)jump->addr; if (jump->flags & IS_COND) inst--; @@ -250,7 +251,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i /* B instructions. */ if (jump->flags & IS_MOVABLE) { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; @@ -268,7 +269,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i } } else { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2; + diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; @@ -364,6 +365,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; @@ -380,9 +382,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); + label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); @@ -393,8 +398,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!const_ || const_->addr >= word_count); /* These structures are ordered by their address. */ if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -404,7 +408,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else jump->addr = (sljit_uw)(code_ptr - 7); #endif - code_ptr = detect_jump_type(jump, code_ptr, code); + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); jump = jump->next; } if (const_ && const_->addr == word_count) { @@ -434,16 +438,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; + buf_ptr = (sljit_ins *)jump->addr; if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; + addr = (sljit_sw)(addr - ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins))) >> 2; SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN); buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); break; } if (jump->flags & PATCH_J) { - SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); + SLJIT_ASSERT((addr & ~0xfffffff) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff)); buf_ptr[0] |= (addr >> 2) & 0x03ffffff; break; } @@ -476,7 +480,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + + code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + #ifndef __GNUC__ SLJIT_CACHE_FLUSH(code, code_ptr); #else @@ -1625,7 +1634,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile sljit_s32 delay_check = UNMOVABLE_INS; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1743,7 +1751,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler sljit_ins inst; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w)); ADJUST_LOCAL_OFFSET(src1, src1w); ADJUST_LOCAL_OFFSET(src2, src2w); @@ -1865,7 +1872,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile sljit_s32 if_true; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); compiler->cache_arg = 0; @@ -2124,7 +2130,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi sljit_s32 reg; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); diff --git a/src/sljit/sljitNativePPC_32.c b/src/sljit/sljitNativePPC_32.c index 0f23cf8..f696d1b 100644 --- a/src/sljit/sljitNativePPC_32.c +++ b/src/sljit/sljitNativePPC_32.c @@ -250,20 +250,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } diff --git a/src/sljit/sljitNativePPC_64.c b/src/sljit/sljitNativePPC_64.c index 8e3223f..386d247 100644 --- a/src/sljit/sljitNativePPC_64.c +++ b/src/sljit/sljitNativePPC_64.c @@ -398,18 +398,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins*)addr; - inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); - inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); - inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); - inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff); + inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff); + inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 5); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins*)addr; @@ -417,5 +418,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 5); } diff --git a/src/sljit/sljitNativePPC_common.c b/src/sljit/sljitNativePPC_common.c index 1b8acaf..150c0bf 100644 --- a/src/sljit/sljitNativePPC_common.c +++ b/src/sljit/sljitNativePPC_common.c @@ -249,7 +249,7 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; @@ -267,7 +267,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -275,7 +275,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in goto keep_address; #endif - diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l; + diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l; extra_jump_flags = 0; if (jump->flags & IS_COND) { @@ -296,6 +296,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in jump->flags |= PATCH_B | extra_jump_flags; return 1; } + if (target_addr <= 0x03ffffff) { jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags; return 1; @@ -309,6 +310,7 @@ keep_address: jump->flags |= PATCH_ABS32; return 1; } + if (target_addr <= 0x7fffffffffffl) { jump->flags |= PATCH_ABS48; return 1; @@ -326,6 +328,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; @@ -349,9 +352,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); + label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); @@ -363,7 +369,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* These structures are ordered by their address. */ if (label && label->size == word_count) { /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -373,7 +379,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else jump->addr = (sljit_uw)(code_ptr - 6); #endif - if (detect_jump_type(jump, code_ptr, code)) { + if (detect_jump_type(jump, code_ptr, code, executable_offset)) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) code_ptr[-3] = code_ptr[0]; code_ptr -= 3; @@ -420,7 +426,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } while (buf); if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -438,11 +444,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; + buf_ptr = (sljit_ins *)jump->addr; + if (jump->flags & PATCH_B) { if (jump->flags & IS_COND) { if (!(jump->flags & PATCH_ABS_B)) { - addr = addr - jump->addr; + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); } @@ -453,7 +460,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } else { if (!(jump->flags & PATCH_ABS_B)) { - addr = addr - jump->addr; + addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); } @@ -464,6 +471,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } break; } + /* Set the fields of immediate loads. */ #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); @@ -492,19 +500,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); - SLJIT_CACHE_FLUSH(code, code_ptr); + + code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (((sljit_sw)code_ptr) & 0x4) code_ptr++; - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); - return code_ptr; -#else - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); - return code_ptr; #endif + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); +#endif + + code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + + SLJIT_CACHE_FLUSH(code, code_ptr); + +#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + return code_ptr; #else return code; #endif @@ -2138,7 +2152,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile sljit_ins bo_bi_flags; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); bo_bi_flags = get_bo_bi_flags(type & 0xff); @@ -2363,7 +2376,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi sljit_s32 reg; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); diff --git a/src/sljit/sljitNativeSPARC_32.c b/src/sljit/sljitNativeSPARC_32.c index 7e589a1..4a206f1 100644 --- a/src/sljit/sljitNativeSPARC_32.c +++ b/src/sljit/sljitNativeSPARC_32.c @@ -145,20 +145,22 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; - inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff); - inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff); + inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff); + inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { - sljit_ins *inst = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins *)addr; inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); + inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } diff --git a/src/sljit/sljitNativeSPARC_common.c b/src/sljit/sljitNativeSPARC_common.c index fabb3bd..7445fc4 100644 --- a/src/sljit/sljitNativeSPARC_common.c +++ b/src/sljit/sljitNativeSPARC_common.c @@ -199,7 +199,7 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; @@ -213,7 +213,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - target_addr = (sljit_uw)(code + jump->u.label->size); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } inst = (sljit_ins*)jump->addr; @@ -239,8 +239,9 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i if (jump->flags & IS_COND) inst--; + diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2; + if (jump->flags & IS_MOVABLE) { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2; if (diff <= MAX_DISP && diff >= MIN_DISP) { jump->flags |= PATCH_B; inst--; @@ -257,7 +258,8 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i } } - diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + diff += sizeof(sljit_ins); + if (diff <= MAX_DISP && diff >= MIN_DISP) { jump->flags |= PATCH_B; if (jump->flags & IS_COND) @@ -280,6 +282,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; @@ -296,9 +299,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + executable_offset = SLJIT_EXEC_OFFSET(code); + label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); @@ -310,7 +316,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* These structures are ordered by their address. */ if (label && label->size == word_count) { /* Just recording the address. */ - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -320,7 +326,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #else jump->addr = (sljit_uw)(code_ptr - 6); #endif - code_ptr = detect_jump_type(jump, code_ptr, code); + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); jump = jump->next; } if (const_ && const_->addr == word_count) { @@ -336,7 +342,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } while (buf); if (label && label->size == word_count) { - label->addr = (sljit_uw)code_ptr; + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); label->size = code_ptr - code; label = label->next; } @@ -350,16 +356,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil while (jump) { do { addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; - buf_ptr = (sljit_ins*)jump->addr; + buf_ptr = (sljit_ins *)jump->addr; if (jump->flags & PATCH_CALL) { - addr = (sljit_sw)(addr - jump->addr) >> 2; + addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000); buf_ptr[0] = CALL | (addr & 0x3fffffff); break; } if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - jump->addr) >> 2; + addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2; SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP); buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK); break; @@ -378,7 +384,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); + + code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + SLJIT_CACHE_FLUSH(code, code_ptr); return code; } @@ -1295,7 +1306,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile struct sljit_jump *jump; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1423,7 +1433,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi struct sljit_const *const_; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); diff --git a/src/sljit/sljitNativeTILEGX_64.c b/src/sljit/sljitNativeTILEGX_64.c index f1d0a16..177a65b 100644 --- a/src/sljit/sljitNativeTILEGX_64.c +++ b/src/sljit/sljitNativeTILEGX_64.c @@ -2412,7 +2412,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil flush_buffer(compiler); CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -2511,7 +2510,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp flush_buffer(compiler); CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2528,13 +2526,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp return const_; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target) { sljit_ins *inst = (sljit_ins *)addr; - inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43); - inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43); - inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43); + inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43); + inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43); + inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43); SLJIT_CACHE_FLUSH(inst, inst + 3); } diff --git a/src/sljit/sljitNativeX86_32.c b/src/sljit/sljitNativeX86_32.c index 78f3dcb..00333f6 100644 --- a/src/sljit/sljitNativeX86_32.c +++ b/src/sljit/sljitNativeX86_32.c @@ -38,7 +38,7 @@ static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, s return SLJIT_SUCCESS; } -static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset) { if (type == SLJIT_JUMP) { *code_ptr++ = JMP_i32; @@ -57,7 +57,7 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MW; else - sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4)); + sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset); code_ptr += 4; return code_ptr; diff --git a/src/sljit/sljitNativeX86_common.c b/src/sljit/sljitNativeX86_common.c index f72ab51..12a0e27 100644 --- a/src/sljit/sljitNativeX86_common.c +++ b/src/sljit/sljitNativeX86_common.c @@ -409,7 +409,11 @@ static sljit_u8 get_jump_code(sljit_s32 type) return 0; } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset); +#else static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type); +#endif static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset) { @@ -511,8 +515,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump->addr = (sljit_uw)code_ptr; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset); - else + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset); +#else code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2); +#endif + } jump = jump->next; } else if (*buf_ptr == 0) { @@ -521,7 +530,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = label->next; } else { /* *buf_ptr is 1 */ - SLJIT_ASSERT(sljit_is_dyn_code_modification_enabled()); const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw); const_ = const_->next; } @@ -572,6 +580,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Some space may be wasted because of short jumps. */ SLJIT_ASSERT(code_ptr <= code + compiler->size); compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_offset = executable_offset; compiler->executable_size = code_ptr - code; return (void*)(code + executable_offset); } @@ -2572,7 +2581,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile struct sljit_jump *jump; CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP); CHECK_PTR(check_sljit_emit_jump(compiler, type)); if (SLJIT_UNLIKELY(compiler->flags_saved)) { @@ -2901,7 +2909,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi #endif CHECK_ERROR_PTR(); - CHECK_DYN_CODE_MOD(1); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2940,17 +2947,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { + SLJIT_UNUSED_ARG(executable_offset); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_unaligned_store_sw((void*)addr, new_addr - (addr + 4)); + sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset); #else - sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_addr); + sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target); #endif } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) { + SLJIT_UNUSED_ARG(executable_offset); sljit_unaligned_store_sw((void*)addr, new_constant); }