diff options
Diffstat (limited to 'thirdparty/pcre2/src/sljit')
18 files changed, 900 insertions, 205 deletions
diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h index ba60311e45..acba9da4be 100644 --- a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h +++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h @@ -214,6 +214,10 @@  #define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)  #endif +#ifndef SLJIT_MEMMOVE +#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) +#endif +  #ifndef SLJIT_ZEROMEM  #define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)  #endif diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c index 3b37a9751f..92ddb94914 100644 --- a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c +++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c @@ -118,10 +118,20 @@ static SLJIT_INLINE int get_map_jit_flag()  	if (map_jit_flag == -1) {  		struct utsname name; +		map_jit_flag = 0;  		uname(&name);  		/* Kernel version for 10.14.0 (Mojave) */ -		map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0; +		if (atoi(name.release) >= 18) { +			/* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */ +			void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + +			if (ptr == MAP_FAILED) { +				map_jit_flag = MAP_JIT; +			} else { +				munmap(ptr, getpagesize()); +			} +		}  	}  	return map_jit_flag; @@ -137,6 +147,7 @@ static SLJIT_INLINE int get_map_jit_flag()  static SLJIT_INLINE void* alloc_chunk(sljit_uw size)  {  	void *retval; +	const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;  #ifdef MAP_ANON @@ -146,16 +157,25 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)  	flags |= get_map_jit_flag();  #endif -	retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0); +	retval = mmap(NULL, size, prot, flags, -1, 0);  #else /* !MAP_ANON */  	if (dev_zero < 0) {  		if (open_dev_zero())  			return NULL;  	} -	retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); +	retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);  #endif /* MAP_ANON */ -	return (retval != MAP_FAILED) ? retval : NULL; +	if (retval == MAP_FAILED) +		retval = NULL; +	else { +		if (mprotect(retval, size, prot) < 0) { +			munmap(retval, size); +			retval = NULL; +		} +	} + +	return retval;  }  static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c index ded9541b31..9bab0c3ec6 100644 --- a/thirdparty/pcre2/src/sljit/sljitLir.c +++ b/thirdparty/pcre2/src/sljit/sljitLir.c @@ -144,6 +144,7 @@  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #	define PATCH_MD		0x10  #endif +#	define TYPE_SHIFT	13  #endif  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) @@ -521,6 +522,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw  	}  } +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) +{ +	if (SLJIT_LIKELY(!!put_label)) +		put_label->label = label; +} +  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)  {  	SLJIT_UNUSED_ARG(compiler); @@ -620,6 +627,30 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)  	return arg_count;  } +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump, +	struct sljit_const *const_, struct sljit_put_label *put_label) +{ +	sljit_uw result = ~(sljit_uw)0; + +	if (label) +		result = label->size; + +	if (jump && jump->addr < result) +		result = jump->addr; + +	if (const_ && const_->addr < result) +		result = const_->addr; + +	if (put_label && put_label->addr < result) +		result = put_label->addr; + +	return result; +} + +#endif /* !SLJIT_CONFIG_X86 */ +  static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,  	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,  	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -687,6 +718,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp  	compiler->last_const = const_;  } +static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset) +{ +	put_label->next = NULL; +	put_label->label = NULL; +	put_label->addr = compiler->size - offset; +	put_label->flags = 0; +	if (compiler->last_put_label) +		compiler->last_put_label->next = put_label; +	else +		compiler->put_labels = put_label; +	compiler->last_put_label = put_label; +} +  #define ADDRESSING_DEPENDS_ON(exp, reg) \  	(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) @@ -1905,6 +1949,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil  	CHECK_RETURN_OK;  } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) +	FUNCTION_CHECK_DST(dst, dstw, 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +	if (SLJIT_UNLIKELY(!!compiler->verbose)) { +		fprintf(compiler->verbose, "  put_label "); +		sljit_verbose_param(compiler, dst, dstw); +		fprintf(compiler->verbose, "\n"); +	} +#endif +	CHECK_RETURN_OK; +} +  #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */  #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ @@ -2581,6 +2640,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	return NULL;  } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	SLJIT_UNUSED_ARG(compiler); +	SLJIT_UNUSED_ARG(dst); +	SLJIT_UNUSED_ARG(dstw); +	return NULL; +} +  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)  {  	SLJIT_UNUSED_ARG(addr); @@ -2597,4 +2664,4 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta  	SLJIT_UNREACHABLE();  } -#endif +#endif /* !SLJIT_CONFIG_UNSUPPORTED */ diff --git a/thirdparty/pcre2/src/sljit/sljitLir.h b/thirdparty/pcre2/src/sljit/sljitLir.h index e71890cf7b..836d25cf71 100644 --- a/thirdparty/pcre2/src/sljit/sljitLir.h +++ b/thirdparty/pcre2/src/sljit/sljitLir.h @@ -348,13 +348,20 @@ struct sljit_label {  struct sljit_jump {  	struct sljit_jump *next;  	sljit_uw addr; -	sljit_sw flags; +	sljit_uw flags;  	union {  		sljit_uw target; -		struct sljit_label* label; +		struct sljit_label *label;  	} u;  }; +struct sljit_put_label { +	struct sljit_put_label *next; +	struct sljit_label *label; +	sljit_uw addr; +	sljit_uw flags; +}; +  struct sljit_const {  	struct sljit_const *next;  	sljit_uw addr; @@ -366,10 +373,12 @@ struct sljit_compiler {  	struct sljit_label *labels;  	struct sljit_jump *jumps; +	struct sljit_put_label *put_labels;  	struct sljit_const *consts;  	struct sljit_label *last_label;  	struct sljit_jump *last_jump;  	struct sljit_const *last_const; +	struct sljit_put_label *last_put_label;  	void *allocator_data;  	struct sljit_memory_fragment *buf; @@ -1314,10 +1323,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil     Flags: - (may destroy flags) */  SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset); -/* The constant can be changed runtime (see: sljit_set_const) +/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)     Flags: - (does not modify flags) */  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value); +/* Store the value of a label (see: sljit_set_put_label) +   Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); + +/* Set the value stored by put_label to this label. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label); +  /* After the code generation the address for label, jump and const instructions     are computed. Since these structures are freed by sljit_free_compiler, the     addresses must be preserved by the user program elsewere. */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c index 6d61eed9a7..71f7bcdadb 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c @@ -583,8 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	sljit_uw *buf_end;  	sljit_uw size;  	sljit_uw word_count; +	sljit_uw next_addr;  	sljit_sw executable_offset; -	sljit_sw jump_addr; +	sljit_sw addr;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  	sljit_uw cpool_size;  	sljit_uw cpool_skip_alignment; @@ -597,6 +598,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -625,11 +627,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 1;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	if (label && label->size == 0) {  		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); @@ -669,35 +673,45 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  			else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {  #endif  				*code_ptr = *buf_ptr++; +				if (next_addr == word_count) { +					SLJIT_ASSERT(!label || label->size >= word_count); +					SLJIT_ASSERT(!jump || jump->addr >= word_count); +					SLJIT_ASSERT(!const_ || const_->addr >= word_count); +					SLJIT_ASSERT(!put_label || put_label->addr >= word_count); +  				/* These structures are ordered by their address. */ -				SLJIT_ASSERT(!label || label->size >= word_count); -				SLJIT_ASSERT(!jump || jump->addr >= word_count); -				SLJIT_ASSERT(!const_ || const_->addr >= word_count); -				if (jump && jump->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, executable_offset)) -						code_ptr--; -					jump->addr = (sljit_uw)code_ptr; +						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, executable_offset)) -						code_ptr -= 2; +						jump->addr = (sljit_uw)(code_ptr - 2); +						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)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); -					label->size = (code_ptr + 1) - code; -					label = label->next; -				} -				if (const_ && const_->addr == word_count) { +						jump = jump->next; +					} +					if (label && label->size == word_count) { +						/* code_ptr can be affected above. */ +						label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); +						label->size = (code_ptr + 1) - code; +						label = label->next; +					} +					if (const_ && const_->addr == word_count) {  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -					const_->addr = (sljit_uw)code_ptr; +						const_->addr = (sljit_uw)code_ptr;  #else -					const_->addr = (sljit_uw)(code_ptr - 1); +						const_->addr = (sljit_uw)(code_ptr - 1);  #endif -					const_ = const_->next; +						const_ = const_->next; +					} +					if (put_label && put_label->addr == word_count) { +						SLJIT_ASSERT(put_label->label); +						put_label->addr = (sljit_uw)code_ptr; +						put_label = put_label->next; +					} +					next_addr = compute_next_addr(label, jump, const_, put_label);  				}  				code_ptr++;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) @@ -725,6 +739,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  	SLJIT_ASSERT(cpool_size == 0); @@ -755,15 +770,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		buf_ptr = (sljit_uw *)jump->addr;  		if (jump->flags & PATCH_B) { -			jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); +			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 - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000); -				*buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff; +				SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000); +				*buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff;  			}  			else { -				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; +				SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000); +				*buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff;  			}  		}  		else if (jump->flags & SLJIT_REWRITABLE_JUMP) { @@ -813,6 +828,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	}  #endif +	put_label = compiler->put_labels; +	while (put_label) { +		addr = put_label->label->addr; +		buf_ptr = (sljit_uw*)put_label->addr; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +		SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000); +		buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; +#else +		SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT); +		buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff); +		buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); +#endif +		put_label = put_label->next; +	} +  	SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);  	compiler->error = SLJIT_ERR_COMPILED; @@ -2639,28 +2670,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)  {  	struct sljit_const *const_; -	sljit_s32 reg; +	sljit_s32 dst_r;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));  	ADJUST_LOCAL_OFFSET(dst, dstw); +	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value)); +	compiler->patches++; +#else +	PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value)); +#endif +  	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));  	PTR_FAIL_IF(!const_); +	set_const(const_, compiler); -	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); +	return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value)); +	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));  	compiler->patches++;  #else -	PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); +	PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));  #endif -	set_const(const_, compiler); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0);  	if (dst & SLJIT_MEM)  		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); -	return const_; +	return put_label;  }  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c index b015695c52..e15b3451e8 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -161,7 +161,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, sljit_sw executable_offset) +static SLJIT_INLINE sljit_sw 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; @@ -196,14 +196,14 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in  		return 4;  	} -	if (target_addr <= 0xffffffffl) { +	if (target_addr < 0x100000000l) {  		if (jump->flags & IS_COND)  			code_ptr[-5] -= (2 << 5);  		code_ptr[-2] = code_ptr[0];  		return 2;  	} -	if (target_addr <= 0xffffffffffffl) { +	if (target_addr < 0x1000000000000l) {  		if (jump->flags & IS_COND)  			code_ptr[-5] -= (1 << 5);  		jump->flags |= PATCH_ABS48; @@ -215,6 +215,22 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in  	return 0;  } +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ +	if (max_label < 0x100000000l) { +		put_label->flags = 0; +		return 2; +	} + +	if (max_label < 0x1000000000000l) { +		put_label->flags = 1; +		return 1; +	} + +	put_label->flags = 2; +	return 0; +} +  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)  {  	struct sljit_memory_fragment *buf; @@ -223,6 +239,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_uw next_addr;  	sljit_sw executable_offset;  	sljit_uw addr;  	sljit_s32 dst; @@ -230,6 +247,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -241,34 +259,47 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 0;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	do {  		buf_ptr = (sljit_ins*)buf->memory;  		buf_end = buf_ptr + (buf->used_size >> 2);  		do {  			*code_ptr = *buf_ptr++; -			/* These structures are ordered by their address. */ -			SLJIT_ASSERT(!label || label->size >= word_count); -			SLJIT_ASSERT(!jump || jump->addr >= word_count); -			SLJIT_ASSERT(!const_ || const_->addr >= word_count); -			if (label && label->size == word_count) { -				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, executable_offset); -					jump = jump->next; -			} -			if (const_ && const_->addr == word_count) { -				const_->addr = (sljit_uw)code_ptr; -				const_ = const_->next; +			if (next_addr == word_count) { +				SLJIT_ASSERT(!label || label->size >= word_count); +				SLJIT_ASSERT(!jump || jump->addr >= word_count); +				SLJIT_ASSERT(!const_ || const_->addr >= word_count); +				SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + +				/* These structures are ordered by their address. */ +				if (label && label->size == word_count) { +					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, executable_offset); +						jump = jump->next; +				} +				if (const_ && const_->addr == word_count) { +					const_->addr = (sljit_uw)code_ptr; +					const_ = const_->next; +				} +				if (put_label && put_label->addr == word_count) { +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)(code_ptr - 3); +					code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); +					put_label = put_label->next; +				} +				next_addr = compute_next_addr(label, jump, const_, put_label);  			}  			code_ptr ++;  			word_count ++; @@ -286,6 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);  	jump = compiler->jumps; @@ -323,6 +355,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} +	put_label = compiler->put_labels; +	while (put_label) { +		addr = put_label->label->addr; +		buf_ptr = (sljit_ins *)put_label->addr; + +		buf_ptr[0] |= (addr & 0xffff) << 5; +		buf_ptr[1] |= ((addr >> 16) & 0xffff) << 5; + +		if (put_label->flags >= 1) +			buf_ptr[2] |= ((addr >> 32) & 0xffff) << 5; + +		if (put_label->flags >= 2) +			buf_ptr[3] |= ((addr >> 48) & 0xffff) << 5; + +		put_label = put_label->next; +	} +  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset;  	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -1947,6 +1996,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	return const_;  } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; +	PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0)); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 1); + +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); + +	return put_label; +} +  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; diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c index d7024b6d7d..cdfe4a4d24 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -365,11 +365,13 @@ 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_uw next_addr;  	sljit_sw executable_offset;  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -381,34 +383,46 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	half_count = 0; +	next_addr = 0;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	do {  		buf_ptr = (sljit_u16*)buf->memory;  		buf_end = buf_ptr + (buf->used_size >> 1);  		do {  			*code_ptr = *buf_ptr++; -			/* These structures are ordered by their address. */ -			SLJIT_ASSERT(!label || label->size >= half_count); -			SLJIT_ASSERT(!jump || jump->addr >= half_count); -			SLJIT_ASSERT(!const_ || const_->addr >= half_count); -			if (label && label->size == half_count) { -				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, executable_offset); -					jump = jump->next; -			} -			if (const_ && const_->addr == half_count) { -				const_->addr = (sljit_uw)code_ptr; -				const_ = const_->next; +			if (next_addr == half_count) { +				SLJIT_ASSERT(!label || label->size >= half_count); +				SLJIT_ASSERT(!jump || jump->addr >= half_count); +				SLJIT_ASSERT(!const_ || const_->addr >= half_count); +				SLJIT_ASSERT(!put_label || put_label->addr >= half_count); + +				/* These structures are ordered by their address. */ +				if (label && label->size == half_count) { +					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, executable_offset); +						jump = jump->next; +				} +				if (const_ && const_->addr == half_count) { +					const_->addr = (sljit_uw)code_ptr; +					const_ = const_->next; +				} +				if (put_label && put_label->addr == half_count) { +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)code_ptr; +					put_label = put_label->next; +				} +				next_addr = compute_next_addr(label, jump, const_, put_label);  			}  			code_ptr ++;  			half_count ++; @@ -426,6 +440,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);  	jump = compiler->jumps; @@ -434,6 +449,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} +	put_label = compiler->put_labels; +	while (put_label) { +		modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr); +		put_label = put_label->next; +	} +  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset;  	compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16); @@ -2311,6 +2332,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	return const_;  } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0); + +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; +	PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0)); + +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); +	return put_label; +} +  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; diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index ad970bf25a..16dec052fe 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -425,6 +425,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);  	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); @@ -435,6 +436,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);  	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); diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index e0d6a3f085..7d1d087496 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -449,6 +449,55 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_  }  #endif +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ +	if (max_label < 0x80000000l) { +		put_label->flags = 0; +		return 1; +	} + +	if (max_label < 0x800000000000l) { +		put_label->flags = 1; +		return 3; +	} + +	put_label->flags = 2; +	return 5; +} + +static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label) +{ +	sljit_uw addr = put_label->label->addr; +	sljit_ins *inst = (sljit_ins *)put_label->addr; +	sljit_s32 reg = *inst; + +	if (put_label->flags == 0) { +		SLJIT_ASSERT(addr < 0x80000000l); +		inst[0] = LUI | T(reg) | IMM(addr >> 16); +	} +	else if (put_label->flags == 1) { +		SLJIT_ASSERT(addr < 0x800000000000l); +		inst[0] = LUI | T(reg) | IMM(addr >> 32); +		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); +		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); +		inst += 2; +	} +	else { +		inst[0] = LUI | T(reg) | IMM(addr >> 48); +		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff); +		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); +		inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); +		inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16); +		inst += 4; +	} + +	inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff); +} + +#endif +  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)  {  	struct sljit_memory_fragment *buf; @@ -457,12 +506,14 @@ 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_uw next_addr;  	sljit_sw executable_offset;  	sljit_uw addr;  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -474,39 +525,54 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 0;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	do {  		buf_ptr = (sljit_ins*)buf->memory;  		buf_end = buf_ptr + (buf->used_size >> 2);  		do {  			*code_ptr = *buf_ptr++; -			SLJIT_ASSERT(!label || label->size >= word_count); -			SLJIT_ASSERT(!jump || jump->addr >= word_count); -			SLJIT_ASSERT(!const_ || const_->addr >= word_count); -			/* These structures are ordered by their address. */ -			if (label && label->size == word_count) { -				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) { +			if (next_addr == word_count) { +				SLJIT_ASSERT(!label || label->size >= word_count); +				SLJIT_ASSERT(!jump || jump->addr >= word_count); +				SLJIT_ASSERT(!const_ || const_->addr >= word_count); +				SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + +				/* These structures are ordered by their address. */ +				if (label && label->size == word_count) { +					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) {  #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -				jump->addr = (sljit_uw)(code_ptr - 3); +					jump->addr = (sljit_uw)(code_ptr - 3);  #else -				jump->addr = (sljit_uw)(code_ptr - 7); +					jump->addr = (sljit_uw)(code_ptr - 7);  #endif -				code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); -				jump = jump->next; -			} -			if (const_ && const_->addr == word_count) { -				/* Just recording the address. */ -				const_->addr = (sljit_uw)code_ptr; -				const_ = const_->next; +					code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); +					jump = jump->next; +				} +				if (const_ && const_->addr == word_count) { +					const_->addr = (sljit_uw)code_ptr; +					const_ = const_->next; +				} +				if (put_label && put_label->addr == word_count) { +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); +					word_count += 5; +#endif +					put_label = put_label->next; +				} +				next_addr = compute_next_addr(label, jump, const_, put_label);  			}  			code_ptr ++;  			word_count ++; @@ -524,6 +590,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);  	jump = compiler->jumps; @@ -571,6 +638,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} +	put_label = compiler->put_labels; +	while (put_label) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +		addr = put_label->label->addr; +		buf_ptr = (sljit_ins *)put_label->addr; + +		SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI); +		buf_ptr[0] |= (addr >> 16) & 0xffff; +		buf_ptr[1] |= addr & 0xffff; +#else +		put_label_set(put_label); +#endif +		put_label = put_label->next; +	} +  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset;  	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -2157,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)  {  	struct sljit_const *const_; -	sljit_s32 reg; +	sljit_s32 dst_r;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2167,11 +2249,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	PTR_FAIL_IF(!const_);  	set_const(const_, compiler); -	reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - -	PTR_FAIL_IF(emit_const(compiler, reg, init_value)); +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));  	if (dst & SLJIT_MEM)  		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); +  	return const_;  } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0); + +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +	PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); +#else +	PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS)); +	compiler->size += 5; +#endif + +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + +	return put_label; +} diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c index fc185f7847..3ce741153f 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c @@ -259,6 +259,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);  	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); @@ -269,6 +270,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);  	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); diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c index 706b2ba20b..3b73021cc8 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c @@ -35,9 +35,6 @@  #error "Must implement count leading zeroes"  #endif -#define RLDI(dst, src, sh, mb, type) \ -	(HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) -  #define PUSH_RLDICR(reg, shift) \  	push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c index b34e3965ed..e827514315 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c @@ -231,6 +231,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {  #define SIMM_MIN	(-0x8000)  #define UIMM_MAX	(0xffff) +#define RLDI(dst, src, sh, mb, type) \ +	(HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) +  #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)  { @@ -324,6 +327,55 @@ keep_address:  	return 0;  } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ +	if (max_label < 0x100000000l) { +		put_label->flags = 0; +		return 1; +	} + +	if (max_label < 0x1000000000000l) { +		put_label->flags = 1; +		return 3; +	} + +	put_label->flags = 2; +	return 4; +} + +static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label) +{ +	sljit_uw addr = put_label->label->addr; +	sljit_ins *inst = (sljit_ins *)put_label->addr; +	sljit_s32 reg = *inst; + +	if (put_label->flags == 0) { +		SLJIT_ASSERT(addr < 0x100000000l); +		inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16); +	} +	else { +		if (put_label->flags == 1) { +			SLJIT_ASSERT(addr < 0x1000000000000l); +			inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32); +		} +		else { +			inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48); +			inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff); +			inst ++; +		} + +		inst[1] = RLDI(reg, reg, 32, 31, 1); +		inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff); +		inst += 2; +	} + +	inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff); +} + +#endif +  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)  {  	struct sljit_memory_fragment *buf; @@ -332,12 +384,14 @@ 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_uw next_addr;  	sljit_sw executable_offset;  	sljit_uw addr;  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -356,71 +410,87 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 0;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	do {  		buf_ptr = (sljit_ins*)buf->memory;  		buf_end = buf_ptr + (buf->used_size >> 2);  		do {  			*code_ptr = *buf_ptr++; -			SLJIT_ASSERT(!label || label->size >= word_count); -			SLJIT_ASSERT(!jump || jump->addr >= word_count); -			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)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); -				label->size = code_ptr - code; -				label = label->next; -			} -			if (jump && jump->addr == word_count) { +			if (next_addr == word_count) { +				SLJIT_ASSERT(!label || label->size >= word_count); +				SLJIT_ASSERT(!jump || jump->addr >= word_count); +				SLJIT_ASSERT(!const_ || const_->addr >= word_count); +				SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + +				/* These structures are ordered by their address. */ +				if (label && label->size == word_count) { +					/* Just recording the address. */ +					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) {  #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -				jump->addr = (sljit_uw)(code_ptr - 3); +					jump->addr = (sljit_uw)(code_ptr - 3);  #else -				jump->addr = (sljit_uw)(code_ptr - 6); +					jump->addr = (sljit_uw)(code_ptr - 6);  #endif -				if (detect_jump_type(jump, code_ptr, code, executable_offset)) { +					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; -#else -					if (jump->flags & PATCH_ABS32) { +						code_ptr[-3] = code_ptr[0];  						code_ptr -= 3; -						code_ptr[-1] = code_ptr[2]; -						code_ptr[0] = code_ptr[3]; -					} -					else if (jump->flags & PATCH_ABS48) { -						code_ptr--; -						code_ptr[-1] = code_ptr[0]; -						code_ptr[0] = code_ptr[1]; -						/* rldicr rX,rX,32,31 -> rX,rX,16,47 */ -						SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); -						code_ptr[-3] ^= 0x8422; -						/* oris -> ori */ -						code_ptr[-2] ^= 0x4000000; -					} -					else { -						code_ptr[-6] = code_ptr[0]; -						code_ptr -= 6; -					} +#else +						if (jump->flags & PATCH_ABS32) { +							code_ptr -= 3; +							code_ptr[-1] = code_ptr[2]; +							code_ptr[0] = code_ptr[3]; +						} +						else if (jump->flags & PATCH_ABS48) { +							code_ptr--; +							code_ptr[-1] = code_ptr[0]; +							code_ptr[0] = code_ptr[1]; +							/* rldicr rX,rX,32,31 -> rX,rX,16,47 */ +							SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); +							code_ptr[-3] ^= 0x8422; +							/* oris -> ori */ +							code_ptr[-2] ^= 0x4000000; +						} +						else { +							code_ptr[-6] = code_ptr[0]; +							code_ptr -= 6; +						}  #endif -					if (jump->flags & REMOVE_COND) { -						code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); -						code_ptr++; -						jump->addr += sizeof(sljit_ins); -						code_ptr[0] = Bx; -						jump->flags -= IS_COND; +						if (jump->flags & REMOVE_COND) { +							code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); +							code_ptr++; +							jump->addr += sizeof(sljit_ins); +							code_ptr[0] = Bx; +							jump->flags -= IS_COND; +						}  					} +					jump = jump->next;  				} -				jump = jump->next; -			} -			if (const_ && const_->addr == word_count) { -				const_->addr = (sljit_uw)code_ptr; -				const_ = const_->next; +				if (const_ && const_->addr == word_count) { +					const_->addr = (sljit_uw)code_ptr; +					const_ = const_->next; +				} +				if (put_label && put_label->addr == word_count) { +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); +					word_count += 4; +#endif +					put_label = put_label->next; +				} +				next_addr = compute_next_addr(label, jump, const_, put_label);  			}  			code_ptr ++;  			word_count ++; @@ -438,6 +508,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label); +  #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)  	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));  #else @@ -503,6 +575,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} +	put_label = compiler->put_labels; +	while (put_label) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +		addr = put_label->label->addr; +		buf_ptr = (sljit_ins *)put_label->addr; + +		SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI); +		buf_ptr[0] |= (addr >> 16) & 0xffff; +		buf_ptr[1] |= addr & 0xffff; +#else +		put_label_set(put_label); +#endif +		put_label = put_label->next; +	} +  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset;  	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -2261,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)  {  	struct sljit_const *const_; -	sljit_s32 reg; +	sljit_s32 dst_r;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2271,11 +2358,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	PTR_FAIL_IF(!const_);  	set_const(const_, compiler); -	reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - -	PTR_FAIL_IF(emit_const(compiler, reg, init_value)); +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));  	if (dst & SLJIT_MEM)  		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); +  	return const_;  } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0); + +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +	PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); +#else +	PTR_FAIL_IF(push_inst(compiler, dst_r)); +	compiler->size += 4; +#endif + +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + +	return put_label; +} diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c index 0671b130cc..8079fad8df 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c @@ -267,6 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));  	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); @@ -277,6 +278,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta  {  	sljit_ins *inst = (sljit_ins *)addr; +	SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));  	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); diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c index 669ecd8152..bfa4ecede2 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c @@ -298,12 +298,14 @@ 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_uw next_addr;  	sljit_sw executable_offset;  	sljit_uw addr;  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -315,40 +317,52 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 0;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	do {  		buf_ptr = (sljit_ins*)buf->memory;  		buf_end = buf_ptr + (buf->used_size >> 2);  		do {  			*code_ptr = *buf_ptr++; -			SLJIT_ASSERT(!label || label->size >= word_count); -			SLJIT_ASSERT(!jump || jump->addr >= word_count); -			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)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); -				label->size = code_ptr - code; -				label = label->next; -			} -			if (jump && jump->addr == word_count) { +			if (next_addr == word_count) { +				SLJIT_ASSERT(!label || label->size >= word_count); +				SLJIT_ASSERT(!jump || jump->addr >= word_count); +				SLJIT_ASSERT(!const_ || const_->addr >= word_count); +				SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + +				/* These structures are ordered by their address. */ +				if (label && label->size == word_count) { +					/* Just recording the address. */ +					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) {  #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -				jump->addr = (sljit_uw)(code_ptr - 3); +					jump->addr = (sljit_uw)(code_ptr - 3);  #else -				jump->addr = (sljit_uw)(code_ptr - 6); +					jump->addr = (sljit_uw)(code_ptr - 6);  #endif -				code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); -				jump = jump->next; -			} -			if (const_ && const_->addr == word_count) { -				/* Just recording the address. */ -				const_->addr = (sljit_uw)code_ptr; -				const_ = const_->next; +					code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); +					jump = jump->next; +				} +				if (const_ && const_->addr == word_count) { +					/* Just recording the address. */ +					const_->addr = (sljit_uw)code_ptr; +					const_ = const_->next; +				} +				if (put_label && put_label->addr == word_count) { +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)code_ptr; +					put_label = put_label->next; +				} +				next_addr = compute_next_addr(label, jump, const_, put_label);  			}  			code_ptr ++;  			word_count ++; @@ -366,6 +380,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  	SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);  	jump = compiler->jumps; @@ -389,8 +404,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  			/* Set the fields of immediate loads. */  #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -			buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); -			buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); +			SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000)); +			buf_ptr[0] |= (addr >> 10) & 0x3fffff; +			buf_ptr[1] |= addr & 0x3ff;  #else  #error "Implementation required"  #endif @@ -398,6 +414,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} +	put_label = compiler->put_labels; +	while (put_label) { +		addr = put_label->label->addr; +		buf_ptr = (sljit_ins *)put_label->addr; + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +		SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000)); +		buf_ptr[0] |= (addr >> 10) & 0x3fffff; +		buf_ptr[1] |= addr & 0x3ff; +#else +#error "Implementation required" +#endif +		put_label = put_label->next; +	}  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset; @@ -1465,8 +1495,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)  { -	sljit_s32 reg;  	struct sljit_const *const_; +	sljit_s32 dst_r;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -1476,11 +1506,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	PTR_FAIL_IF(!const_);  	set_const(const_, compiler); -	reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - -	PTR_FAIL_IF(emit_const(compiler, reg, init_value)); +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));  	if (dst & SLJIT_MEM)  		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));  	return const_;  } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0); + +	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +	PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); + +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); +	return put_label; +} diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c index 074e64b9f2..34a3a3d940 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c @@ -38,8 +38,10 @@ 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, sljit_sw executable_offset) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)  { +	sljit_s32 type = jump->flags >> TYPE_SHIFT; +  	if (type == SLJIT_JUMP) {  		*code_ptr++ = JMP_i32;  		jump->addr++; diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c index 8506565614..5758711954 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c @@ -39,8 +39,10 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg,  	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 = jump->flags >> TYPE_SHIFT; +  	int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);  	/* The relative jump below specialized for this case. */ @@ -72,6 +74,56 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_  	return code_ptr;  } +static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label) +{ +	if (max_label > HALFWORD_MAX) { +		put_label->addr -= put_label->flags; +		put_label->flags = PATCH_MD; +		return code_ptr; +	} + +	if (put_label->flags == 0) { +		/* Destination is register. */ +		code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw); + +		SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); +		SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32); + +		if ((code_ptr[0] & 0x07) != 0) { +			code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x08); +			code_ptr += 2 + sizeof(sljit_s32); +		} +		else { +			code_ptr[0] = code_ptr[1]; +			code_ptr += 1 + sizeof(sljit_s32); +		} + +		put_label->addr = (sljit_uw)code_ptr; +		return code_ptr; +	} + +	code_ptr -= put_label->flags + (2 + sizeof(sljit_uw)); +	SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags); + +	SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); + +	if ((code_ptr[1] & 0xf8) == MOV_r_i32) { +		code_ptr += 2 + sizeof(sljit_uw); +		SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); +	} + +	SLJIT_ASSERT(code_ptr[1] == MOV_rm_r); + +	code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x4); +	code_ptr[1] = MOV_rm_i32; +	code_ptr[2] = (sljit_u8)(code_ptr[2] & ~(0x7 << 3)); + +	code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32)); +	put_label->addr = (sljit_uw)code_ptr; +	put_label->flags = 0; +	return code_ptr; +} +  SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,  	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,  	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c index 6f02ee3e8b..6296da5382 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c @@ -428,13 +428,15 @@ static sljit_u8 get_jump_code(sljit_s32 type)  }  #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); +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);  #else -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); +static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);  #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) +static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)  { +	sljit_s32 type = jump->flags >> TYPE_SHIFT;  	sljit_s32 short_jump;  	sljit_uw label_addr; @@ -447,7 +449,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  	if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) -		return generate_far_jump_code(jump, code_ptr, type); +		return generate_far_jump_code(jump, code_ptr);  #endif  	if (type == SLJIT_JUMP) { @@ -497,6 +499,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -511,6 +514,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	do { @@ -525,27 +529,38 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  				buf_ptr += len;  			}  			else { -				if (*buf_ptr >= 2) { +				switch (*buf_ptr) { +				case 0: +					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); +					label->size = code_ptr - code; +					label = label->next; +					break; +				case 1:  					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); +						code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);  					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); +						code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);  #else -						code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2); +						code_ptr = generate_far_jump_code(jump, code_ptr);  #endif  					}  					jump = jump->next; -				} -				else if (*buf_ptr == 0) { -					label->addr = ((sljit_uw)code_ptr) + executable_offset; -					label->size = code_ptr - code; -					label = label->next; -				} -				else { /* *buf_ptr is 1 */ +					break; +				case 2:  					const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);  					const_ = const_->next; +					break; +				default: +					SLJIT_ASSERT(*buf_ptr == 3); +					SLJIT_ASSERT(put_label->label); +					put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +					code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); +#endif +					put_label = put_label->next; +					break;  				}  				buf_ptr++;  			} @@ -557,6 +572,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label); +	SLJIT_ASSERT(code_ptr <= code + compiler->size);  	jump = compiler->jumps;  	while (jump) { @@ -591,8 +608,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		jump = jump->next;  	} -	/* Some space may be wasted because of short jumps. */ -	SLJIT_ASSERT(code_ptr <= code + compiler->size); +	put_label = compiler->put_labels; +	while (put_label) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +		sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr); +#else +		if (put_label->flags & PATCH_MD) { +			SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX); +			sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr); +		} +		else { +			SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX); +			sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr); +		} +#endif + +		put_label = put_label->next; +	} +  	compiler->error = SLJIT_ERR_COMPILED;  	compiler->executable_offset = executable_offset;  	compiler->executable_size = code_ptr - code; @@ -2481,7 +2514,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile  	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));  	PTR_FAIL_IF_NULL(jump); -	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); +	set_jump(jump, compiler, (type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT));  	type &= 0xff;  	/* Worst case size. */ @@ -2495,7 +2528,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile  	PTR_FAIL_IF_NULL(inst);  	*inst++ = 0; -	*inst++ = type + 2; +	*inst++ = 1;  	return jump;  } @@ -2513,7 +2546,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi  	if (src == SLJIT_IMM) {  		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));  		FAIL_IF_NULL(jump); -		set_jump(jump, compiler, JUMP_ADDR); +		set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT));  		jump->u.target = srcw;  		/* Worst case size. */ @@ -2527,7 +2560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi  		FAIL_IF_NULL(inst);  		*inst++ = 0; -		*inst++ = type + 2; +		*inst++ = 1;  	}  	else {  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -2831,7 +2864,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	PTR_FAIL_IF(!inst);  	*inst++ = 0; -	*inst++ = 1; +	*inst++ = 2;  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  	if (dst & SLJIT_MEM) @@ -2842,6 +2875,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi  	return const_;  } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_u8 *inst; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +	sljit_s32 reg; +	sljit_uw start_size; +#endif + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	CHECK_EXTRA_REGS(dst, dstw, (void)0); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +	compiler->mode32 = 0; +	reg = FAST_IS_REG(dst) ? dst : TMP_REG1; + +	if (emit_load_imm64(compiler, reg, 0)) +		return NULL; +#else +	if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0)) +		return NULL; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +	if (dst & SLJIT_MEM) { +		start_size = compiler->size; +		if (emit_mov(compiler, dst, dstw, TMP_REG1, 0)) +			return NULL; +		put_label->flags = compiler->size - start_size; +	} +#endif + +	inst = (sljit_u8*)ensure_buf(compiler, 2); +	PTR_FAIL_IF(!inst); + +	*inst++ = 0; +	*inst++ = 3; + +	return put_label; +} +  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); diff --git a/thirdparty/pcre2/src/sljit/sljitUtils.c b/thirdparty/pcre2/src/sljit/sljitUtils.c index 5c2a838932..857492a174 100644 --- a/thirdparty/pcre2/src/sljit/sljitUtils.c +++ b/thirdparty/pcre2/src/sljit/sljitUtils.c @@ -154,7 +154,13 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)  #include "windows.h"  #else  /* Provides mmap function. */ +#include <sys/types.h>  #include <sys/mman.h> +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#endif +#endif  /* For detecting the page size. */  #include <unistd.h>  |