Path: blob/master/thirdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c
9913 views
/*1* Stack-less Just-In-Time compiler2*3* Copyright Zoltan Herczeg ([email protected]). All rights reserved.4*5* Redistribution and use in source and binary forms, with or without modification, are6* permitted provided that the following conditions are met:7*8* 1. Redistributions of source code must retain the above copyright notice, this list of9* conditions and the following disclaimer.10*11* 2. Redistributions in binary form must reproduce the above copyright notice, this list12* of conditions and the following disclaimer in the documentation and/or other materials13* provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY16* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES17* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT18* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,19* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED20* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR21* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN22* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN23* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump)27{28return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL);29}3031SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump)32{33return (jump->flags & JUMP_ADDR) != 0;34}3536SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump)37{38return (jump->flags & JUMP_MOV_ADDR) != 0;39}4041#define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1)4243struct sljit_serialized_compiler {44sljit_u32 signature;45sljit_u16 version;46sljit_u16 cpu_type;4748sljit_uw buf_segment_count;49sljit_uw label_count;50sljit_uw jump_count;51sljit_uw const_count;5253sljit_s32 options;54sljit_s32 scratches;55sljit_s32 saveds;56sljit_s32 fscratches;57sljit_s32 fsaveds;58sljit_s32 local_size;59sljit_uw size;6061#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)62sljit_s32 status_flags_state;63#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */6465#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)66sljit_s32 args_size;67#endif /* SLJIT_CONFIG_X86_32 */6869#if ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \70|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)71sljit_uw args_size;72#endif /* (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */7374#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)75sljit_uw cpool_diff;76sljit_uw cpool_fill;77sljit_uw patches;78#endif /* SLJIT_CONFIG_ARM_V6 */7980#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)81sljit_s32 delay_slot;82#endif /* SLJIT_CONFIG_MIPS */8384};8586struct sljit_serialized_debug_info {87sljit_sw last_flags;88sljit_s32 last_return;89sljit_s32 logical_local_size;90};9192struct sljit_serialized_label {93sljit_uw size;94};9596struct sljit_serialized_jump {97sljit_uw addr;98sljit_uw flags;99sljit_uw value;100};101102struct sljit_serialized_const {103sljit_uw addr;104};105106#define SLJIT_SERIALIZE_ALIGN(v) (((v) + sizeof(sljit_uw) - 1) & ~(sljit_uw)(sizeof(sljit_uw) - 1))107#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)108#define SLJIT_SERIALIZE_SIGNATURE 0x534c4a54109#else /* !SLJIT_LITTLE_ENDIAN */110#define SLJIT_SERIALIZE_SIGNATURE 0x544a4c53111#endif /* SLJIT_LITTLE_ENDIAN */112#define SLJIT_SERIALIZE_VERSION 1113114SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,115sljit_s32 options, sljit_uw *size)116{117sljit_uw serialized_size = sizeof(struct sljit_serialized_compiler);118struct sljit_memory_fragment *buf;119struct sljit_label *label;120struct sljit_jump *jump;121struct sljit_const *const_;122struct sljit_serialized_compiler *serialized_compiler;123struct sljit_serialized_label *serialized_label;124struct sljit_serialized_jump *serialized_jump;125struct sljit_serialized_const *serialized_const;126#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \127|| (defined SLJIT_DEBUG && SLJIT_DEBUG)128struct sljit_serialized_debug_info *serialized_debug_info;129#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */130sljit_uw counter, used_size;131sljit_u8 *result;132sljit_u8 *ptr;133SLJIT_UNUSED_ARG(options);134135if (size != NULL)136*size = 0;137138PTR_FAIL_IF(compiler->error);139140#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \141|| (defined SLJIT_DEBUG && SLJIT_DEBUG)142if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG))143serialized_size += sizeof(struct sljit_serialized_debug_info);144#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */145146#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)147serialized_size += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));148#endif /* SLJIT_CONFIG_ARM_V6 */149150/* Compute the size of the data. */151buf = compiler->buf;152while (buf != NULL) {153serialized_size += sizeof(sljit_uw) + SLJIT_SERIALIZE_ALIGN(buf->used_size);154buf = buf->next;155}156157serialized_size += compiler->label_count * sizeof(struct sljit_serialized_label);158159jump = compiler->jumps;160while (jump != NULL) {161serialized_size += sizeof(struct sljit_serialized_jump);162jump = jump->next;163}164165const_ = compiler->consts;166while (const_ != NULL) {167serialized_size += sizeof(struct sljit_serialized_const);168const_ = const_->next;169}170171result = (sljit_u8*)SLJIT_MALLOC(serialized_size, compiler->allocator_data);172PTR_FAIL_IF_NULL(result);173174if (size != NULL)175*size = serialized_size;176177ptr = result;178serialized_compiler = (struct sljit_serialized_compiler*)ptr;179ptr += sizeof(struct sljit_serialized_compiler);180181serialized_compiler->signature = SLJIT_SERIALIZE_SIGNATURE;182serialized_compiler->version = SLJIT_SERIALIZE_VERSION;183serialized_compiler->cpu_type = 0;184serialized_compiler->label_count = compiler->label_count;185serialized_compiler->options = compiler->options;186serialized_compiler->scratches = compiler->scratches;187serialized_compiler->saveds = compiler->saveds;188serialized_compiler->fscratches = compiler->fscratches;189serialized_compiler->fsaveds = compiler->fsaveds;190serialized_compiler->local_size = compiler->local_size;191serialized_compiler->size = compiler->size;192193#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)194serialized_compiler->status_flags_state = compiler->status_flags_state;195#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */196197#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \198|| ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \199|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)200serialized_compiler->args_size = compiler->args_size;201#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */202203#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)204serialized_compiler->cpool_diff = compiler->cpool_diff;205serialized_compiler->cpool_fill = compiler->cpool_fill;206serialized_compiler->patches = compiler->patches;207208SLJIT_MEMCPY(ptr, compiler->cpool, compiler->cpool_fill * sizeof(sljit_uw));209SLJIT_MEMCPY(ptr + compiler->cpool_fill * sizeof(sljit_uw), compiler->cpool_unique, compiler->cpool_fill);210ptr += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));211#endif /* SLJIT_CONFIG_ARM_V6 */212213#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)214serialized_compiler->delay_slot = compiler->delay_slot;215#endif /* SLJIT_CONFIG_MIPS */216217buf = compiler->buf;218counter = 0;219while (buf != NULL) {220used_size = buf->used_size;221*(sljit_uw*)ptr = used_size;222ptr += sizeof(sljit_uw);223SLJIT_MEMCPY(ptr, buf->memory, used_size);224ptr += SLJIT_SERIALIZE_ALIGN(used_size);225buf = buf->next;226counter++;227}228serialized_compiler->buf_segment_count = counter;229230label = compiler->labels;231while (label != NULL) {232serialized_label = (struct sljit_serialized_label*)ptr;233serialized_label->size = label->size;234ptr += sizeof(struct sljit_serialized_label);235label = label->next;236}237238jump = compiler->jumps;239counter = 0;240while (jump != NULL) {241serialized_jump = (struct sljit_serialized_jump*)ptr;242serialized_jump->addr = jump->addr;243serialized_jump->flags = jump->flags;244245if (jump->flags & JUMP_ADDR)246serialized_jump->value = jump->u.target;247else if (jump->u.label != NULL)248serialized_jump->value = jump->u.label->u.index;249else250serialized_jump->value = SLJIT_MAX_ADDRESS;251252ptr += sizeof(struct sljit_serialized_jump);253jump = jump->next;254counter++;255}256serialized_compiler->jump_count = counter;257258const_ = compiler->consts;259counter = 0;260while (const_ != NULL) {261serialized_const = (struct sljit_serialized_const*)ptr;262serialized_const->addr = const_->addr;263ptr += sizeof(struct sljit_serialized_const);264const_ = const_->next;265counter++;266}267serialized_compiler->const_count = counter;268269#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \270|| (defined SLJIT_DEBUG && SLJIT_DEBUG)271if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) {272serialized_debug_info = (struct sljit_serialized_debug_info*)ptr;273serialized_debug_info->last_flags = compiler->last_flags;274serialized_debug_info->last_return = compiler->last_return;275serialized_debug_info->logical_local_size = compiler->logical_local_size;276serialized_compiler->cpu_type |= SLJIT_SERIALIZE_DEBUG;277#if (defined SLJIT_DEBUG && SLJIT_DEBUG)278ptr += sizeof(struct sljit_serialized_debug_info);279#endif /* SLJIT_DEBUG */280}281#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */282283SLJIT_ASSERT((sljit_uw)(ptr - result) == serialized_size);284return (sljit_uw*)result;285}286287SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,288sljit_s32 options, void *allocator_data)289{290struct sljit_compiler *compiler;291struct sljit_serialized_compiler *serialized_compiler;292struct sljit_serialized_label *serialized_label;293struct sljit_serialized_jump *serialized_jump;294struct sljit_serialized_const *serialized_const;295#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \296|| (defined SLJIT_DEBUG && SLJIT_DEBUG)297struct sljit_serialized_debug_info *serialized_debug_info;298#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */299struct sljit_memory_fragment *buf;300struct sljit_memory_fragment *last_buf;301struct sljit_label *label;302struct sljit_label *last_label;303struct sljit_label **label_list = NULL;304struct sljit_jump *jump;305struct sljit_jump *last_jump;306struct sljit_const *const_;307struct sljit_const *last_const;308sljit_u8 *ptr = (sljit_u8*)buffer;309sljit_u8 *end = ptr + size;310sljit_uw i, used_size, aligned_size, label_count;311SLJIT_UNUSED_ARG(options);312313if (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0)314return NULL;315316serialized_compiler = (struct sljit_serialized_compiler*)ptr;317318if (serialized_compiler->signature != SLJIT_SERIALIZE_SIGNATURE || serialized_compiler->version != SLJIT_SERIALIZE_VERSION)319return NULL;320321compiler = sljit_create_compiler(allocator_data);322PTR_FAIL_IF(compiler == NULL);323324compiler->label_count = serialized_compiler->label_count;325compiler->options = serialized_compiler->options;326compiler->scratches = serialized_compiler->scratches;327compiler->saveds = serialized_compiler->saveds;328compiler->fscratches = serialized_compiler->fscratches;329compiler->fsaveds = serialized_compiler->fsaveds;330compiler->local_size = serialized_compiler->local_size;331compiler->size = serialized_compiler->size;332333#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)334compiler->status_flags_state = serialized_compiler->status_flags_state;335#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */336337#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \338|| ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \339|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)340compiler->args_size = serialized_compiler->args_size;341#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */342343#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)344used_size = serialized_compiler->cpool_fill;345aligned_size = SLJIT_SERIALIZE_ALIGN(used_size * (sizeof(sljit_uw) + 1));346compiler->cpool_diff = serialized_compiler->cpool_diff;347compiler->cpool_fill = used_size;348compiler->patches = serialized_compiler->patches;349350if ((sljit_uw)(end - ptr) < aligned_size)351goto error;352353SLJIT_MEMCPY(compiler->cpool, ptr, used_size * sizeof(sljit_uw));354SLJIT_MEMCPY(compiler->cpool_unique, ptr + used_size * sizeof(sljit_uw), used_size);355ptr += aligned_size;356#endif /* SLJIT_CONFIG_ARM_V6 */357358#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)359compiler->delay_slot = serialized_compiler->delay_slot;360#endif /* SLJIT_CONFIG_MIPS */361362#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \363|| (defined SLJIT_DEBUG && SLJIT_DEBUG)364if (!(serialized_compiler->cpu_type & SLJIT_SERIALIZE_DEBUG))365goto error;366#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */367368ptr += sizeof(struct sljit_serialized_compiler);369i = serialized_compiler->buf_segment_count;370last_buf = NULL;371while (i > 0) {372if ((sljit_uw)(end - ptr) < sizeof(sljit_uw))373goto error;374375used_size = *(sljit_uw*)ptr;376aligned_size = SLJIT_SERIALIZE_ALIGN(used_size);377ptr += sizeof(sljit_uw);378379if ((sljit_uw)(end - ptr) < aligned_size)380goto error;381382if (last_buf == NULL) {383SLJIT_ASSERT(compiler->buf != NULL && compiler->buf->next == NULL);384buf = compiler->buf;385} else {386buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);387if (!buf)388goto error;389buf->next = NULL;390}391392buf->used_size = used_size;393SLJIT_MEMCPY(buf->memory, ptr, used_size);394395if (last_buf != NULL)396last_buf->next = buf;397last_buf = buf;398399ptr += aligned_size;400i--;401}402403last_label = NULL;404label_count = serialized_compiler->label_count;405if ((sljit_uw)(end - ptr) < label_count * sizeof(struct sljit_serialized_label))406goto error;407408label_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data);409if (label_list == NULL)410goto error;411412for (i = 0; i < label_count; i++) {413label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));414if (label == NULL)415goto error;416417serialized_label = (struct sljit_serialized_label*)ptr;418label->next = NULL;419label->u.index = i;420label->size = serialized_label->size;421422if (last_label != NULL)423last_label->next = label;424else425compiler->labels = label;426last_label = label;427428label_list[i] = label;429ptr += sizeof(struct sljit_serialized_label);430}431compiler->last_label = last_label;432433last_jump = NULL;434i = serialized_compiler->jump_count;435if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump))436goto error;437438while (i > 0) {439jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));440if (jump == NULL)441goto error;442443serialized_jump = (struct sljit_serialized_jump*)ptr;444jump->next = NULL;445jump->addr = serialized_jump->addr;446jump->flags = serialized_jump->flags;447448if (!(serialized_jump->flags & JUMP_ADDR)) {449if (serialized_jump->value != SLJIT_MAX_ADDRESS) {450if (serialized_jump->value >= label_count)451goto error;452jump->u.label = label_list[serialized_jump->value];453} else454jump->u.label = NULL;455} else456jump->u.target = serialized_jump->value;457458if (last_jump != NULL)459last_jump->next = jump;460else461compiler->jumps = jump;462last_jump = jump;463464ptr += sizeof(struct sljit_serialized_jump);465i--;466}467compiler->last_jump = last_jump;468469SLJIT_FREE(label_list, allocator_data);470label_list = NULL;471472last_const = NULL;473i = serialized_compiler->const_count;474if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_const))475goto error;476477while (i > 0) {478const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));479if (const_ == NULL)480goto error;481482serialized_const = (struct sljit_serialized_const*)ptr;483const_->next = NULL;484const_->addr = serialized_const->addr;485486if (last_const != NULL)487last_const->next = const_;488else489compiler->consts = const_;490last_const = const_;491492ptr += sizeof(struct sljit_serialized_const);493i--;494}495compiler->last_const = last_const;496497#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \498|| (defined SLJIT_DEBUG && SLJIT_DEBUG)499if ((sljit_uw)(end - ptr) < sizeof(struct sljit_serialized_debug_info))500goto error;501502serialized_debug_info = (struct sljit_serialized_debug_info*)ptr;503compiler->last_flags = (sljit_s32)serialized_debug_info->last_flags;504compiler->last_return = serialized_debug_info->last_return;505compiler->logical_local_size = serialized_debug_info->logical_local_size;506#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */507508return compiler;509510error:511sljit_free_compiler(compiler);512if (label_list != NULL)513SLJIT_FREE(label_list, allocator_data);514return NULL;515}516517518