From c6cb411d3905a790f9eb059c0ff0dd39fba4017a Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 10 Nov 2013 13:01:46 +0000 Subject: [PATCH] execution --- phpdbg.c | 31 +++++++++------ phpdbg.h | 1 + phpdbg_prompt.c | 100 +++++++++++++++++++++++++++++++++++++++++------- phpdbg_prompt.h | 1 + test.php | 3 ++ 5 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 test.php diff --git a/phpdbg.c b/phpdbg.c index b416a54fa6..3b1a93b172 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -20,15 +20,21 @@ ZEND_DECLARE_MODULE_GLOBALS(phpdbg); +void (*zend_execute_old)(zend_execute_data *execute_data TSRMLS_DC); +void (*zend_execute_internal_old)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); + static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) { - pg->exec = NULL; - pg->ops = NULL; + pg->exec = NULL; + pg->ops = NULL; } static PHP_MINIT_FUNCTION(phpdbg) { - ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL); + ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL); + + zend_execute_old = zend_execute_ex; + zend_execute_ex = phpdbg_execute_ex; - return SUCCESS; + return SUCCESS; } static inline void php_phpdbg_destroy_break(void *brake) { @@ -42,16 +48,17 @@ static PHP_RINIT_FUNCTION(phpdbg) { } static PHP_RSHUTDOWN_FUNCTION(phpdbg) { - zend_hash_destroy(&PHPDBG_G(breaks)); + zend_hash_destroy(&PHPDBG_G(breaks)); - if (PHPDBG_G(exec)) { - efree(PHPDBG_G(exec)); - } + if (PHPDBG_G(exec)) { + efree(PHPDBG_G(exec)); + } - if (PHPDBG_G(ops)) { - destroy_op_array(PHPDBG_G(ops) TSRMLS_CC); - efree(PHPDBG_G(ops)); - } + if (PHPDBG_G(ops)) { + destroy_op_array(PHPDBG_G(ops) TSRMLS_CC); + efree(PHPDBG_G(ops)); + } + return SUCCESS; } static zend_module_entry sapi_phpdbg_module_entry = { diff --git a/phpdbg.h b/phpdbg.h index ba3ea5d533..a3da778520 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -41,6 +41,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *exec; /* file to execute */ size_t exec_len; /* size of exec */ zend_op_array *ops; /* op_array */ + zval *retval; /* return value */ ZEND_END_MODULE_GLOBALS(phpdbg) #include "phpdbg_prompt.h" diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index a1f9685066..31722665b3 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -20,6 +20,7 @@ #include #include #include "zend.h" +#include "zend_compile.h" #include "phpdbg.h" #include "phpdbg_help.h" @@ -52,9 +53,23 @@ static PHPDBG_COMMAND(exec) { /* {{{ */ return SUCCESS; } /* }}} */ -static PHPDBG_COMMAND(compile) { /* {{{ */ - zend_file_handle fh; +static inline int phpdbg_compile(TSRMLS_D) { + zend_file_handle fh; + printf("Attempting compilation of %s\n", PHPDBG_G(exec)); + if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { + PHPDBG_G(ops) = zend_compile_file( + &fh, ZEND_INCLUDE TSRMLS_CC); + zend_destroy_file_handle(&fh TSRMLS_CC); + printf("Success\n"); + return SUCCESS; + } else { + printf("Could not open file %s\n", PHPDBG_G(exec)); + return FAILURE; + } +} + +static PHPDBG_COMMAND(compile) { /* {{{ */ if (PHPDBG_G(exec)) { if (PHPDBG_G(ops)) { @@ -63,23 +78,39 @@ static PHPDBG_COMMAND(compile) { /* {{{ */ efree(PHPDBG_G(ops)); } - printf("Attempting compilation of %s\n", PHPDBG_G(exec)); - if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { - PHPDBG_G(ops) = zend_compile_file( - &fh, ZEND_INCLUDE TSRMLS_CC); - zend_destroy_file_handle(&fh TSRMLS_CC); - printf("Success\n"); - return SUCCESS; - } else { - printf("Could not open file %s\n", PHPDBG_G(exec)); - return FAILURE; - } + return phpdbg_compile(TSRMLS_C); } else { printf("No execution context\n"); return FAILURE; } } /* }}} */ +static PHPDBG_COMMAND(run) { /* {{{ */ + if (PHPDBG_G(ops) || PHPDBG_G(exec)) { + if (!PHPDBG_G(ops)) { + if (phpdbg_compile(TSRMLS_C) == FAILURE) { + printf("Failed to compile %s, cannot run\n", PHPDBG_G(exec)); + return FAILURE; + } + } + + EG(active_op_array) = PHPDBG_G(ops); + EG(return_value_ptr_ptr) = &PHPDBG_G(retval); + + zend_try { + zend_execute(EG(active_op_array) TSRMLS_CC); + } zend_catch { + printf("Caught excetion in VM\n"); + return FAILURE; + } zend_end_try(); + + return SUCCESS; + } else { + printf("Nothing to execute !"); + return FAILURE; + } +} /* }}} */ + static PHPDBG_COMMAND(print) { /* {{{ */ if (!expr_len) { printf("Showing Execution Context Information:\n"); @@ -144,6 +175,7 @@ static PHPDBG_COMMAND(help) /* {{{ */ static const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(exec, "set execution context"), PHPDBG_COMMAND_D(compile, "attempt to pre-compile execution context"), + PHPDBG_COMMAND_D(run, "attempt execution"), PHPDBG_COMMAND_D(print, "print something"), PHPDBG_COMMAND_D(break, "set breakpoint"), PHPDBG_COMMAND_D(help, "show help menu"), @@ -190,3 +222,45 @@ void phpdbg_interactive(int argc, char **argv TSRMLS_DC) /* {{{ */ printf("phpdbg> "); } } /* }}} */ + +void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) +{ + zend_bool original_in_execution; + + original_in_execution = EG(in_execution); + EG(in_execution) = 1; + + if (0) { +zend_vm_enter: + execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); + } + + while (1) { + int ret; +#ifdef ZEND_WIN32 + if (EG(timed_out)) { + zend_timeout(0); + } +#endif + + printf("[OPLINE: %p]\n", execute_data->opline); + + if ((ret = execute_data->opline->handler(execute_data TSRMLS_CC)) > 0) { + switch (ret) { + case 1: + EG(in_execution) = original_in_execution; + return; + case 2: + goto zend_vm_enter; + break; + case 3: + execute_data = EG(current_execute_data); + break; + default: + break; + } + } + + } + zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); +} diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 590358bf44..028f2c080a 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -57,5 +57,6 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le int phpdbg_do_##name(const char *expr, size_t expr_len TSRMLS_DC) void phpdbg_interactive(int argc, char **argv TSRMLS_DC); +void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC); #endif /* PHPDBG_PROMPT_H */ diff --git a/test.php b/test.php new file mode 100644 index 0000000000..2f3600c6a0 --- /dev/null +++ b/test.php @@ -0,0 +1,3 @@ + -- 2.50.1