转载:http://www.laruence.com/2008/09/23/539.html
php version:5.6.22
mac
#include <stdio.h>
#include "../php/php-5.6.22/sapi/embed/php_embed.h"
#ifdef ZTS
void ***tsrm_ls;
#endif
//#define BUFFER_LEN 10000;
char *opname(zend_uchar opcode)
{
switch (opcode) {
case ZEND_NOP:
return "ZEND_NOP";
case ZEND_ADD:
return "ZEND_ADD";
case ZEND_SUB:
return "ZEND_SUB";
case ZEND_MUL:
return "ZEND_MUL";
case ZEND_DIV:
return "ZEND_DIV";
case ZEND_MOD:
return "ZEND_MOD";
case ZEND_SL:
return "ZEND_SL";
case ZEND_SR:
return "ZEND_SR";
case ZEND_CONCAT:
return "ZEND_CONCAT";
case ZEND_BW_OR:
return "ZEND_BW_OR";
case ZEND_BW_AND:
return "ZEND_BW_AND";
case ZEND_BW_XOR:
return "ZEND_BW_XOR";
case ZEND_BW_NOT:
return "ZEND_BW_NOT";
case ZEND_BOOL_NOT:
return "ZEND_BOOL_NOT";
case ZEND_BOOL_XOR:
return "ZEND_BOOL_XOR";
case ZEND_IS_IDENTICAL:
return "ZEND_IS_IDENTICAL";
case ZEND_IS_NOT_IDENTICAL:
return "ZEND_IS_NOT_IDENTICAL";
case ZEND_IS_EQUAL:
return "ZEND_IS_EQUAL";
case ZEND_IS_NOT_EQUAL:
return "ZEND_IS_NOT_EQUAL";
case ZEND_IS_SMALLER:
return "ZEND_IS_SMALLER";
case ZEND_IS_SMALLER_OR_EQUAL:
return "ZEND_IS_SMALLER_OR_EQUAL";
case ZEND_CAST:
return "ZEND_CAST";
case ZEND_QM_ASSIGN:
return "ZEND_QM_ASSIGN";
case ZEND_ASSIGN_ADD:
return "ZEND_ASSIGN_ADD";
case ZEND_ASSIGN_SUB:
return "ZEND_ASSIGN_SUB";
case ZEND_ASSIGN_MUL:
return "ZEND_ASSIGN_MUL";
case ZEND_ASSIGN_DIV:
return "ZEND_ASSIGN_DIV";
case ZEND_ASSIGN_MOD:
return "ZEND_ASSIGN_MOD";
case ZEND_ASSIGN_SL:
return "ZEND_ASSIGN_SL";
case ZEND_ASSIGN_SR:
return "ZEND_ASSIGN_SR";
case ZEND_ASSIGN_CONCAT:
return "ZEND_ASSIGN_CONCAT";
case ZEND_ASSIGN_BW_OR:
return "ZEND_ASSIGN_BW_OR";
case ZEND_ASSIGN_BW_AND:
return "ZEND_ASSIGN_BW_AND";
case ZEND_ASSIGN_BW_XOR:
return "ZEND_ASSIGN_BW_XOR";
case ZEND_PRE_INC:
return "ZEND_PRE_INC";
case ZEND_PRE_DEC:
return "ZEND_PRE_DEC";
case ZEND_POST_INC:
return "ZEND_POST_INC";
case ZEND_POST_DEC:
return "ZEND_POST_DEC";
case ZEND_ASSIGN:
return "ZEND_ASSIGN";
case ZEND_ASSIGN_REF:
return "ZEND_ASSIGN_REF";
case ZEND_ECHO:
return "ZEND_ECHO";
case ZEND_PRINT:
return "ZEND_PRINT";
case ZEND_JMP:
return "ZEND_JMP";
case ZEND_JMPZ:
return "ZEND_JMPZ";
case ZEND_JMPNZ:
return "ZEND_JMPNZ";
case ZEND_JMPZNZ:
return "ZEND_JMPZNZ";
case ZEND_JMPZ_EX:
return "ZEND_JMPZ_EX";
case ZEND_JMPNZ_EX:
return "ZEND_JMPNZ_EX";
case ZEND_CASE:
return "ZEND_CASE";
case ZEND_SWITCH_FREE:
return "ZEND_SWITCH_FREE";
case ZEND_BRK:
return "ZEND_BRK";
case ZEND_CONT:
return "ZEND_CONT";
case ZEND_BOOL:
return "ZEND_BOOL";
case ZEND_INIT_STRING:
return "ZEND_INIT_STRING";
case ZEND_ADD_CHAR:
return "ZEND_ADD_CHAR";
case ZEND_ADD_STRING:
return "ZEND_ADD_STRING";
case ZEND_ADD_VAR:
return "ZEND_ADD_VAR";
case ZEND_BEGIN_SILENCE:
return "ZEND_BEGIN_SILENCE";
case ZEND_END_SILENCE:
return "ZEND_END_SILENCE";
case ZEND_INIT_FCALL_BY_NAME:
return "ZEND_INIT_FCALL_BY_NAME";
case ZEND_DO_FCALL:
return "ZEND_DO_FCALL";
case ZEND_DO_FCALL_BY_NAME:
return "ZEND_DO_FCALL_BY_NAME";
case ZEND_RETURN:
return "ZEND_RETURN";
case ZEND_RECV:
return "ZEND_RECV";
case ZEND_RECV_INIT:
return "ZEND_RECV_INIT";
case ZEND_SEND_VAL:
return "ZEND_SEND_VAL";
case ZEND_SEND_VAR:
return "ZEND_SEND_VAR";
case ZEND_SEND_REF:
return "ZEND_SEND_REF";
case ZEND_NEW:
return "ZEND_NEW";
case ZEND_INIT_NS_FCALL_BY_NAME:
return "ZEND_INIT_NS_FCALL_BY_NAME";
case ZEND_FREE:
return "ZEND_FREE";
case ZEND_INIT_ARRAY:
return "ZEND_INIT_ARRAY";
case ZEND_ADD_ARRAY_ELEMENT:
return "ZEND_ADD_ARRAY_ELEMENT";
case ZEND_INCLUDE_OR_EVAL:
return "ZEND_INCLUDE_OR_EVAL";
case ZEND_UNSET_VAR:
return "ZEND_UNSET_VAR";
case ZEND_UNSET_DIM:
return "ZEND_UNSET_DIM";
case ZEND_UNSET_OBJ:
return "ZEND_UNSET_OBJ";
case ZEND_FE_RESET:
return "ZEND_FE_RESET";
case ZEND_FE_FETCH:
return "ZEND_FE_FETCH";
case ZEND_EXIT:
return "ZEND_EXIT";
case ZEND_FETCH_R:
return "ZEND_FETCH_R";
case ZEND_FETCH_DIM_R:
return "ZEND_FETCH_DIM_R";
case ZEND_FETCH_OBJ_R:
return "ZEND_FETCH_OBJ_R";
case ZEND_FETCH_W:
return "ZEND_FETCH_W";
case ZEND_FETCH_DIM_W:
return "ZEND_FETCH_DIM_W";
case ZEND_FETCH_OBJ_W:
return "ZEND_FETCH_OBJ_W";
case ZEND_FETCH_RW:
return "ZEND_FETCH_RW";
case ZEND_FETCH_DIM_RW:
return "ZEND_FETCH_DIM_RW";
case ZEND_FETCH_OBJ_RW:
return "ZEND_FETCH_OBJ_RW";
case ZEND_FETCH_IS:
return "ZEND_FETCH_IS";
case ZEND_FETCH_DIM_IS:
return "ZEND_FETCH_DIM_IS";
case ZEND_FETCH_OBJ_IS:
return "ZEND_FETCH_OBJ_IS";
case ZEND_FETCH_FUNC_ARG:
return "ZEND_FETCH_FUNC_ARG";
case ZEND_FETCH_DIM_FUNC_ARG:
return "ZEND_FETCH_DIM_FUNC_ARG";
case ZEND_FETCH_OBJ_FUNC_ARG:
return "ZEND_FETCH_OBJ_FUNC_ARG";
case ZEND_FETCH_UNSET:
return "ZEND_FETCH_UNSET";
case ZEND_FETCH_DIM_UNSET:
return "ZEND_FETCH_DIM_UNSET";
case ZEND_FETCH_OBJ_UNSET:
return "ZEND_FETCH_OBJ_UNSET";
case ZEND_FETCH_DIM_TMP_VAR:
return "ZEND_FETCH_DIM_TMP_VAR";
case ZEND_FETCH_CONSTANT:
return "ZEND_FETCH_CONSTANT";
case ZEND_GOTO:
return "ZEND_GOTO";
case ZEND_EXT_STMT:
return "ZEND_EXT_STMT";
case ZEND_EXT_FCALL_BEGIN:
return "ZEND_EXT_FCALL_BEGIN";
case ZEND_EXT_FCALL_END:
return "ZEND_EXT_FCALL_END";
case ZEND_EXT_NOP:
return "ZEND_EXT_NOP";
case ZEND_TICKS:
return "ZEND_TICKS";
case ZEND_SEND_VAR_NO_REF:
return "ZEND_SEND_VAR_NO_REF";
case ZEND_CATCH:
return "ZEND_CATCH";
case ZEND_THROW:
return "ZEND_THROW";
case ZEND_FETCH_CLASS:
return "ZEND_FETCH_CLASS";
case ZEND_CLONE:
return "ZEND_CLONE";
case ZEND_RETURN_BY_REF:
return "ZEND_RETURN_BY_REF";
case ZEND_INIT_METHOD_CALL:
return "ZEND_INIT_METHOD_CALL";
case ZEND_INIT_STATIC_METHOD_CALL:
return "ZEND_INIT_STATIC_METHOD_CALL";
case ZEND_ISSET_ISEMPTY_VAR:
return "ZEND_ISSET_ISEMPTY_VAR";
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
return "ZEND_ISSET_ISEMPTY_DIM_OBJ";
case ZEND_PRE_INC_OBJ:
return "ZEND_PRE_INC_OBJ";
case ZEND_PRE_DEC_OBJ:
return "ZEND_PRE_DEC_OBJ";
case ZEND_POST_INC_OBJ:
return "ZEND_POST_INC_OBJ";
case ZEND_POST_DEC_OBJ:
return "ZEND_POST_DEC_OBJ";
case ZEND_ASSIGN_OBJ:
return "ZEND_ASSIGN_OBJ";
case ZEND_INSTANCEOF:
return "ZEND_INSTANCEOF";
case ZEND_DECLARE_CLASS:
return "ZEND_DECLARE_CLASS";
case ZEND_DECLARE_INHERITED_CLASS:
return "ZEND_DECLARE_INHERITED_CLASS";
case ZEND_DECLARE_FUNCTION:
return "ZEND_DECLARE_FUNCTION";
case ZEND_RAISE_ABSTRACT_ERROR:
return "ZEND_RAISE_ABSTRACT_ERROR";
case ZEND_DECLARE_CONST:
return "ZEND_DECLARE_CONST";
case ZEND_ADD_INTERFACE:
return "ZEND_ADD_INTERFACE";
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
return "ZEND_DECLARE_INHERITED_CLASS_DELAYED";
case ZEND_VERIFY_ABSTRACT_CLASS:
return "ZEND_VERIFY_ABSTRACT_CLASS";
case ZEND_ASSIGN_DIM:
return "ZEND_ASSIGN_DIM";
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
return "ZEND_ISSET_ISEMPTY_PROP_OBJ";
case ZEND_HANDLE_EXCEPTION:
return "ZEND_HANDLE_EXCEPTION";
case ZEND_USER_OPCODE:
return "ZEND_USER_OPCODE";
case ZEND_JMP_SET:
return "ZEND_JMP_SET";
case ZEND_DECLARE_LAMBDA_FUNCTION:
return "ZEND_DECLARE_LAMBDA_FUNCTION";
case ZEND_ADD_TRAIT:
return "ZEND_ADD_TRAIT";
case ZEND_BIND_TRAITS:
return "ZEND_BIND_TRAITS";
case ZEND_SEPARATE:
return "ZEND_SEPARATE";
case ZEND_QM_ASSIGN_VAR:
return "ZEND_QM_ASSIGN_VAR";
case ZEND_JMP_SET_VAR:
return "ZEND_JMP_SET_VAR";
case ZEND_DISCARD_EXCEPTION:
return "ZEND_DISCARD_EXCEPTION";
case ZEND_YIELD:
return "ZEND_YIELD";
case ZEND_GENERATOR_RETURN:
return "ZEND_GENERATOR_RETURN";
case ZEND_FAST_CALL:
return "ZEND_FAST_CALL";
case ZEND_FAST_RET:
return "ZEND_FAST_RET";
case ZEND_RECV_VARIADIC:
return "ZEND_RECV_VARIADIC";
case ZEND_SEND_UNPACK:
return "ZEND_SEND_UNPACK";
case ZEND_POW:
return "ZEND_POW";
case ZEND_ASSIGN_POW:
return "ZEND_ASSIGN_POW";
default:
return "unknow";
}
}
char *format_zval(zval *z)
{
static char buffer[10000];
int len;
switch(z->type) {
case IS_NULL:
return "NULL";
case IS_LONG:
case IS_BOOL:
snprintf(buffer, 10000, "%d", z->value.lval);
return buffer;
case IS_DOUBLE:
snprintf(buffer, 10000, "%f", z->value.dval);
return buffer;
case IS_STRING:
snprintf(buffer, 10000, "\"%s\"", z->value.str.val);
return buffer;
case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
case IS_CONSTANT:
// case IS_CONSTANT_ARRAY:
return "";
default:
return "unknown";
}
// efree(buffer);
}
char * format_znode(znode_op *n, zend_uint type)
{
static char buffer[10000];
switch (type &~ EXT_TYPE_UNUSED) {
case IS_CONST:
return format_zval(n->zv);
break;
case IS_VAR:
snprintf(buffer, 10000, "$%d", n->var /sizeof(temp_variable));
return buffer;
break;
case IS_TMP_VAR:
snprintf(buffer, 10000, "~%d", n->var /sizeof(temp_variable));
return buffer;
break;
default:
return "";
break;
}
// efree(buffer);
}
void dump_op(zend_op *op, int num)
{
printf("%5d %5d %30s %40s %40s %40s\n", num, op->lineno,
opname(op->opcode),
format_znode(&op->op1 , op->op1_type),
format_znode(&op->op2, op->op2_type),
"sss") ;
}
void dump_op_array(zend_op_array *op_array)
{
if(op_array) {
int i;
printf("%5s %5s %30s %40s %40s %40s\n", "opnum", "line", "opcode", "op1", "op2", "result");
for(i = 0; i < op_array->last; i++) {
dump_op(&op_array->opcodes[i], i);
}
}
}
int main(int argc, char **argv)
{
zend_op_array *op_array;
zend_file_handle file_handle;
if(argc != 2) {
printf("usage: op_dumper <script>\n");
return 1;
}
PHP_EMBED_START_BLOCK(argc,argv);
printf("Script: %s\n", argv[1]);
file_handle.filename = argv[1];
file_handle.free_filename = 0;
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.opened_path = NULL;
op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC);
if(!op_array) {
printf("Error parsing script: %s\n", file_handle.filename);
return 1;
}
dump_op_array(op_array);
destroy_op_array(op_array TSRMLS_CC);
efree(op_array);
zend_destroy_file_handle(&file_handle TSRMLS_CC);
PHP_EMBED_END_BLOCK();
return 0;
}