mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Provide method to access opcodes via command line argument
This commit is contained in:
parent
4a38f51857
commit
31e98386db
4 changed files with 153 additions and 3 deletions
|
@ -32,6 +32,7 @@
|
||||||
#include "phpdbg_io.h"
|
#include "phpdbg_io.h"
|
||||||
#include "zend_alloc.h"
|
#include "zend_alloc.h"
|
||||||
#include "phpdbg_eol.h"
|
#include "phpdbg_eol.h"
|
||||||
|
#include "phpdbg_print.h"
|
||||||
|
|
||||||
#include "ext/standard/basic_functions.h"
|
#include "ext/standard/basic_functions.h"
|
||||||
|
|
||||||
|
@ -761,6 +762,7 @@ const opt_struct OPTIONS[] = { /* {{{ */
|
||||||
{'a', 1, "address-or-any"},
|
{'a', 1, "address-or-any"},
|
||||||
#endif
|
#endif
|
||||||
{'x', 0, "xml output"},
|
{'x', 0, "xml output"},
|
||||||
|
{'p', 2, "show opcodes"},
|
||||||
{'h', 0, "help"},
|
{'h', 0, "help"},
|
||||||
{'V', 0, "version"},
|
{'V', 0, "version"},
|
||||||
{'-', 0, NULL}
|
{'-', 0, NULL}
|
||||||
|
@ -1028,6 +1030,7 @@ int main(int argc, char **argv) /* {{{ */
|
||||||
int server = -1;
|
int server = -1;
|
||||||
int socket = -1;
|
int socket = -1;
|
||||||
FILE* stream = NULL;
|
FILE* stream = NULL;
|
||||||
|
char *print_opline_func;
|
||||||
|
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
void ***tsrm_ls;
|
void ***tsrm_ls;
|
||||||
|
@ -1204,6 +1207,12 @@ phpdbg_main:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 'p': {
|
||||||
|
print_opline_func = php_optarg;
|
||||||
|
show_banner = 0;
|
||||||
|
settings = (void *) 0x1;
|
||||||
|
} break;
|
||||||
|
|
||||||
case 'h': {
|
case 'h': {
|
||||||
sapi_startup(phpdbg);
|
sapi_startup(phpdbg);
|
||||||
phpdbg->startup(phpdbg);
|
phpdbg->startup(phpdbg);
|
||||||
|
@ -1231,6 +1240,8 @@ phpdbg_main:
|
||||||
return 0;
|
return 0;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
php_optarg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set exec if present on command line */
|
/* set exec if present on command line */
|
||||||
|
@ -1306,7 +1317,7 @@ phpdbg_main:
|
||||||
/* set flags from command line */
|
/* set flags from command line */
|
||||||
PHPDBG_G(flags) = flags;
|
PHPDBG_G(flags) = flags;
|
||||||
|
|
||||||
if (settings) {
|
if (settings > (zend_phpdbg_globals *) 0x2) {
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
*((zend_phpdbg_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
|
*((zend_phpdbg_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
|
||||||
#else
|
#else
|
||||||
|
@ -1509,6 +1520,15 @@ phpdbg_main:
|
||||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings == (void *) 0x1) {
|
||||||
|
if (PHPDBG_G(ops)) {
|
||||||
|
phpdbg_print_opcodes(print_opline_func);
|
||||||
|
} else {
|
||||||
|
write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("No opcodes could be compiled | No file specified or compilation failed?\n"));
|
||||||
|
}
|
||||||
|
goto phpdbg_out;
|
||||||
|
}
|
||||||
|
|
||||||
/* step from here, not through init */
|
/* step from here, not through init */
|
||||||
if (step) {
|
if (step) {
|
||||||
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
|
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
|
||||||
|
|
|
@ -389,6 +389,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
||||||
" **-l** **-l**4000 Setup remote console ports" CR
|
" **-l** **-l**4000 Setup remote console ports" CR
|
||||||
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
|
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
|
||||||
" **-x** Enable xml output (instead of normal text output)" CR
|
" **-x** Enable xml output (instead of normal text output)" CR
|
||||||
|
" **-p** **-p**, **-p=func**, **-p* ** Output opcodes and quit" CR
|
||||||
" **-h** Print the help overview" CR
|
" **-h** Print the help overview" CR
|
||||||
" **-V** Print version number" CR
|
" **-V** Print version number" CR
|
||||||
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
|
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
|
||||||
|
@ -396,12 +397,21 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
||||||
|
|
||||||
"**Remote Console Mode**" CR CR
|
"**Remote Console Mode**" CR CR
|
||||||
|
|
||||||
"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback "
|
"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback "
|
||||||
"interface by default, and this can only be overridden by explicitly setting the remote console "
|
"interface by default, and this can only be overridden by explicitly setting the remote console "
|
||||||
"bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg "
|
"bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg "
|
||||||
"will bind to all available interfaces. You should be aware of the security implications of "
|
"will bind to all available interfaces. You should be aware of the security implications of "
|
||||||
"doing this, so measures should be taken to secure this service if bound to a publicly accessible "
|
"doing this, so measures should be taken to secure this service if bound to a publicly accessible "
|
||||||
"interface/port."
|
"interface/port." CR CR
|
||||||
|
|
||||||
|
"**Opcode output**" CR CR
|
||||||
|
|
||||||
|
"Outputting opcodes requires that a file path is passed as last argument. Modes of execution:" CR
|
||||||
|
"**-p** Outputs the main execution context" CR
|
||||||
|
"**-p* **Outputs all opcodes in the whole file (including classes and functions)" CR
|
||||||
|
"**-p=function_name** Outputs opcodes of a given function in the file" CR
|
||||||
|
"**-p=class_name::** Outputs opcodes of all the methods of a given class" CR
|
||||||
|
"**-p=class_name::method** Outputs opcodes of a given method"
|
||||||
},
|
},
|
||||||
|
|
||||||
{"phpdbginit", CR
|
{"phpdbginit", CR
|
||||||
|
|
|
@ -260,3 +260,121 @@ PHPDBG_PRINT(func) /* {{{ */
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
|
void phpdbg_print_opcodes_main() {
|
||||||
|
phpdbg_out("function name: (null)\n");
|
||||||
|
phpdbg_print_function_helper((zend_function *) PHPDBG_G(ops));
|
||||||
|
}
|
||||||
|
|
||||||
|
void phpdbg_print_opcodes_function(const char *function, size_t len) {
|
||||||
|
zend_function *func = zend_hash_str_find_ptr(EG(function_table), function, len);
|
||||||
|
|
||||||
|
if (!func) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
phpdbg_out("function name: %.*s\n", (int) len, function);
|
||||||
|
phpdbg_print_function_helper(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void phpdbg_print_opcodes_method(const char *class, const char *function) {
|
||||||
|
zend_class_entry *ce = zend_hash_str_find_ptr(EG(class_table), class, strlen(class));
|
||||||
|
zend_function *func;
|
||||||
|
|
||||||
|
if (!ce) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ce->type != ZEND_USER_CLASS) {
|
||||||
|
phpdbg_out("function name: %s::%s (internal)\n", class, function);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(func = zend_hash_str_find_ptr(&ce->function_table, function, strlen(function)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
phpdbg_out("function name: %s::%s\n", class, function);
|
||||||
|
phpdbg_print_function_helper(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void phpdbg_print_opcodes_class(const char *class) {
|
||||||
|
zend_class_entry *ce;
|
||||||
|
zend_function *method;
|
||||||
|
zend_string *method_name;
|
||||||
|
zend_bool first = 1;
|
||||||
|
|
||||||
|
if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
phpdbg_out("%s %s: %s\n",
|
||||||
|
(ce->type == ZEND_USER_CLASS) ?
|
||||||
|
"user" : "internal",
|
||||||
|
(ce->ce_flags & ZEND_ACC_INTERFACE) ?
|
||||||
|
"interface" :
|
||||||
|
(ce->ce_flags & ZEND_ACC_ABSTRACT) ?
|
||||||
|
"abstract Class" :
|
||||||
|
"class",
|
||||||
|
ce->name->val);
|
||||||
|
|
||||||
|
if (ce->type != ZEND_USER_CLASS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
phpdbg_out("%d methods: ", zend_hash_num_elements(&ce->function_table));
|
||||||
|
ZEND_HASH_FOREACH_PTR(&ce->function_table, method) {
|
||||||
|
if (first) {
|
||||||
|
first = 0;
|
||||||
|
} else {
|
||||||
|
phpdbg_out(", ");
|
||||||
|
}
|
||||||
|
phpdbg_out("%s", method->common.function_name->val);
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
if (first) {
|
||||||
|
phpdbg_out("-");
|
||||||
|
}
|
||||||
|
phpdbg_out("\n");
|
||||||
|
|
||||||
|
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, method_name, method) {
|
||||||
|
phpdbg_out("\nfunction name: %s\n", method_name);
|
||||||
|
phpdbg_print_function_helper(method);
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPDBG_API void phpdbg_print_opcodes(char *function)
|
||||||
|
{
|
||||||
|
char *method_name;
|
||||||
|
|
||||||
|
strtok(function, ":");
|
||||||
|
|
||||||
|
if (function == NULL) {
|
||||||
|
phpdbg_print_opcodes_main();
|
||||||
|
} else if (function[0] == '*' && function[1] == 0) {
|
||||||
|
/* all */
|
||||||
|
zend_string *name;
|
||||||
|
zend_function *func;
|
||||||
|
zend_class_entry *ce;
|
||||||
|
|
||||||
|
phpdbg_print_opcodes_main();
|
||||||
|
|
||||||
|
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(function_table), name, func) {
|
||||||
|
if (func->type == ZEND_USER_FUNCTION) {
|
||||||
|
phpdbg_out("\n");
|
||||||
|
phpdbg_print_opcodes_function(name->val, name->len);
|
||||||
|
}
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
|
||||||
|
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), name, ce) {
|
||||||
|
if (ce->type == ZEND_USER_CLASS) {
|
||||||
|
phpdbg_out("\n\n");
|
||||||
|
phpdbg_print_opcodes_class(name->val);
|
||||||
|
}
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
} else if ((method_name = strtok(NULL, ":")) == NULL) {
|
||||||
|
phpdbg_print_opcodes_function(function, strlen(function));
|
||||||
|
} else if (++method_name == NULL || ++method_name == NULL) {
|
||||||
|
phpdbg_print_opcodes_class(function);
|
||||||
|
} else {
|
||||||
|
phpdbg_print_opcodes_method(function, method_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ PHPDBG_PRINT(method);
|
||||||
PHPDBG_PRINT(func);
|
PHPDBG_PRINT(func);
|
||||||
PHPDBG_PRINT(stack);
|
PHPDBG_PRINT(stack);
|
||||||
|
|
||||||
|
PHPDBG_API void phpdbg_print_opcodes(char *function);
|
||||||
|
|
||||||
extern const phpdbg_command_t phpdbg_print_commands[];
|
extern const phpdbg_command_t phpdbg_print_commands[];
|
||||||
|
|
||||||
#endif /* PHPDBG_PRINT_H */
|
#endif /* PHPDBG_PRINT_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue