1 /* 2 +----------------------------------------------------------------------+ 3 | PHP Version 7 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2018 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Felipe Pena <felipe@php.net> | 16 | Authors: Joe Watkins <joe.watkins@live.co.uk> | 17 | Authors: Bob Weinand <bwoebi@php.net> | 18 +----------------------------------------------------------------------+ 19 */ 20 21 #ifndef PHPDBG_CMD_H 22 #define PHPDBG_CMD_H 23 24 #include "TSRM.h" 25 #include "zend_generators.h" 26 27 /* {{{ Command and Parameter */ 28 enum { 29 NO_ARG = 0, 30 REQUIRED_ARG, 31 OPTIONAL_ARG 32 }; 33 34 typedef enum { 35 EMPTY_PARAM = 0, 36 ADDR_PARAM, 37 FILE_PARAM, 38 NUMERIC_FILE_PARAM, 39 METHOD_PARAM, 40 STR_PARAM, 41 NUMERIC_PARAM, 42 NUMERIC_FUNCTION_PARAM, 43 NUMERIC_METHOD_PARAM, 44 STACK_PARAM, 45 EVAL_PARAM, 46 SHELL_PARAM, 47 COND_PARAM, 48 OP_PARAM, 49 ORIG_PARAM, 50 RUN_PARAM 51 } phpdbg_param_type; 52 53 typedef struct _phpdbg_param phpdbg_param_t; 54 struct _phpdbg_param { 55 phpdbg_param_type type; 56 long num; 57 zend_ulong addr; 58 struct { 59 char *name; 60 long line; 61 } file; 62 struct { 63 char *class; 64 char *name; 65 } method; 66 char *str; 67 size_t len; 68 phpdbg_param_t *next; 69 phpdbg_param_t *top; 70 }; 71 72 #define phpdbg_init_param(v, t) do{ \ 73 (v)->type = (t); \ 74 (v)->addr = 0; \ 75 (v)->num = 0; \ 76 (v)->file.name = NULL; \ 77 (v)->file.line = 0; \ 78 (v)->method.class = NULL; \ 79 (v)->method.name = NULL; \ 80 (v)->str = NULL; \ 81 (v)->len = 0; \ 82 (v)->next = NULL; \ 83 (v)->top = NULL; \ 84 } while(0) 85 86 #ifndef YYSTYPE 87 #define YYSTYPE phpdbg_param_t 88 #endif 89 90 #define PHPDBG_ASYNC_SAFE 1 91 92 typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*); 93 94 typedef struct _phpdbg_command_t phpdbg_command_t; 95 struct _phpdbg_command_t { 96 const char *name; /* Command name */ 97 size_t name_len; /* Command name length */ 98 const char *tip; /* Menu tip */ 99 size_t tip_len; /* Menu tip length */ 100 char alias; /* Alias */ 101 phpdbg_command_handler_t handler; /* Command handler */ 102 const phpdbg_command_t *subs; /* Sub Commands */ 103 char *args; /* Argument Spec */ 104 const phpdbg_command_t *parent; /* Parent Command */ 105 zend_bool flags; /* General flags */ 106 }; 107 /* }}} */ 108 109 /* {{{ misc */ 110 #define PHPDBG_STRL(s) s, sizeof(s)-1 111 #define PHPDBG_MAX_CMD 500 112 #define PHPDBG_FRAME(v) (PHPDBG_G(frame).v) 113 #define PHPDBG_EX(v) (EG(current_execute_data)->v) 114 115 typedef struct { 116 int num; 117 zend_generator *generator; 118 zend_execute_data *execute_data; 119 } phpdbg_frame_t; 120 /* }}} */ 121 122 /* 123 * Workflow: 124 * 1) the lexer/parser creates a stack of commands and arguments from input 125 * 2) the commands at the top of the stack are resolved sensibly using aliases, abbreviations and case insensitive matching 126 * 3) the remaining arguments in the stack are verified (optionally) against the handlers declared argument specification 127 * 4) the handler is called passing the top of the stack as the only parameter 128 * 5) the stack is destroyed upon return from the handler 129 */ 130 131 /* 132 * Input Management 133 */ 134 PHPDBG_API char* phpdbg_read_input(char *buffered); 135 PHPDBG_API void phpdbg_destroy_input(char**); 136 PHPDBG_API int phpdbg_ask_user_permission(const char *question); 137 138 /** 139 * Stack Management 140 */ 141 PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); 142 PHPDBG_API void phpdbg_stack_separate(phpdbg_param_t *param); 143 PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top); 144 PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack); 145 PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async_unsafe); 146 PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); 147 148 /* 149 * Parameter Management 150 */ 151 PHPDBG_API void phpdbg_clear_param(phpdbg_param_t*); 152 PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t*, phpdbg_param_t*); 153 PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *, const phpdbg_param_t *); 154 PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *); 155 PHPDBG_API const char* phpdbg_get_param_type(const phpdbg_param_t*); 156 PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer); 157 PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg); 158 159 /** 160 * Command Declarators 161 */ 162 #define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name 163 164 #define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent, flags) \ 165 {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent, flags} 166 167 #define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args, flags) \ 168 {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL, flags} 169 170 #define PHPDBG_COMMAND_D(name, tip, alias, children, args, flags) \ 171 {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL, flags} 172 173 #define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param) 174 175 #define PHPDBG_COMMAND_ARGS param 176 177 #define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, NULL, NULL, 0} 178 179 /* 180 * Default Switch Case 181 */ 182 #define phpdbg_default_switch_case() \ 183 default: \ 184 phpdbg_error("command", "type=\"wrongarg\" got=\"%s\"", "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param)); \ 185 break 186 187 #endif /* PHPDBG_CMD_H */ 188