source: trunk/submodules/xc_disassembler.c @ 993

Last change on this file since 993 was 993, checked in by moo, 21 months ago

refactor: move functions to module

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1#include "xc_disassembler.h"
2#include "xcache.h"
3#include "xcache/xc_utils.h"
4#include "xcache/xc_sandbox.h"
5#include "xc_processor.h"
6
7static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */
8{
9    const Bucket *b;
10    zval *zv, *list;
11    xc_compile_result_t cr;
12    int bufsize = 2;
13    char *buf;
14    xc_dasm_t dasm;
15
16    xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
17
18    xc_apply_op_array(&cr, (apply_func_t) xc_undo_pass_two TSRMLS_CC);
19    xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC);
20
21    /* go */
22    array_init(output);
23
24    ALLOC_INIT_ZVAL(zv);
25    array_init(zv);
26    xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC);
27    add_assoc_zval_ex(output, ZEND_STRS("op_array"), zv);
28
29    buf = emalloc(bufsize);
30
31    ALLOC_INIT_ZVAL(list);
32    array_init(list);
33    for (b = xc_sandbox_user_function_begin(TSRMLS_C); b; b = b->pListNext) {
34        int keysize, keyLength;
35
36        ALLOC_INIT_ZVAL(zv);
37        array_init(zv);
38        xc_dasm_zend_function(&dasm, zv, b->pData TSRMLS_CC);
39
40        keysize = BUCKET_KEY_SIZE(b) + 2;
41        if (keysize > bufsize) {
42            do {
43                bufsize *= 2;
44            } while (keysize > bufsize);
45            buf = erealloc(buf, bufsize);
46        }
47        memcpy(buf, BUCKET_KEY_S(b), keysize);
48        buf[keysize - 2] = buf[keysize - 1] = ""[0];
49        keyLength = b->nKeyLength;
50#ifdef IS_UNICODE
51        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
52            if (buf[0] == ""[0] && buf[1] == ""[0]) {
53                keyLength ++;
54            }
55        } else
56#endif
57        {
58            if (buf[0] == ""[0]) {
59                keyLength ++;
60            }
61        }
62
63        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
64    }
65    add_assoc_zval_ex(output, ZEND_STRS("function_table"), list);
66   
67    ALLOC_INIT_ZVAL(list);
68    array_init(list);
69    for (b = xc_sandbox_user_class_begin(TSRMLS_C); b; b = b->pListNext) {
70        int keysize, keyLength;
71
72        ALLOC_INIT_ZVAL(zv);
73        array_init(zv);
74        xc_dasm_zend_class_entry(&dasm, zv, CestToCePtr(*(xc_cest_t *)b->pData) TSRMLS_CC);
75
76        keysize = BUCKET_KEY_SIZE(b) + 2;
77        if (keysize > bufsize) {
78            do {
79                bufsize *= 2;
80            } while (keysize > bufsize);
81            buf = erealloc(buf, bufsize);
82        }
83        memcpy(buf, BUCKET_KEY_S(b), keysize);
84        buf[keysize - 2] = buf[keysize - 1] = ""[0];
85        keyLength = b->nKeyLength;
86#ifdef IS_UNICODE
87        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
88            if (buf[0] == ""[0] && buf[1] == ""[0]) {
89                keyLength ++;
90            }
91        } else
92#endif
93        {
94            if (buf[0] == ""[0]) {
95                keyLength ++;
96            }
97        }
98        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
99    }
100    efree(buf);
101    add_assoc_zval_ex(output, ZEND_STRS("class_table"), list);
102
103    /*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
104    xc_compile_result_free(&cr);
105}
106/* }}} */
107typedef struct xc_dasm_sandboxed_t { /* {{{ */
108    enum Type {
109        xc_dasm_file_t
110        , xc_dasm_string_t
111    } type;
112    union {
113        zval *zfilename;
114        struct {
115            zval *source;
116            char *eval_name;
117        } compile_string;
118    } input;
119
120    zval *output;
121} xc_dasm_sandboxed_t; /* }}} */
122zend_op_array *xc_dasm_sandboxed(void *data TSRMLS_DC) /* {{{ */
123{
124    zend_bool catched = 0;
125    zend_op_array *op_array = NULL;
126    xc_dasm_sandboxed_t *sandboxed_dasm = (xc_dasm_sandboxed_t *) data;
127
128    zend_try {
129        if (sandboxed_dasm->type == xc_dasm_file_t) {
130            op_array = compile_filename(ZEND_REQUIRE, sandboxed_dasm->input.zfilename TSRMLS_CC);
131        }
132        else {
133            op_array = compile_string(sandboxed_dasm->input.compile_string.source, sandboxed_dasm->input.compile_string.eval_name TSRMLS_CC);
134        }
135    } zend_catch {
136        catched = 1;
137    } zend_end_try();
138
139    if (catched || !op_array) {
140#define return_value sandboxed_dasm->output
141        RETVAL_FALSE;
142#undef return_value
143        return NULL;
144    }
145
146    xc_dasm(sandboxed_dasm->output, op_array TSRMLS_CC);
147
148    /* free */
149#ifdef ZEND_ENGINE_2
150    destroy_op_array(op_array TSRMLS_CC);
151#else
152    destroy_op_array(op_array);
153#endif
154    efree(op_array);
155
156    return NULL;
157} /* }}} */
158void xc_dasm_string(zval *output, zval *source TSRMLS_DC) /* {{{ */
159{
160    xc_dasm_sandboxed_t sandboxed_dasm;
161    char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
162
163    sandboxed_dasm.output = output;
164    sandboxed_dasm.type = xc_dasm_string_t;
165    sandboxed_dasm.input.compile_string.source = source;
166    sandboxed_dasm.input.compile_string.eval_name = eval_name;
167    xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, eval_name TSRMLS_CC);
168    efree(eval_name);
169}
170/* }}} */
171void xc_dasm_file(zval *output, const char *filename TSRMLS_DC) /* {{{ */
172{
173    zval *zfilename;
174    xc_dasm_sandboxed_t sandboxed_dasm;
175
176    MAKE_STD_ZVAL(zfilename);
177    zfilename->value.str.val = estrdup(filename);
178    zfilename->value.str.len = strlen(filename);
179    zfilename->type = IS_STRING;
180
181    sandboxed_dasm.output = output;
182    sandboxed_dasm.type = xc_dasm_file_t;
183    sandboxed_dasm.input.zfilename = zfilename;
184    xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, zfilename->value.str.val TSRMLS_CC);
185
186    zval_dtor(zfilename);
187    FREE_ZVAL(zfilename);
188}
189/* }}} */
190
191/* {{{ proto array xcache_dasm_file(string filename)
192   Disassemble file into opcode array by filename */
193PHP_FUNCTION(xcache_dasm_file)
194{
195    char *filename;
196    int filename_len;
197
198    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
199        return;
200    }
201    if (!filename_len) RETURN_FALSE;
202
203    xc_dasm_file(return_value, filename TSRMLS_CC);
204}
205/* }}} */
206/* {{{ proto array xcache_dasm_string(string code)
207   Disassemble php code into opcode array */
208PHP_FUNCTION(xcache_dasm_string)
209{
210    zval *code;
211
212    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &code) == FAILURE) {
213        return;
214    }
215    xc_dasm_string(return_value, code TSRMLS_CC);
216}
217/* }}} */
Note: See TracBrowser for help on using the repository browser.