123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780 |
- /*
- +----------------------------------------------------------------------+
- | Zend JIT |
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Dmitry Stogov <dmitry@php.net> |
- | Xinchen Hui <laruence@php.net> |
- | Hao Sun <hao.sun@arm.com> |
- +----------------------------------------------------------------------+
- */
- #ifdef HAVE_CAPSTONE
- # define HAVE_DISASM 1
- # include <capstone/capstone.h>
- # define HAVE_CAPSTONE_ITER 1
- #elif ZEND_JIT_TARGET_X86
- # define HAVE_DISASM 1
- # define DISASM_INTEL_SYNTAX 0
- # include "jit/libudis86/itab.c"
- # include "jit/libudis86/decode.c"
- # include "jit/libudis86/syn.c"
- # if DISASM_INTEL_SYNTAX
- # include "jit/libudis86/syn-intel.c"
- # else
- # include "jit/libudis86/syn-att.c"
- # endif
- # include "jit/libudis86/udis86.c"
- #endif /* HAVE_CAPSTONE */
- #ifdef HAVE_DISASM
- static void zend_jit_disasm_add_symbol(const char *name,
- uint64_t addr,
- uint64_t size);
- #ifndef _WIN32
- # include "jit/zend_elf.c"
- #endif
- #include "zend_sort.h"
- #ifndef _GNU_SOURCE
- # define _GNU_SOURCE
- #endif
- #ifndef _WIN32
- #include <dlfcn.h>
- #endif
- struct _sym_node {
- uint64_t addr;
- uint64_t end;
- struct _sym_node *parent;
- struct _sym_node *child[2];
- unsigned char info;
- char name[1];
- };
- static void zend_syms_rotateleft(zend_sym_node *p) {
- zend_sym_node *r = p->child[1];
- p->child[1] = r->child[0];
- if (r->child[0]) {
- r->child[0]->parent = p;
- }
- r->parent = p->parent;
- if (p->parent == NULL) {
- JIT_G(symbols) = r;
- } else if (p->parent->child[0] == p) {
- p->parent->child[0] = r;
- } else {
- p->parent->child[1] = r;
- }
- r->child[0] = p;
- p->parent = r;
- }
- static void zend_syms_rotateright(zend_sym_node *p) {
- zend_sym_node *l = p->child[0];
- p->child[0] = l->child[1];
- if (l->child[1]) {
- l->child[1]->parent = p;
- }
- l->parent = p->parent;
- if (p->parent == NULL) {
- JIT_G(symbols) = l;
- } else if (p->parent->child[1] == p) {
- p->parent->child[1] = l;
- } else {
- p->parent->child[0] = l;
- }
- l->child[1] = p;
- p->parent = l;
- }
- static void zend_jit_disasm_add_symbol(const char *name,
- uint64_t addr,
- uint64_t size)
- {
- zend_sym_node *sym;
- size_t len = strlen(name);
- sym = malloc(sizeof(zend_sym_node) + len + 1);
- if (!sym) {
- return;
- }
- sym->addr = addr;
- sym->end = (addr + size - 1);
- memcpy((char*)&sym->name, name, len + 1);
- sym->parent = sym->child[0] = sym->child[1] = NULL;
- sym->info = 1;
- if (JIT_G(symbols)) {
- zend_sym_node *node = JIT_G(symbols);
- /* insert it into rbtree */
- do {
- if (sym->addr > node->addr) {
- ZEND_ASSERT(sym->addr > (node->end));
- if (node->child[1]) {
- node = node->child[1];
- } else {
- node->child[1] = sym;
- sym->parent = node;
- break;
- }
- } else if (sym->addr < node->addr) {
- if (node->child[0]) {
- node = node->child[0];
- } else {
- node->child[0] = sym;
- sym->parent = node;
- break;
- }
- } else {
- ZEND_ASSERT(sym->addr == node->addr);
- if (strcmp(name, node->name) == 0 && sym->end < node->end) {
- /* reduce size of the existing symbol */
- node->end = sym->end;
- }
- free(sym);
- return;
- }
- } while (1);
- /* fix rbtree after instering */
- while (sym && sym != JIT_G(symbols) && sym->parent->info == 1) {
- if (sym->parent == sym->parent->parent->child[0]) {
- node = sym->parent->parent->child[1];
- if (node && node->info == 1) {
- sym->parent->info = 0;
- node->info = 0;
- sym->parent->parent->info = 1;
- sym = sym->parent->parent;
- } else {
- if (sym == sym->parent->child[1]) {
- sym = sym->parent;
- zend_syms_rotateleft(sym);
- }
- sym->parent->info = 0;
- sym->parent->parent->info = 1;
- zend_syms_rotateright(sym->parent->parent);
- }
- } else {
- node = sym->parent->parent->child[0];
- if (node && node->info == 1) {
- sym->parent->info = 0;
- node->info = 0;
- sym->parent->parent->info = 1;
- sym = sym->parent->parent;
- } else {
- if (sym == sym->parent->child[0]) {
- sym = sym->parent;
- zend_syms_rotateright(sym);
- }
- sym->parent->info = 0;
- sym->parent->parent->info = 1;
- zend_syms_rotateleft(sym->parent->parent);
- }
- }
- }
- } else {
- JIT_G(symbols) = sym;
- }
- JIT_G(symbols)->info = 0;
- }
- static void zend_jit_disasm_destroy_symbols(zend_sym_node *n) {
- if (n) {
- if (n->child[0]) {
- zend_jit_disasm_destroy_symbols(n->child[0]);
- }
- if (n->child[1]) {
- zend_jit_disasm_destroy_symbols(n->child[1]);
- }
- free(n);
- }
- }
- static const char* zend_jit_disasm_find_symbol(uint64_t addr,
- int64_t *offset) {
- zend_sym_node *node = JIT_G(symbols);
- while (node) {
- if (addr < node->addr) {
- node = node->child[0];
- } else if (addr > node->end) {
- node = node->child[1];
- } else {
- *offset = addr - node->addr;
- return node->name;
- }
- }
- return NULL;
- }
- #ifdef HAVE_CAPSTONE
- static uint64_t zend_jit_disasm_branch_target(csh cs, const cs_insn *insn)
- {
- unsigned int i;
- #if ZEND_JIT_TARGET_X86
- if (cs_insn_group(cs, insn, X86_GRP_JUMP)) {
- for (i = 0; i < insn->detail->x86.op_count; i++) {
- if (insn->detail->x86.operands[i].type == X86_OP_IMM) {
- return insn->detail->x86.operands[i].imm;
- }
- }
- }
- #elif ZEND_JIT_TARGET_ARM64
- if (cs_insn_group(cs, insn, ARM64_GRP_JUMP)
- || insn->id == ARM64_INS_BL
- || insn->id == ARM64_INS_ADR) {
- for (i = 0; i < insn->detail->arm64.op_count; i++) {
- if (insn->detail->arm64.operands[i].type == ARM64_OP_IMM)
- return insn->detail->arm64.operands[i].imm;
- }
- }
- #endif
- return 0;
- }
- #endif
- static const char* zend_jit_disasm_resolver(
- #ifndef HAVE_CAPSTONE
- struct ud *ud,
- #endif
- uint64_t addr,
- int64_t *offset)
- {
- #ifndef _WIN32
- # ifndef HAVE_CAPSTONE
- ((void)ud);
- # endif
- const char *name;
- void *a = (void*)(zend_uintptr_t)(addr);
- Dl_info info;
- name = zend_jit_disasm_find_symbol(addr, offset);
- if (name) {
- return name;
- }
- if (dladdr(a, &info)
- && info.dli_sname != NULL
- && info.dli_saddr == a) {
- return info.dli_sname;
- }
- #else
- const char *name;
- name = zend_jit_disasm_find_symbol(addr, offset);
- if (name) {
- return name;
- }
- #endif
- return NULL;
- }
- static int zend_jit_cmp_labels(Bucket *b1, Bucket *b2)
- {
- return ((b1->h > b2->h) > 0) ? 1 : -1;
- }
- static int zend_jit_disasm(const char *name,
- const char *filename,
- const zend_op_array *op_array,
- zend_cfg *cfg,
- const void *start,
- size_t size)
- {
- const void *end = (void *)((char *)start + size);
- zval zv, *z;
- zend_long n, m;
- HashTable labels;
- uint64_t addr;
- int b;
- #ifdef HAVE_CAPSTONE
- csh cs;
- cs_insn *insn;
- # ifdef HAVE_CAPSTONE_ITER
- const uint8_t *cs_code;
- size_t cs_size;
- uint64_t cs_addr;
- # else
- size_t count, i;
- # endif
- const char *sym;
- int64_t offset = 0;
- char *p, *q, *r;
- #else
- struct ud ud;
- const struct ud_operand *op;
- #endif
- #ifdef HAVE_CAPSTONE
- # if ZEND_JIT_TARGET_X86
- # if defined(__x86_64__) || defined(_WIN64)
- if (cs_open(CS_ARCH_X86, CS_MODE_64, &cs) != CS_ERR_OK)
- return 0;
- # else
- if (cs_open(CS_ARCH_X86, CS_MODE_32, &cs) != CS_ERR_OK)
- return 0;
- # endif
- cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);
- # if DISASM_INTEL_SYNTAX
- cs_option(cs, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
- # else
- cs_option(cs, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
- # endif
- # elif ZEND_JIT_TARGET_ARM64
- if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &cs) != CS_ERR_OK)
- return 0;
- cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);
- cs_option(cs, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
- # endif
- #else
- ud_init(&ud);
- # if defined(__x86_64__) || defined(_WIN64)
- ud_set_mode(&ud, 64);
- # else
- ud_set_mode(&ud, 32);
- # endif
- # if DISASM_INTEL_SYNTAX
- ud_set_syntax(&ud, UD_SYN_INTEL);
- # else
- ud_set_syntax(&ud, UD_SYN_ATT);
- # endif
- ud_set_sym_resolver(&ud, zend_jit_disasm_resolver);
- #endif /* HAVE_CAPSTONE */
- if (name) {
- fprintf(stderr, "%s: ; (%s)\n", name, filename ? filename : "unknown");
- }
- #ifndef HAVE_CAPSTONE
- ud_set_input_buffer(&ud, (uint8_t*)start, (uint8_t*)end - (uint8_t*)start);
- ud_set_pc(&ud, (uint64_t)(uintptr_t)start);
- #endif
- zend_hash_init(&labels, 8, NULL, NULL, 0);
- if (op_array && cfg) {
- ZVAL_FALSE(&zv);
- for (b = 0; b < cfg->blocks_count; b++) {
- if (cfg->blocks[b].flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) {
- addr = (uint64_t)(uintptr_t)op_array->opcodes[cfg->blocks[b].start].handler;
- if (addr >= (uint64_t)(uintptr_t)start && addr < (uint64_t)(uintptr_t)end) {
- zend_hash_index_add(&labels, addr, &zv);
- }
- }
- }
- }
- #ifdef HAVE_CAPSTONE
- ZVAL_TRUE(&zv);
- # ifdef HAVE_CAPSTONE_ITER
- cs_code = start;
- cs_size = (uint8_t*)end - (uint8_t*)start;
- cs_addr = (uint64_t)(uintptr_t)cs_code;
- insn = cs_malloc(cs);
- while (cs_disasm_iter(cs, &cs_code, &cs_size, &cs_addr, insn)) {
- if ((addr = zend_jit_disasm_branch_target(cs, insn))) {
- # else
- count = cs_disasm(cs, start, (uint8_t*)end - (uint8_t*)start, (uintptr_t)start, 0, &insn);
- for (i = 0; i < count; i++) {
- if ((addr = zend_jit_disasm_branch_target(cs, &(insn[i])))) {
- # endif
- if (addr >= (uint64_t)(uintptr_t)start && addr < (uint64_t)(uintptr_t)end) {
- zend_hash_index_add(&labels, addr, &zv);
- }
- }
- }
- #else
- ZVAL_TRUE(&zv);
- while (ud_disassemble(&ud)) {
- op = ud_insn_opr(&ud, 0);
- if (op && op->type == UD_OP_JIMM) {
- addr = ud_syn_rel_target(&ud, (struct ud_operand*)op);
- if (addr >= (uint64_t)(uintptr_t)start && addr < (uint64_t)(uintptr_t)end) {
- zend_hash_index_add(&labels, addr, &zv);
- }
- }
- }
- #endif
- zend_hash_sort(&labels, zend_jit_cmp_labels, 0);
- /* label numbering */
- n = 0; m = 0;
- ZEND_HASH_FOREACH_VAL(&labels, z) {
- if (Z_TYPE_P(z) == IS_FALSE) {
- m--;
- ZVAL_LONG(z, m);
- } else {
- n++;
- ZVAL_LONG(z, n);
- }
- } ZEND_HASH_FOREACH_END();
- #ifdef HAVE_CAPSTONE
- # ifdef HAVE_CAPSTONE_ITER
- cs_code = start;
- cs_size = (uint8_t*)end - (uint8_t*)start;
- cs_addr = (uint64_t)(uintptr_t)cs_code;
- while (cs_disasm_iter(cs, &cs_code, &cs_size, &cs_addr, insn)) {
- z = zend_hash_index_find(&labels, insn->address);
- # else
- for (i = 0; i < count; i++) {
- z = zend_hash_index_find(&labels, insn[i].address);
- # endif
- if (z) {
- if (Z_LVAL_P(z) < 0) {
- fprintf(stderr, ".ENTRY" ZEND_LONG_FMT ":\n", -Z_LVAL_P(z));
- } else {
- fprintf(stderr, ".L" ZEND_LONG_FMT ":\n", Z_LVAL_P(z));
- }
- }
- # ifdef HAVE_CAPSTONE_ITER
- if (JIT_G(debug) & ZEND_JIT_DEBUG_ASM_ADDR) {
- fprintf(stderr, " %" PRIx64 ":", insn->address);
- }
- fprintf(stderr, "\t%s ", insn->mnemonic);
- p = insn->op_str;
- # else
- if (JIT_G(debug) & ZEND_JIT_DEBUG_ASM_ADDR) {
- fprintf(stderr, " %" PRIx64 ":", insn[i].address);
- }
- fprintf(stderr, "\t%s ", insn[i].mnemonic);
- p = insn[i].op_str;
- # endif
- /* Try to replace the target addresses with a symbols */
- while ((q = strchr(p, 'x')) != NULL) {
- if (p != q && *(q-1) == '0') {
- r = q + 1;
- addr = 0;
- while (1) {
- if (*r >= '0' && *r <= '9') {
- addr = addr * 16 + (*r - '0');
- } else if (*r >= 'A' && *r <= 'F') {
- addr = addr * 16 + (*r - 'A' + 10);
- } else if (*r >= 'a' && *r <= 'f') {
- addr = addr * 16 + (*r - 'a' + 10);
- } else {
- break;
- }
- r++;
- }
- if (addr >= (uint64_t)(uintptr_t)start && addr < (uint64_t)(uintptr_t)end) {
- if ((z = zend_hash_index_find(&labels, addr))) {
- if (Z_LVAL_P(z) < 0) {
- fwrite(p, 1, q - p - 1, stderr);
- fprintf(stderr, ".ENTRY" ZEND_LONG_FMT, -Z_LVAL_P(z));
- } else {
- fwrite(p, 1, q - p - 1, stderr);
- fprintf(stderr, ".L" ZEND_LONG_FMT, Z_LVAL_P(z));
- }
- } else {
- fwrite(p, 1, r - p, stderr);
- }
- } else if ((sym = zend_jit_disasm_resolver(addr, &offset))) {
- fwrite(p, 1, q - p - 1, stderr);
- fputs(sym, stderr);
- if (offset != 0) {
- if (offset > 0) {
- fprintf(stderr, "+%" PRIx64, offset);
- } else {
- fprintf(stderr, "-%" PRIx64, offset);
- }
- }
- } else {
- fwrite(p, 1, r - p, stderr);
- }
- p = r;
- } else {
- fwrite(p, 1, q - p + 1, stderr);
- p = q + 1;
- }
- }
- fprintf(stderr, "%s\n", p);
- }
- # ifdef HAVE_CAPSTONE_ITER
- cs_free(insn, 1);
- # else
- cs_free(insn, count);
- # endif
- #else
- ud_set_input_buffer(&ud, (uint8_t*)start, (uint8_t*)end - (uint8_t*)start);
- ud_set_pc(&ud, (uint64_t)(uintptr_t)start);
- while (ud_disassemble(&ud)) {
- addr = ud_insn_off(&ud);
- z = zend_hash_index_find(&labels, addr);
- if (z) {
- if (Z_LVAL_P(z) < 0) {
- fprintf(stderr, ".ENTRY" ZEND_LONG_FMT ":\n", -Z_LVAL_P(z));
- } else {
- fprintf(stderr, ".L" ZEND_LONG_FMT ":\n", Z_LVAL_P(z));
- }
- }
- op = ud_insn_opr(&ud, 0);
- if (op && op->type == UD_OP_JIMM) {
- addr = ud_syn_rel_target(&ud, (struct ud_operand*)op);
- if (addr >= (uint64_t)(uintptr_t)start && addr < (uint64_t)(uintptr_t)end) {
- z = zend_hash_index_find(&labels, addr);
- if (z) {
- const char *str = ud_insn_asm(&ud);
- int len;
- len = 0;
- while (str[len] != 0 && str[len] != ' ' && str[len] != '\t') {
- len++;
- }
- if (str[len] != 0) {
- while (str[len] == ' ' || str[len] == '\t') {
- len++;
- }
- if (Z_LVAL_P(z) < 0) {
- fprintf(stderr, "\t%.*s.ENTRY" ZEND_LONG_FMT "\n", len, str, -Z_LVAL_P(z));
- } else {
- fprintf(stderr, "\t%.*s.L" ZEND_LONG_FMT "\n", len, str, Z_LVAL_P(z));
- }
- continue;
- }
- }
- }
- }
- if (JIT_G(debug) & ZEND_JIT_DEBUG_ASM_ADDR) {
- fprintf(stderr, " %" PRIx64 ":", ud_insn_off(&ud));
- }
- fprintf(stderr, "\t%s\n", ud_insn_asm(&ud));
- }
- #endif
- fprintf(stderr, "\n");
- zend_hash_destroy(&labels);
- #ifdef HAVE_CAPSTONE
- cs_close(&cs);
- #endif
- return 1;
- }
- static int zend_jit_disasm_init(void)
- {
- #ifndef ZTS
- #define REGISTER_EG(n) \
- zend_jit_disasm_add_symbol("EG("#n")", \
- (uint64_t)(uintptr_t)&executor_globals.n, sizeof(executor_globals.n))
- REGISTER_EG(uninitialized_zval);
- REGISTER_EG(exception);
- REGISTER_EG(vm_interrupt);
- REGISTER_EG(exception_op);
- REGISTER_EG(timed_out);
- REGISTER_EG(current_execute_data);
- REGISTER_EG(vm_stack_top);
- REGISTER_EG(vm_stack_end);
- REGISTER_EG(symbol_table);
- REGISTER_EG(jit_trace_num);
- #undef REGISTER_EG
- #define REGISTER_CG(n) \
- zend_jit_disasm_add_symbol("CG("#n")", \
- (uint64_t)(uintptr_t)&compiler_globals.n, sizeof(compiler_globals.n))
- REGISTER_CG(map_ptr_base);
- #undef REGISTER_CG
- #endif
- /* Register JIT helper functions */
- #define REGISTER_HELPER(n) \
- zend_jit_disasm_add_symbol(#n, \
- (uint64_t)(uintptr_t)n, sizeof(void*));
- REGISTER_HELPER(memcmp);
- REGISTER_HELPER(zend_jit_init_func_run_time_cache_helper);
- REGISTER_HELPER(zend_jit_find_func_helper);
- REGISTER_HELPER(zend_jit_find_ns_func_helper);
- REGISTER_HELPER(zend_jit_find_method_helper);
- REGISTER_HELPER(zend_jit_find_method_tmp_helper);
- REGISTER_HELPER(zend_jit_push_static_metod_call_frame);
- REGISTER_HELPER(zend_jit_push_static_metod_call_frame_tmp);
- REGISTER_HELPER(zend_jit_invalid_method_call);
- REGISTER_HELPER(zend_jit_invalid_method_call_tmp);
- REGISTER_HELPER(zend_jit_unref_helper);
- REGISTER_HELPER(zend_jit_extend_stack_helper);
- REGISTER_HELPER(zend_jit_int_extend_stack_helper);
- REGISTER_HELPER(zend_jit_leave_nested_func_helper);
- REGISTER_HELPER(zend_jit_leave_top_func_helper);
- REGISTER_HELPER(zend_jit_leave_func_helper);
- REGISTER_HELPER(zend_jit_symtable_find);
- REGISTER_HELPER(zend_jit_hash_index_lookup_rw_no_packed);
- REGISTER_HELPER(zend_jit_hash_index_lookup_rw);
- REGISTER_HELPER(zend_jit_hash_lookup_rw);
- REGISTER_HELPER(zend_jit_symtable_lookup_rw);
- REGISTER_HELPER(zend_jit_symtable_lookup_w);
- REGISTER_HELPER(zend_jit_undefined_op_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_r_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_is_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_isset_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_str_offset_r_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_str_r_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_str_is_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_obj_r_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_obj_is_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_rw_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_w_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_obj_rw_helper);
- REGISTER_HELPER(zend_jit_fetch_dim_obj_w_helper);
- // REGISTER_HELPER(zend_jit_fetch_dim_obj_unset_helper);
- REGISTER_HELPER(zend_jit_assign_dim_helper);
- REGISTER_HELPER(zend_jit_assign_dim_op_helper);
- REGISTER_HELPER(zend_jit_fast_assign_concat_helper);
- REGISTER_HELPER(zend_jit_fast_concat_helper);
- REGISTER_HELPER(zend_jit_fast_concat_tmp_helper);
- REGISTER_HELPER(zend_jit_isset_dim_helper);
- REGISTER_HELPER(zend_jit_free_call_frame);
- REGISTER_HELPER(zend_jit_fetch_global_helper);
- REGISTER_HELPER(zend_jit_verify_arg_slow);
- REGISTER_HELPER(zend_jit_verify_return_slow);
- REGISTER_HELPER(zend_jit_fetch_obj_r_slow);
- REGISTER_HELPER(zend_jit_fetch_obj_r_dynamic);
- REGISTER_HELPER(zend_jit_fetch_obj_is_slow);
- REGISTER_HELPER(zend_jit_fetch_obj_is_dynamic);
- REGISTER_HELPER(zend_jit_fetch_obj_w_slow);
- REGISTER_HELPER(zend_jit_check_array_promotion);
- REGISTER_HELPER(zend_jit_create_typed_ref);
- REGISTER_HELPER(zend_jit_extract_helper);
- REGISTER_HELPER(zend_jit_vm_stack_free_args_helper);
- REGISTER_HELPER(zend_jit_copy_extra_args_helper);
- REGISTER_HELPER(zend_jit_deprecated_helper);
- REGISTER_HELPER(zend_jit_assign_const_to_typed_ref);
- REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref);
- REGISTER_HELPER(zend_jit_assign_var_to_typed_ref);
- REGISTER_HELPER(zend_jit_assign_cv_to_typed_ref);
- REGISTER_HELPER(zend_jit_pre_inc_typed_ref);
- REGISTER_HELPER(zend_jit_pre_dec_typed_ref);
- REGISTER_HELPER(zend_jit_post_inc_typed_ref);
- REGISTER_HELPER(zend_jit_post_dec_typed_ref);
- REGISTER_HELPER(zend_jit_assign_op_to_typed_ref);
- REGISTER_HELPER(zend_jit_assign_op_to_typed_ref_tmp);
- REGISTER_HELPER(zend_jit_only_vars_by_reference);
- REGISTER_HELPER(zend_jit_invalid_array_access);
- REGISTER_HELPER(zend_jit_invalid_property_read);
- REGISTER_HELPER(zend_jit_invalid_property_write);
- REGISTER_HELPER(zend_jit_invalid_property_incdec);
- REGISTER_HELPER(zend_jit_invalid_property_assign);
- REGISTER_HELPER(zend_jit_invalid_property_assign_op);
- REGISTER_HELPER(zend_jit_prepare_assign_dim_ref);
- REGISTER_HELPER(zend_jit_pre_inc);
- REGISTER_HELPER(zend_jit_pre_dec);
- REGISTER_HELPER(zend_runtime_jit);
- REGISTER_HELPER(zend_jit_hot_func);
- REGISTER_HELPER(zend_jit_check_constant);
- REGISTER_HELPER(zend_jit_get_constant);
- REGISTER_HELPER(zend_jit_array_free);
- REGISTER_HELPER(zend_jit_zval_array_dup);
- REGISTER_HELPER(zend_jit_add_arrays_helper);
- REGISTER_HELPER(zend_jit_assign_obj_helper);
- REGISTER_HELPER(zend_jit_assign_obj_op_helper);
- REGISTER_HELPER(zend_jit_assign_to_typed_prop);
- REGISTER_HELPER(zend_jit_assign_op_to_typed_prop);
- REGISTER_HELPER(zend_jit_inc_typed_prop);
- REGISTER_HELPER(zend_jit_dec_typed_prop);
- REGISTER_HELPER(zend_jit_pre_inc_typed_prop);
- REGISTER_HELPER(zend_jit_pre_dec_typed_prop);
- REGISTER_HELPER(zend_jit_post_inc_typed_prop);
- REGISTER_HELPER(zend_jit_post_dec_typed_prop);
- REGISTER_HELPER(zend_jit_pre_inc_obj_helper);
- REGISTER_HELPER(zend_jit_pre_dec_obj_helper);
- REGISTER_HELPER(zend_jit_post_inc_obj_helper);
- REGISTER_HELPER(zend_jit_post_dec_obj_helper);
- REGISTER_HELPER(zend_jit_rope_end);
- #if (PHP_VERSION_ID <= 80100) && (SIZEOF_SIZE_T == 4)
- REGISTER_HELPER(zval_jit_update_constant_ex);
- #endif
- REGISTER_HELPER(zend_jit_free_trampoline_helper);
- REGISTER_HELPER(zend_jit_exception_in_interrupt_handler_helper);
- #undef REGISTER_HELPER
- #ifndef _WIN32
- zend_elf_load_symbols();
- #endif
- if (zend_vm_kind() == ZEND_VM_KIND_HYBRID) {
- zend_op opline;
- memset(&opline, 0, sizeof(opline));
- opline.opcode = ZEND_DO_UCALL;
- opline.result_type = IS_UNUSED;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_DO_UCALL;
- opline.result_type = IS_VAR;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_UCALL_SPEC_RETVAL_USED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_DO_FCALL_BY_NAME;
- opline.result_type = IS_UNUSED;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_DO_FCALL_BY_NAME;
- opline.result_type = IS_VAR;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_DO_FCALL;
- opline.result_type = IS_UNUSED;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_DO_FCALL;
- opline.result_type = IS_VAR;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_DO_FCALL_SPEC_RETVAL_USED_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_RETURN;
- opline.op1_type = IS_CONST;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_RETURN_SPEC_CONST_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_RETURN;
- opline.op1_type = IS_TMP_VAR;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_RETURN_SPEC_TMP_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_RETURN;
- opline.op1_type = IS_VAR;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_RETURN_SPEC_VAR_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- opline.opcode = ZEND_RETURN;
- opline.op1_type = IS_CV;
- zend_vm_set_opcode_handler(&opline);
- zend_jit_disasm_add_symbol("ZEND_RETURN_SPEC_CV_LABEL", (uint64_t)(uintptr_t)opline.handler, sizeof(void*));
- zend_jit_disasm_add_symbol("ZEND_HYBRID_HALT_LABEL", (uint64_t)(uintptr_t)zend_jit_halt_op->handler, sizeof(void*));
- }
- return 1;
- }
- static void zend_jit_disasm_shutdown(void)
- {
- if (JIT_G(symbols)) {
- zend_jit_disasm_destroy_symbols(JIT_G(symbols));
- JIT_G(symbols) = NULL;
- }
- }
- #endif /* HAVE_DISASM */
|