1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2017 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_WATCH_H
22 #define PHPDBG_WATCH_H
23
24 #include "phpdbg_cmd.h"
25
26 #ifdef _WIN32
27 # include "phpdbg_win.h"
28 #endif
29
30 #define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name)
31
32 /**
33 * Printer Forward Declarations
34 */
35 PHPDBG_WATCH(array);
36 PHPDBG_WATCH(delete);
37 PHPDBG_WATCH(recursive);
38
39 extern const phpdbg_command_t phpdbg_watch_commands[];
40
41 /* Watchpoint functions/typedefs */
42
43 /* References are managed through their parent zval *, being a simple WATCH_ON_ZVAL and eventually WATCH_ON_REFCOUNTED */
44 typedef enum {
45 WATCH_ON_ZVAL,
46 WATCH_ON_HASHTABLE,
47 WATCH_ON_REFCOUNTED,
48 } phpdbg_watchtype;
49
50
51 #define PHPDBG_WATCH_SIMPLE 0x01
52 #define PHPDBG_WATCH_RECURSIVE 0x02
53 #define PHPDBG_WATCH_ARRAY 0x04
54 #define PHPDBG_WATCH_OBJECT 0x08
55 #define PHPDBG_WATCH_NORMAL (PHPDBG_WATCH_SIMPLE | PHPDBG_WATCH_RECURSIVE)
56 #define PHPDBG_WATCH_IMPLICIT 0x10
57
58 #define PHPDBG_DESTRUCTED_ZVAL 0x80
59
60 typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t;
61
62 struct _phpdbg_watchpoint_t {
63 union {
64 zval *zv;
65 zend_refcounted *ref;
66 void *ptr;
67 } addr;
68 size_t size;
69 phpdbg_watchtype type;
70 char flags;
71 unsigned int implicit_ht_count;
72 phpdbg_watchpoint_t *parent;
73 phpdbg_watchpoint_t *reference;
74 HashTable *parent_container;
75 zend_string *name_in_parent;
76 zend_string *str;
77 };
78
79 typedef struct {
80 phpdbg_watchpoint_t *watch;
81 unsigned int refs;
82 HashTable watches;
83 HashTable implicit_watches;
84 } phpdbg_watch_collision;
85
86 typedef struct {
87 dtor_func_t dtor;
88 HashTable watches;
89 } phpdbg_watch_ht_info;
90
91 void phpdbg_setup_watchpoints(void);
92
93 #ifndef _WIN32
94 int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context);
95 #else
96 int phpdbg_watchpoint_segfault_handler(void *addr);
97 #endif
98
99 void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch);
100 void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch);
101
102 int phpdbg_delete_var_watchpoint(char *input, size_t len);
103 int phpdbg_create_var_watchpoint(char *input, size_t len);
104
105 int phpdbg_print_changed_zvals(void);
106
107 void phpdbg_list_watchpoints(void);
108
109 void phpdbg_watch_efree(void *ptr);
110
111
112 static long phpdbg_pagesize;
113
phpdbg_get_page_boundary(void * addr)114 static zend_always_inline void *phpdbg_get_page_boundary(void *addr) {
115 return (void *) ((size_t) addr & ~(phpdbg_pagesize - 1));
116 }
117
phpdbg_get_total_page_size(void * addr,size_t size)118 static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
119 return (size_t) phpdbg_get_page_boundary((void *) ((size_t) addr + size - 1)) - (size_t) phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
120 }
121
122 #endif
123