xref: /PHP-8.4/main/debug_gdb_scripts.c (revision 31e2ec63)
1 /*
2  * Generated by debug_gdb_scripts_gen.php.
3  *
4  * This inlines .gdbinit and php_gdb.py into the .debug_gdb_scripts
5  * section of the binary, so that they can be found by gdb.
6  *
7  * See https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html#dotdebug_005fgdb_005fscripts-section
8  */
9 asm(
10     ".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n"
11     ".byte 4 /* Python Text */\n"
12     ".ascii \"gdb.inlined-script\\n\"\n"
13     ".ascii \"gdb.execute('''\\n\"\n"
14     ".ascii \"define set_ts\\n\"\n"
15     ".ascii \"	set $tsrm_ls = $arg0\\n\"\n"
16     ".ascii \"end\\n\"\n"
17     ".ascii \"\\n\"\n"
18     ".ascii \"document set_ts\\n\"\n"
19     ".ascii \"	set the ts resource, it is impossible for gdb to\\n\"\n"
20     ".ascii \"	call ts_resource_ex while no process is running,\\n\"\n"
21     ".ascii \"	but we could get the resource from the argument\\n\"\n"
22     ".ascii \"	of frame info.\\n\"\n"
23     ".ascii \"end\\n\"\n"
24     ".ascii \"\\n\"\n"
25     ".ascii \"define ____executor_globals\\n\"\n"
26     ".ascii \"	if basic_functions_module.zts\\n\"\n"
27     ".ascii \"		set $tsrm_ls = _tsrm_ls_cache\\n\"\n"
28     ".ascii \"		set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1])\\n\"\n"
29     ".ascii \"		set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1])\\n\"\n"
30     ".ascii \"		set $eg_ptr = $eg\\n\"\n"
31     ".ascii \"	else\\n\"\n"
32     ".ascii \"		set $eg = executor_globals\\n\"\n"
33     ".ascii \"		set $cg = compiler_globals\\n\"\n"
34     ".ascii \"		set $eg_ptr = (zend_executor_globals*) &executor_globals\\n\"\n"
35     ".ascii \"	end\\n\"\n"
36     ".ascii \"end\\n\"\n"
37     ".ascii \"\\n\"\n"
38     ".ascii \"document ____executor_globals\\n\"\n"
39     ".ascii \"	portable way of accessing executor_globals, set $eg\\n\"\n"
40     ".ascii \"	this also sets compiler_globals to $cg\\n\"\n"
41     ".ascii \"	ZTS detection is automatically based on ext/standard module struct\\n\"\n"
42     ".ascii \"end\\n\"\n"
43     ".ascii \"\\n\"\n"
44     ".ascii \"define print_cvs\\n\"\n"
45     ".ascii \"	if $argc == 0\\n\"\n"
46     ".ascii \"		____executor_globals\\n\"\n"
47     ".ascii \"		set $cv_ex_ptr = $eg.current_execute_data\\n\"\n"
48     ".ascii \"	else\\n\"\n"
49     ".ascii \"		set $cv_ex_ptr = (zend_execute_data *)$arg0\\n\"\n"
50     ".ascii \"	end\\n\"\n"
51     ".ascii \"	set $cv_count = $cv_ex_ptr.func.op_array.last_var\\n\"\n"
52     ".ascii \"	set $cv = $cv_ex_ptr.func.op_array.vars\\n\"\n"
53     ".ascii \"	set $cv_idx = 0\\n\"\n"
54     ".ascii \"	set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)\\n\"\n"
55     ".ascii \"\\n\"\n"
56     ".ascii \"	printf \\\"Compiled variables count: %d\\\\\\\\n\\\\\\\\n\\\", $cv_count\\n\"\n"
57     ".ascii \"	while $cv_idx < $cv_count\\n\"\n"
58     ".ascii \"		printf \\\"[%d] \\\\'%s\\\\'\\\\\\\\n\\\", $cv_idx, $cv[$cv_idx].val\\n\"\n"
59     ".ascii \"		set $zvalue = ((zval *) $cv_ex_ptr) + $callFrameSize + $cv_idx\\n\"\n"
60     ".ascii \"		printzv $zvalue\\n\"\n"
61     ".ascii \"		set $cv_idx = $cv_idx + 1\\n\"\n"
62     ".ascii \"	end\\n\"\n"
63     ".ascii \"end\\n\"\n"
64     ".ascii \"\\n\"\n"
65     ".ascii \"document print_cvs\\n\"\n"
66     ".ascii \"	Prints the compiled variables and their values.\\n\"\n"
67     ".ascii \"	If a zend_execute_data pointer is set this will print the compiled\\n\"\n"
68     ".ascii \"	variables of that scope. If no parameter is used it will use\\n\"\n"
69     ".ascii \"	current_execute_data for scope.\\n\"\n"
70     ".ascii \"\\n\"\n"
71     ".ascii \"	usage: print_cvs [zend_execute_data *]\\n\"\n"
72     ".ascii \"end\\n\"\n"
73     ".ascii \"\\n\"\n"
74     ".ascii \"define dump_bt\\n\"\n"
75     ".ascii \"	set $ex = $arg0\\n\"\n"
76     ".ascii \"	while $ex\\n\"\n"
77     ".ascii \"		printf \\\"[%p] \\\", $ex\\n\"\n"
78     ".ascii \"		set $func = $ex->func\\n\"\n"
79     ".ascii \"		if $func\\n\"\n"
80     ".ascii \"			if $ex->This->value.obj\\n\"\n"
81     ".ascii \"				if $func->common.scope\\n\"\n"
82     ".ascii \"					printf \\\"%s->\\\", (char*)$func->common.scope->name->val\\n\"\n"
83     ".ascii \"				else\\n\"\n"
84     ".ascii \"					printf \\\"%s->\\\", (char*)$ex->This->value.obj->ce.name->val\\n\"\n"
85     ".ascii \"				end\\n\"\n"
86     ".ascii \"			else\\n\"\n"
87     ".ascii \"				if $func->common.scope\\n\"\n"
88     ".ascii \"					printf \\\"%s::\\\", (char*)$func->common.scope->name->val\\n\"\n"
89     ".ascii \"				end\\n\"\n"
90     ".ascii \"			end\\n\"\n"
91     ".ascii \"\\n\"\n"
92     ".ascii \"			if $func->common.function_name\\n\"\n"
93     ".ascii \"				printf \\\"%s(\\\", (char*)$func->common.function_name->val\\n\"\n"
94     ".ascii \"			else\\n\"\n"
95     ".ascii \"				printf \\\"(main\\\"\\n\"\n"
96     ".ascii \"			end\\n\"\n"
97     ".ascii \"\\n\"\n"
98     ".ascii \"			set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval)\\n\"\n"
99     ".ascii \"\\n\"\n"
100     ".ascii \"			set $count = $ex->This.u2.num_args\\n\"\n"
101     ".ascii \"			set $arg = 0\\n\"\n"
102     ".ascii \"			while $arg < $count\\n\"\n"
103     ".ascii \"				if $arg > 0\\n\"\n"
104     ".ascii \"					printf \\\", \\\"\\n\"\n"
105     ".ascii \"				end\\n\"\n"
106     ".ascii \"\\n\"\n"
107     ".ascii \"				set $zvalue = (zval *) $ex + $callFrameSize + $arg\\n\"\n"
108     ".ascii \"				set $type = $zvalue->u1.v.type\\n\"\n"
109     ".ascii \"				if $type == 1\\n\"\n"
110     ".ascii \"					printf \\\"NULL\\\"\\n\"\n"
111     ".ascii \"				end\\n\"\n"
112     ".ascii \"				if $type == 2\\n\"\n"
113     ".ascii \"					printf \\\"false\\\"\\n\"\n"
114     ".ascii \"				end\\n\"\n"
115     ".ascii \"				if $type == 3\\n\"\n"
116     ".ascii \"					printf \\\"true\\\"\\n\"\n"
117     ".ascii \"				end\\n\"\n"
118     ".ascii \"				if $type == 4\\n\"\n"
119     ".ascii \"					printf \\\"%ld\\\", $zvalue->value.lval\\n\"\n"
120     ".ascii \"				end\\n\"\n"
121     ".ascii \"				if $type == 5\\n\"\n"
122     ".ascii \"					printf \\\"%f\\\", $zvalue->value.dval\\n\"\n"
123     ".ascii \"				end\\n\"\n"
124     ".ascii \"				if $type == 6\\n\"\n"
125     ".ascii \"					____print_str (char*)$zvalue->value.str->val $zvalue->value.str->len\\n\"\n"
126     ".ascii \"				end\\n\"\n"
127     ".ascii \"				if $type == 7\\n\"\n"
128     ".ascii \"					printf \\\"array(%d)[%p]\\\", $zvalue->value.arr->nNumOfElements, $zvalue\\n\"\n"
129     ".ascii \"				end\\n\"\n"
130     ".ascii \"				if $type == 8\\n\"\n"
131     ".ascii \"					printf \\\"object[%p]\\\", $zvalue\\n\"\n"
132     ".ascii \"				end\\n\"\n"
133     ".ascii \"				if $type == 9\\n\"\n"
134     ".ascii \"					printf \\\"resource(#%d)\\\", $zvalue->value.lval\\n\"\n"
135     ".ascii \"				end\\n\"\n"
136     ".ascii \"				if $type == 10\\n\"\n"
137     ".ascii \"					printf \\\"reference\\\"\\n\"\n"
138     ".ascii \"				end\\n\"\n"
139     ".ascii \"				if $type > 10\\n\"\n"
140     ".ascii \"					printf \\\"unknown type %d\\\", $type\\n\"\n"
141     ".ascii \"				end\\n\"\n"
142     ".ascii \"				set $arg = $arg + 1\\n\"\n"
143     ".ascii \"			end\\n\"\n"
144     ".ascii \"\\n\"\n"
145     ".ascii \"			printf \\\") \\\"\\n\"\n"
146     ".ascii \"		else\\n\"\n"
147     ".ascii \"			printf \\\"??? \\\"\\n\"\n"
148     ".ascii \"		end\\n\"\n"
149     ".ascii \"		if $func != 0\\n\"\n"
150     ".ascii \"			if $func->type == 2\\n\"\n"
151     ".ascii \"				printf \\\"%s:%d \\\", (char*)$func->op_array.filename->val, $ex->opline->lineno\\n\"\n"
152     ".ascii \"			else\\n\"\n"
153     ".ascii \"				printf \\\"[internal function]\\\"\\n\"\n"
154     ".ascii \"			end\\n\"\n"
155     ".ascii \"		end\\n\"\n"
156     ".ascii \"		set $ex = $ex->prev_execute_data\\n\"\n"
157     ".ascii \"		printf \\\"\\\\\\\\n\\\"\\n\"\n"
158     ".ascii \"	end\\n\"\n"
159     ".ascii \"end\\n\"\n"
160     ".ascii \"\\n\"\n"
161     ".ascii \"document dump_bt\\n\"\n"
162     ".ascii \"	dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data\\n\"\n"
163     ".ascii \"end\\n\"\n"
164     ".ascii \"\\n\"\n"
165     ".ascii \"define printzv\\n\"\n"
166     ".ascii \"	set $ind = 1\\n\"\n"
167     ".ascii \"	____printzv $arg0 0\\n\"\n"
168     ".ascii \"end\\n\"\n"
169     ".ascii \"\\n\"\n"
170     ".ascii \"document printzv\\n\"\n"
171     ".ascii \"	prints zval contents\\n\"\n"
172     ".ascii \"end\\n\"\n"
173     ".ascii \"\\n\"\n"
174     ".ascii \"define ____printzv_contents\\n\"\n"
175     ".ascii \"	set $zvalue = $arg0\\n\"\n"
176     ".ascii \"	set $type = $zvalue->u1.v.type\\n\"\n"
177     ".ascii \"\\n\"\n"
178     ".ascii \"	# 15 == IS_INDIRECT\\n\"\n"
179     ".ascii \"	if $type > 5 && $type < 12\\n\"\n"
180     ".ascii \"		printf \\\"(refcount=%d) \\\", $zvalue->value.counted->gc.refcount\\n\"\n"
181     ".ascii \"	end\\n\"\n"
182     ".ascii \"\\n\"\n"
183     ".ascii \"	if $type == 0\\n\"\n"
184     ".ascii \"		printf \\\"UNDEF\\\"\\n\"\n"
185     ".ascii \"	end\\n\"\n"
186     ".ascii \"	if $type == 1\\n\"\n"
187     ".ascii \"		printf \\\"NULL\\\"\\n\"\n"
188     ".ascii \"	end\\n\"\n"
189     ".ascii \"	if $type == 2\\n\"\n"
190     ".ascii \"		printf \\\"bool: false\\\"\\n\"\n"
191     ".ascii \"	end\\n\"\n"
192     ".ascii \"	if $type == 3\\n\"\n"
193     ".ascii \"		printf \\\"bool: true\\\"\\n\"\n"
194     ".ascii \"	end\\n\"\n"
195     ".ascii \"	if $type == 4\\n\"\n"
196     ".ascii \"		printf \\\"long: %ld\\\", $zvalue->value.lval\\n\"\n"
197     ".ascii \"	end\\n\"\n"
198     ".ascii \"	if $type == 5\\n\"\n"
199     ".ascii \"		printf \\\"double: %f\\\", $zvalue->value.dval\\n\"\n"
200     ".ascii \"	end\\n\"\n"
201     ".ascii \"	if $type == 6\\n\"\n"
202     ".ascii \"		printf \\\"string: %s\\\", (char*)$zvalue->value.str->val\\n\"\n"
203     ".ascii \"	end\\n\"\n"
204     ".ascii \"	if $type == 7\\n\"\n"
205     ".ascii \"		printf \\\"array: \\\"\\n\"\n"
206     ".ascii \"		if ! $arg1\\n\"\n"
207     ".ascii \"			set $ind = $ind + 1\\n\"\n"
208     ".ascii \"			____print_ht $zvalue->value.arr 1\\n\"\n"
209     ".ascii \"			set $ind = $ind - 1\\n\"\n"
210     ".ascii \"			set $i = $ind\\n\"\n"
211     ".ascii \"			while $i > 0\\n\"\n"
212     ".ascii \"				printf \\\"  \\\"\\n\"\n"
213     ".ascii \"				set $i = $i - 1\\n\"\n"
214     ".ascii \"			end\\n\"\n"
215     ".ascii \"		end\\n\"\n"
216     ".ascii \"		set $type = 0\\n\"\n"
217     ".ascii \"	end\\n\"\n"
218     ".ascii \"	if $type == 8\\n\"\n"
219     ".ascii \"		printf \\\"object\\\"\\n\"\n"
220     ".ascii \"		____executor_globals\\n\"\n"
221     ".ascii \"		set $handle = $zvalue->value.obj.handle\\n\"\n"
222     ".ascii \"		set $handlers = $zvalue->value.obj.handlers\\n\"\n"
223     ".ascii \"		set $zobj = $zvalue->value.obj\\n\"\n"
224     ".ascii \"		set $cname = (char*)$zobj->ce->name->val\\n\"\n"
225     ".ascii \"		printf \\\"(%s) #%d\\\", $cname, $handle\\n\"\n"
226     ".ascii \"		if ! $arg1\\n\"\n"
227     ".ascii \"			if $handlers->get_properties == &zend_std_get_properties\\n\"\n"
228     ".ascii \"				if $zobj->properties\\n\"\n"
229     ".ascii \"					printf \\\"\\\\\\\\nProperties \\\"\\n\"\n"
230     ".ascii \"					set $ht = $zobj->properties\\n\"\n"
231     ".ascii \"					set $ind = $ind + 1\\n\"\n"
232     ".ascii \"					____print_ht $ht 1\\n\"\n"
233     ".ascii \"					set $ind = $ind - 1\\n\"\n"
234     ".ascii \"					set $i = $ind\\n\"\n"
235     ".ascii \"					while $i > 0\\n\"\n"
236     ".ascii \"						printf \\\"  \\\"\\n\"\n"
237     ".ascii \"						set $i = $i - 1\\n\"\n"
238     ".ascii \"					end\\n\"\n"
239     ".ascii \"				else\\n\"\n"
240     ".ascii \"					printf \\\" {\\\\\\\\n\\\"\\n\"\n"
241     ".ascii \"					set $ht = &$zobj->ce->properties_info\\n\"\n"
242     ".ascii \"					set $k = 0\\n\"\n"
243     ".ascii \"					set $num = $ht->nNumUsed\\n\"\n"
244     ".ascii \"					while $k < $num\\n\"\n"
245     ".ascii \"						set $p = (Bucket*)($ht->arData + $k)\\n\"\n"
246     ".ascii \"						set $name = $p->key\\n\"\n"
247     ".ascii \"						set $prop = (zend_property_info*)$p->val.value.ptr\\n\"\n"
248     ".ascii \"						set $val = (zval*)((char*)$zobj + $prop->offset)\\n\"\n"
249     ".ascii \"						printf \\\"%s => \\\", (char*)$name->val\\n\"\n"
250     ".ascii \"						printzv $val\\n\"\n"
251     ".ascii \"						set $k = $k + 1\\n\"\n"
252     ".ascii \"					end\\n\"\n"
253     ".ascii \"				end\\n\"\n"
254     ".ascii \"			end\\n\"\n"
255     ".ascii \"		end\\n\"\n"
256     ".ascii \"		set $type = 0\\n\"\n"
257     ".ascii \"	end\\n\"\n"
258     ".ascii \"	if $type == 9\\n\"\n"
259     ".ascii \"		printf \\\"resource: #%d\\\", $zvalue->value.res->handle\\n\"\n"
260     ".ascii \"	end\\n\"\n"
261     ".ascii \"	if $type == 10\\n\"\n"
262     ".ascii \"		printf \\\"reference: \\\"\\n\"\n"
263     ".ascii \"		____printzv &$zvalue->value.ref->val $arg1\\n\"\n"
264     ".ascii \"	end\\n\"\n"
265     ".ascii \"	if $type == 11\\n\"\n"
266     ".ascii \"		printf \\\"CONSTANT_AST\\\"\\n\"\n"
267     ".ascii \"	end\\n\"\n"
268     ".ascii \"	if $type == 12\\n\"\n"
269     ".ascii \"		printf \\\"indirect: \\\"\\n\"\n"
270     ".ascii \"		____printzv $zvalue->value.zv $arg1\\n\"\n"
271     ".ascii \"	end\\n\"\n"
272     ".ascii \"	if $type == 13\\n\"\n"
273     ".ascii \"		printf \\\"pointer: %p\\\", $zvalue->value.ptr\\n\"\n"
274     ".ascii \"	end\\n\"\n"
275     ".ascii \"	if $type == 15\\n\"\n"
276     ".ascii \"		printf \\\"_ERROR\\\"\\n\"\n"
277     ".ascii \"	end\\n\"\n"
278     ".ascii \"	if $type == 16\\n\"\n"
279     ".ascii \"		printf \\\"_BOOL\\\"\\n\"\n"
280     ".ascii \"	end\\n\"\n"
281     ".ascii \"	if $type == 17\\n\"\n"
282     ".ascii \"		printf \\\"_NUMBER\\\"\\n\"\n"
283     ".ascii \"	end\\n\"\n"
284     ".ascii \"	if $type > 17\\n\"\n"
285     ".ascii \"		printf \\\"unknown type %d\\\", $type\\n\"\n"
286     ".ascii \"	end\\n\"\n"
287     ".ascii \"	printf \\\"\\\\\\\\n\\\"\\n\"\n"
288     ".ascii \"end\\n\"\n"
289     ".ascii \"\\n\"\n"
290     ".ascii \"define ____printzv\\n\"\n"
291     ".ascii \"	____executor_globals\\n\"\n"
292     ".ascii \"	set $zvalue = $arg0\\n\"\n"
293     ".ascii \"\\n\"\n"
294     ".ascii \"	printf \\\"[%p] \\\", $zvalue\\n\"\n"
295     ".ascii \"\\n\"\n"
296     ".ascii \"	set $zcontents = (zval*) $zvalue\\n\"\n"
297     ".ascii \"	if $arg1\\n\"\n"
298     ".ascii \"		____printzv_contents $zcontents $arg1\\n\"\n"
299     ".ascii \"	else\\n\"\n"
300     ".ascii \"		____printzv_contents $zcontents 0\\n\"\n"
301     ".ascii \"	end\\n\"\n"
302     ".ascii \"end\\n\"\n"
303     ".ascii \"\\n\"\n"
304     ".ascii \"define print_global_vars\\n\"\n"
305     ".ascii \"	____executor_globals\\n\"\n"
306     ".ascii \"	set $symtable = ((HashTable *)&($eg_ptr->symbol_table))\\n\"\n"
307     ".ascii \"	print_ht $symtable\\n\"\n"
308     ".ascii \"end\\n\"\n"
309     ".ascii \"\\n\"\n"
310     ".ascii \"document print_global_vars\\n\"\n"
311     ".ascii \"	Prints the global variables\\n\"\n"
312     ".ascii \"end\\n\"\n"
313     ".ascii \"\\n\"\n"
314     ".ascii \"define print_const_table\\n\"\n"
315     ".ascii \"	set $ind = 1\\n\"\n"
316     ".ascii \"	printf \\\"[%p] {\\\\\\\\n\\\", $arg0\\n\"\n"
317     ".ascii \"	____print_ht $arg0 4\\n\"\n"
318     ".ascii \"	printf \\\"}\\\\\\\\n\\\"\\n\"\n"
319     ".ascii \"end\\n\"\n"
320     ".ascii \"\\n\"\n"
321     ".ascii \"document print_const_table\\n\"\n"
322     ".ascii \"	Dumps elements of Constants HashTable\\n\"\n"
323     ".ascii \"	Example: print_const_table executor_globals.zend_constants\\n\"\n"
324     ".ascii \"end\\n\"\n"
325     ".ascii \"\\n\"\n"
326     ".ascii \"define ____print_ht\\n\"\n"
327     ".ascii \"	set $ht = (HashTable*)$arg0\\n\"\n"
328     ".ascii \"	set $n = $ind\\n\"\n"
329     ".ascii \"	while $n > 0\\n\"\n"
330     ".ascii \"		printf \\\"  \\\"\\n\"\n"
331     ".ascii \"		set $n = $n - 1\\n\"\n"
332     ".ascii \"	end\\n\"\n"
333     ".ascii \"\\n\"\n"
334     ".ascii \"	set $packed = $ht->u.v.flags & 4\\n\"\n"
335     ".ascii \"	if $packed\\n\"\n"
336     ".ascii \"		printf \\\"Packed\\\"\\n\"\n"
337     ".ascii \"	else\\n\"\n"
338     ".ascii \"		printf \\\"Hash\\\"\\n\"\n"
339     ".ascii \"	end\\n\"\n"
340     ".ascii \"	printf \\\"(%d)[%p]: {\\\\\\\\n\\\", $ht->nNumOfElements, $ht\\n\"\n"
341     ".ascii \"\\n\"\n"
342     ".ascii \"	set $num = $ht->nNumUsed\\n\"\n"
343     ".ascii \"	set $i = 0\\n\"\n"
344     ".ascii \"	set $ind = $ind + 1\\n\"\n"
345     ".ascii \"	while $i < $num\\n\"\n"
346     ".ascii \"		if $packed\\n\"\n"
347     ".ascii \"			set $val = (zval*)($ht->arPacked + $i)\\n\"\n"
348     ".ascii \"			set $key = (zend_string*)0\\n\"\n"
349     ".ascii \"			set $h = $i\\n\"\n"
350     ".ascii \"		else\\n\"\n"
351     ".ascii \"			set $bucket = (Bucket*)($ht->arData + $i)\\n\"\n"
352     ".ascii \"			set $val = &$bucket->val\\n\"\n"
353     ".ascii \"			set $key = $bucket->key\\n\"\n"
354     ".ascii \"			set $h = $bucket->h\\n\"\n"
355     ".ascii \"		end\\n\"\n"
356     ".ascii \"		set $n = $ind\\n\"\n"
357     ".ascii \"		if $val->u1.v.type > 0\\n\"\n"
358     ".ascii \"			while $n > 0\\n\"\n"
359     ".ascii \"				printf \\\"  \\\"\\n\"\n"
360     ".ascii \"				set $n = $n - 1\\n\"\n"
361     ".ascii \"			end\\n\"\n"
362     ".ascii \"			printf \\\"[%d] \\\", $i\\n\"\n"
363     ".ascii \"			if $key\\n\"\n"
364     ".ascii \"				____print_str (char*)$key->val $key->len\\n\"\n"
365     ".ascii \"				printf \\\" => \\\"\\n\"\n"
366     ".ascii \"			else\\n\"\n"
367     ".ascii \"				printf \\\"%d => \\\", $h\\n\"\n"
368     ".ascii \"			end\\n\"\n"
369     ".ascii \"			if $arg1 == 0\\n\"\n"
370     ".ascii \"				printf \\\"%p\\\\\\\\n\\\", $val\\n\"\n"
371     ".ascii \"			end\\n\"\n"
372     ".ascii \"			if $arg1 == 1\\n\"\n"
373     ".ascii \"				set $zval = $val\\n\"\n"
374     ".ascii \"				____printzv $zval 1\\n\"\n"
375     ".ascii \"			end\\n\"\n"
376     ".ascii \"			if $arg1 == 2\\n\"\n"
377     ".ascii \"				printf \\\"%s\\\\\\\\n\\\", (char*)$val->value.ptr\\n\"\n"
378     ".ascii \"			end\\n\"\n"
379     ".ascii \"			if $arg1 == 3\\n\"\n"
380     ".ascii \"				set $func = (zend_function*)$val->value.ptr\\n\"\n"
381     ".ascii \"				printf \\\"\\\\\\\\\\\"%s\\\\\\\\\\\"\\\\\\\\n\\\", (char*)$func->common.function_name->val\\n\"\n"
382     ".ascii \"			end\\n\"\n"
383     ".ascii \"			if $arg1 == 4\\n\"\n"
384     ".ascii \"				set $const = (zend_constant *)$val->value.ptr\\n\"\n"
385     ".ascii \"				____printzv $const 1\\n\"\n"
386     ".ascii \"			end\\n\"\n"
387     ".ascii \"		end\\n\"\n"
388     ".ascii \"		set $i = $i + 1\\n\"\n"
389     ".ascii \"	end\\n\"\n"
390     ".ascii \"	set $ind = $ind - 1\\n\"\n"
391     ".ascii \"	printf \\\"}\\\\\\\\n\\\"\\n\"\n"
392     ".ascii \"end\\n\"\n"
393     ".ascii \"\\n\"\n"
394     ".ascii \"define print_ht\\n\"\n"
395     ".ascii \"	set $ind = 0\\n\"\n"
396     ".ascii \"	____print_ht $arg0 1\\n\"\n"
397     ".ascii \"end\\n\"\n"
398     ".ascii \"\\n\"\n"
399     ".ascii \"document print_ht\\n\"\n"
400     ".ascii \"	dumps elements of HashTable made of zval\\n\"\n"
401     ".ascii \"end\\n\"\n"
402     ".ascii \"\\n\"\n"
403     ".ascii \"define print_htptr\\n\"\n"
404     ".ascii \"	set $ind = 0\\n\"\n"
405     ".ascii \"	____print_ht $arg0 0\\n\"\n"
406     ".ascii \"end\\n\"\n"
407     ".ascii \"\\n\"\n"
408     ".ascii \"document print_htptr\\n\"\n"
409     ".ascii \"	dumps elements of HashTable made of pointers\\n\"\n"
410     ".ascii \"end\\n\"\n"
411     ".ascii \"\\n\"\n"
412     ".ascii \"define print_htstr\\n\"\n"
413     ".ascii \"	set $ind = 0\\n\"\n"
414     ".ascii \"	____print_ht $arg0 2\\n\"\n"
415     ".ascii \"end\\n\"\n"
416     ".ascii \"\\n\"\n"
417     ".ascii \"document print_htstr\\n\"\n"
418     ".ascii \"	dumps elements of HashTable made of strings\\n\"\n"
419     ".ascii \"end\\n\"\n"
420     ".ascii \"\\n\"\n"
421     ".ascii \"define print_ft\\n\"\n"
422     ".ascii \"	set $ind = 0\\n\"\n"
423     ".ascii \"	____print_ht $arg0 3\\n\"\n"
424     ".ascii \"end\\n\"\n"
425     ".ascii \"\\n\"\n"
426     ".ascii \"document print_ft\\n\"\n"
427     ".ascii \"	dumps a function table (HashTable)\\n\"\n"
428     ".ascii \"end\\n\"\n"
429     ".ascii \"\\n\"\n"
430     ".ascii \"define ____print_inh_class\\n\"\n"
431     ".ascii \"	set $ce = $arg0\\n\"\n"
432     ".ascii \"	if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20\\n\"\n"
433     ".ascii \"		printf \\\"abstract \\\"\\n\"\n"
434     ".ascii \"	else\\n\"\n"
435     ".ascii \"		if $ce->ce_flags & 0x40\\n\"\n"
436     ".ascii \"			printf \\\"final \\\"\\n\"\n"
437     ".ascii \"		end\\n\"\n"
438     ".ascii \"	end\\n\"\n"
439     ".ascii \"	printf \\\"class %s\\\", (char*)$ce->name->val\\n\"\n"
440     ".ascii \"	if $ce->parent != 0\\n\"\n"
441     ".ascii \"		printf \\\" extends %s\\\", (char*)$ce->parent->name->val\\n\"\n"
442     ".ascii \"	end\\n\"\n"
443     ".ascii \"	if $ce->num_interfaces != 0\\n\"\n"
444     ".ascii \"		printf \\\" implements\\\"\\n\"\n"
445     ".ascii \"		set $tmp = 0\\n\"\n"
446     ".ascii \"		while $tmp < $ce->num_interfaces\\n\"\n"
447     ".ascii \"			printf \\\" %s\\\", (char*)$ce->interfaces[$tmp]->name->val\\n\"\n"
448     ".ascii \"			set $tmp = $tmp + 1\\n\"\n"
449     ".ascii \"			if $tmp < $ce->num_interfaces\\n\"\n"
450     ".ascii \"				printf \\\",\\\"\\n\"\n"
451     ".ascii \"			end\\n\"\n"
452     ".ascii \"		end\\n\"\n"
453     ".ascii \"	end\\n\"\n"
454     ".ascii \"	set $ce = $ce->parent\\n\"\n"
455     ".ascii \"end\\n\"\n"
456     ".ascii \"\\n\"\n"
457     ".ascii \"define ____print_inh_iface\\n\"\n"
458     ".ascii \"	set $ce = $arg0\\n\"\n"
459     ".ascii \"	printf \\\"interface %s\\\", (char*)$ce->name->val\\n\"\n"
460     ".ascii \"	if $ce->num_interfaces != 0\\n\"\n"
461     ".ascii \"		set $ce = $ce->interfaces[0]\\n\"\n"
462     ".ascii \"		printf \\\" extends %s\\\", (char*)$ce->name->val\\n\"\n"
463     ".ascii \"	else\\n\"\n"
464     ".ascii \"		set $ce = 0\\n\"\n"
465     ".ascii \"	end\\n\"\n"
466     ".ascii \"end\\n\"\n"
467     ".ascii \"\\n\"\n"
468     ".ascii \"define print_inh\\n\"\n"
469     ".ascii \"	set $ce = $arg0\\n\"\n"
470     ".ascii \"	set $depth = 0\\n\"\n"
471     ".ascii \"	while $ce != 0\\n\"\n"
472     ".ascii \"		set $tmp = $depth\\n\"\n"
473     ".ascii \"		while $tmp != 0\\n\"\n"
474     ".ascii \"			printf \\\" \\\"\\n\"\n"
475     ".ascii \"			set $tmp = $tmp - 1\\n\"\n"
476     ".ascii \"		end\\n\"\n"
477     ".ascii \"		set $depth = $depth + 1\\n\"\n"
478     ".ascii \"		if $ce->ce_flags & 0x80\\n\"\n"
479     ".ascii \"			____print_inh_iface $ce\\n\"\n"
480     ".ascii \"		else\\n\"\n"
481     ".ascii \"			____print_inh_class $ce\\n\"\n"
482     ".ascii \"		end\\n\"\n"
483     ".ascii \"		printf \\\" {\\\\\\\\n\\\"\\n\"\n"
484     ".ascii \"	end\\n\"\n"
485     ".ascii \"	while $depth != 0\\n\"\n"
486     ".ascii \"		set $tmp = $depth\\n\"\n"
487     ".ascii \"		while $tmp != 1\\n\"\n"
488     ".ascii \"			printf \\\" \\\"\\n\"\n"
489     ".ascii \"			set $tmp = $tmp - 1\\n\"\n"
490     ".ascii \"		end\\n\"\n"
491     ".ascii \"		printf \\\"}\\\\\\\\n\\\"\\n\"\n"
492     ".ascii \"		set $depth = $depth - 1\\n\"\n"
493     ".ascii \"	end\\n\"\n"
494     ".ascii \"end\\n\"\n"
495     ".ascii \"\\n\"\n"
496     ".ascii \"define print_pi\\n\"\n"
497     ".ascii \"	set $pi = (zend_property_info *)$arg0\\n\"\n"
498     ".ascii \"	set $initial_offset = ((uint32_t)(uintptr_t)(&((zend_object*)0)->properties_table[(0)]))\\n\"\n"
499     ".ascii \"	set $ptr_to_val = (zval*)((char*)$pi->ce->default_properties_table + $pi->offset - $initial_offset)\\n\"\n"
500     ".ascii \"	printf \\\"[%p] {\\\\\\\\n\\\", $pi\\n\"\n"
501     ".ascii \"	printf \\\"    offset = %p\\\\\\\\n\\\", $pi->offset\\n\"\n"
502     ".ascii \"	printf \\\"    ce = [%p] %s\\\\\\\\n\\\", $pi->ce, (char*)$pi->ce->name->val\\n\"\n"
503     ".ascii \"	printf \\\"    flags = 0x%x (\\\", $pi->flags\\n\"\n"
504     ".ascii \"	if $pi->flags & 0x100\\n\"\n"
505     ".ascii \"		printf \\\"ZEND_ACC_PUBLIC\\\"\\n\"\n"
506     ".ascii \"	else\\n\"\n"
507     ".ascii \"		if $pi->flags & 0x200\\n\"\n"
508     ".ascii \"			printf \\\"ZEND_ACC_PROTECTED\\\"\\n\"\n"
509     ".ascii \"		else\\n\"\n"
510     ".ascii \"			if $pi->flags & 0x400\\n\"\n"
511     ".ascii \"				printf \\\"ZEND_ACC_PRIVATE\\\"\\n\"\n"
512     ".ascii \"			else\\n\"\n"
513     ".ascii \"				if $pi->flags & 0x800\\n\"\n"
514     ".ascii \"					printf \\\"ZEND_ACC_EARLY_BINDING\\\"\\n\"\n"
515     ".ascii \"				else\\n\"\n"
516     ".ascii \"					if $pi->flags & 0x20000\\n\"\n"
517     ".ascii \"						printf \\\"ZEND_ACC_SHADOW\\\"\\n\"\n"
518     ".ascii \"					end\\n\"\n"
519     ".ascii \"				end\\n\"\n"
520     ".ascii \"			end\\n\"\n"
521     ".ascii \"		end\\n\"\n"
522     ".ascii \"	end\\n\"\n"
523     ".ascii \"	printf \\\")\\\\\\\\n\\\"\\n\"\n"
524     ".ascii \"	printf \\\"    name  = \\\"\\n\"\n"
525     ".ascii \"	print_zstr $pi->name\\n\"\n"
526     ".ascii \"	printf \\\"    default value: \\\"\\n\"\n"
527     ".ascii \"	printzv $ptr_to_val\\n\"\n"
528     ".ascii \"	printf \\\"}\\\\\\\\n\\\"\\n\"\n"
529     ".ascii \"end\\n\"\n"
530     ".ascii \"\\n\"\n"
531     ".ascii \"document print_pi\\n\"\n"
532     ".ascii \"	Takes a pointer to an object\\\\'s property and prints the property information\\n\"\n"
533     ".ascii \"	usage: print_pi <ptr>\\n\"\n"
534     ".ascii \"end\\n\"\n"
535     ".ascii \"\\n\"\n"
536     ".ascii \"define ____print_str\\n\"\n"
537     ".ascii \"	set $tmp = 0\\n\"\n"
538     ".ascii \"	set $str = $arg0\\n\"\n"
539     ".ascii \"	if $argc > 2\\n\"\n"
540     ".ascii \"		set $maxlen = $arg2\\n\"\n"
541     ".ascii \"	else\\n\"\n"
542     ".ascii \"		set $maxlen = 256\\n\"\n"
543     ".ascii \"	end\\n\"\n"
544     ".ascii \"\\n\"\n"
545     ".ascii \"	printf \\\"\\\\\\\\\\\"\\\"\\n\"\n"
546     ".ascii \"	while $tmp < $arg1 && $tmp < $maxlen\\n\"\n"
547     ".ascii \"		if $str[$tmp] > 31 && $str[$tmp] < 127\\n\"\n"
548     ".ascii \"			printf \\\"%c\\\", $str[$tmp]\\n\"\n"
549     ".ascii \"		else\\n\"\n"
550     ".ascii \"			printf \\\"\\\\\\\\\\\\\\\\%o\\\", $str[$tmp]\\n\"\n"
551     ".ascii \"		end\\n\"\n"
552     ".ascii \"		set $tmp = $tmp + 1\\n\"\n"
553     ".ascii \"	end\\n\"\n"
554     ".ascii \"	if $tmp != $arg1\\n\"\n"
555     ".ascii \"		printf \\\"...\\\"\\n\"\n"
556     ".ascii \"	end\\n\"\n"
557     ".ascii \"	printf \\\"\\\\\\\\\\\"\\\"\\n\"\n"
558     ".ascii \"end\\n\"\n"
559     ".ascii \"\\n\"\n"
560     ".ascii \"define printzn\\n\"\n"
561     ".ascii \"	____executor_globals\\n\"\n"
562     ".ascii \"	set $ind = 0\\n\"\n"
563     ".ascii \"	set $znode = $arg0\\n\"\n"
564     ".ascii \"	if $znode->op_type == 1\\n\"\n"
565     ".ascii \"		set $optype = \\\"IS_CONST\\\"\\n\"\n"
566     ".ascii \"	end\\n\"\n"
567     ".ascii \"	if $znode->op_type == 2\\n\"\n"
568     ".ascii \"		set $optype = \\\"IS_TMP_VAR\\\"\\n\"\n"
569     ".ascii \"	end\\n\"\n"
570     ".ascii \"	if $znode->op_type == 4\\n\"\n"
571     ".ascii \"		set $optype = \\\"IS_VAR\\\"\\n\"\n"
572     ".ascii \"	end\\n\"\n"
573     ".ascii \"	if $znode->op_type == 8\\n\"\n"
574     ".ascii \"		set $optype = \\\"IS_UNUSED\\\"\\n\"\n"
575     ".ascii \"	end\\n\"\n"
576     ".ascii \"\\n\"\n"
577     ".ascii \"	printf \\\"[%p] %s\\\", $znode, $optype\\n\"\n"
578     ".ascii \"\\n\"\n"
579     ".ascii \"	if $znode->op_type == 1\\n\"\n"
580     ".ascii \"		printf \\\": \\\"\\n\"\n"
581     ".ascii \"		____printzv &$znode->u.constant 0\\n\"\n"
582     ".ascii \"	end\\n\"\n"
583     ".ascii \"	if $znode->op_type == 2\\n\"\n"
584     ".ascii \"		printf \\\": \\\"\\n\"\n"
585     ".ascii \"		set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)\\n\"\n"
586     ".ascii \"		____printzv ((union _temp_variable *)$tvar)->tmp_var 0\\n\"\n"
587     ".ascii \"	end\\n\"\n"
588     ".ascii \"	if $znode->op_type == 4\\n\"\n"
589     ".ascii \"		printf \\\": \\\"\\n\"\n"
590     ".ascii \"		set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)\\n\"\n"
591     ".ascii \"		____printzv *$tvar->var.ptr_ptr 0\\n\"\n"
592     ".ascii \"	end\\n\"\n"
593     ".ascii \"	if $znode->op_type == 8\\n\"\n"
594     ".ascii \"		printf \\\"\\\\\\\\n\\\"\\n\"\n"
595     ".ascii \"	end\\n\"\n"
596     ".ascii \"end\\n\"\n"
597     ".ascii \"\\n\"\n"
598     ".ascii \"document printzn\\n\"\n"
599     ".ascii \"	print type and content of znode.\\n\"\n"
600     ".ascii \"	usage: printzn &opline->op1\\n\"\n"
601     ".ascii \"end\\n\"\n"
602     ".ascii \"\\n\"\n"
603     ".ascii \"define printzops\\n\"\n"
604     ".ascii \"	printf \\\"op1 => \\\"\\n\"\n"
605     ".ascii \"	printzn &execute_data->opline.op1\\n\"\n"
606     ".ascii \"	printf \\\"op2 => \\\"\\n\"\n"
607     ".ascii \"	printzn &execute_data->opline.op2\\n\"\n"
608     ".ascii \"	printf \\\"result => \\\"\\n\"\n"
609     ".ascii \"	printzn &execute_data->opline.result\\n\"\n"
610     ".ascii \"end\\n\"\n"
611     ".ascii \"\\n\"\n"
612     ".ascii \"document printzops\\n\"\n"
613     ".ascii \"	dump operands of the current opline\\n\"\n"
614     ".ascii \"end\\n\"\n"
615     ".ascii \"\\n\"\n"
616     ".ascii \"define print_zstr\\n\"\n"
617     ".ascii \"	set $zstr = (zend_string *)$arg0\\n\"\n"
618     ".ascii \"	if $argc == 2\\n\"\n"
619     ".ascii \"		set $maxlen = $arg1\\n\"\n"
620     ".ascii \"	else\\n\"\n"
621     ".ascii \"		set $maxlen = $zstr->len\\n\"\n"
622     ".ascii \"	end\\n\"\n"
623     ".ascii \"	printf \\\"string(%d) \\\", $zstr->len\\n\"\n"
624     ".ascii \"	____print_str (char*)$zstr->val $zstr->len $maxlen\\n\"\n"
625     ".ascii \"	printf \\\"\\\\\\\\n\\\"\\n\"\n"
626     ".ascii \"end\\n\"\n"
627     ".ascii \"\\n\"\n"
628     ".ascii \"document print_zstr\\n\"\n"
629     ".ascii \"	print the length and contents of a zend string\\n\"\n"
630     ".ascii \"	usage: print_zstr <ptr> [max length]\\n\"\n"
631     ".ascii \"end\\n\"\n"
632     ".ascii \"\\n\"\n"
633     ".ascii \"define zbacktrace\\n\"\n"
634     ".ascii \"	____executor_globals\\n\"\n"
635     ".ascii \"	dump_bt $eg.current_execute_data\\n\"\n"
636     ".ascii \"end\\n\"\n"
637     ".ascii \"\\n\"\n"
638     ".ascii \"document zbacktrace\\n\"\n"
639     ".ascii \"	prints backtrace.\\n\"\n"
640     ".ascii \"	This command is almost a short cut for\\n\"\n"
641     ".ascii \"	> (gdb) ____executor_globals\\n\"\n"
642     ".ascii \"	> (gdb) dump_bt $eg.current_execute_data\\n\"\n"
643     ".ascii \"end\\n\"\n"
644     ".ascii \"\\n\"\n"
645     ".ascii \"define lookup_root\\n\"\n"
646     ".ascii \"	set $found = 0\\n\"\n"
647     ".ascii \"	if gc_globals->roots\\n\"\n"
648     ".ascii \"		set $current = gc_globals->roots->next\\n\"\n"
649     ".ascii \"		printf \\\"looking ref %p in roots\\\\\\\\n\\\", $arg0\\n\"\n"
650     ".ascii \"		while $current != &gc_globals->roots\\n\"\n"
651     ".ascii \"			if $current->ref == $arg0\\n\"\n"
652     ".ascii \"				set $found = $current\\n\"\n"
653     ".ascii \"				break\\n\"\n"
654     ".ascii \"			end\\n\"\n"
655     ".ascii \"			set $current = $current->next\\n\"\n"
656     ".ascii \"		end\\n\"\n"
657     ".ascii \"		if $found != 0\\n\"\n"
658     ".ascii \"			printf \\\"found root %p\\\\\\\\n\\\", $found\\n\"\n"
659     ".ascii \"		else\\n\"\n"
660     ".ascii \"			printf \\\"not found\\\\\\\\n\\\"\\n\"\n"
661     ".ascii \"		end\\n\"\n"
662     ".ascii \"	end\\n\"\n"
663     ".ascii \"end\\n\"\n"
664     ".ascii \"\\n\"\n"
665     ".ascii \"document lookup_root\\n\"\n"
666     ".ascii \"	lookup a refcounted in root\\n\"\n"
667     ".ascii \"	usage: lookup_root [ptr].\\n\"\n"
668     ".ascii \"end\\n\"\n"
669     ".ascii \"\\n\"\n"
670     ".ascii \"''')\\n\"\n"
671     ".ascii \"\\n\"\n"
672     ".ascii \"\\\"\\\"\\\"GDB support for PHP types\\n\"\n"
673     ".ascii \"\\n\"\n"
674     ".ascii \"This is auto-loaded by GDB if Python Auto-loading is enabled (the default), and\\n\"\n"
675     ".ascii \"the PHP binary is in the auto load safe path:\\n\"\n"
676     ".ascii \"\\n\"\n"
677     ".ascii \"    # ~/.config/gdb/gdbinit (not ~/.gdbinit)\\n\"\n"
678     ".ascii \"    add-auto-load-safe-path /path/to/php-src\\n\"\n"
679     ".ascii \"\\n\"\n"
680     ".ascii \"See https://sourceware.org/gdb/current/onlinedocs/gdb.html/Python-Auto_002dloading.html\\n\"\n"
681     ".ascii \"See https://sourceware.org/gdb/current/onlinedocs/gdb.html/Auto_002dloading-safe-path.html#Auto_002dloading-safe-path\\n\"\n"
682     ".ascii \"\\n\"\n"
683     ".ascii \"If needed, pretty printers can be by-passed by using the /r flag:\\n\"\n"
684     ".ascii \"  (gdb) p /r any_variable\\n\"\n"
685     ".ascii \"\\n\"\n"
686     ".ascii \"Use |set print pretty| to enable multi-line printing and indentation:\\n\"\n"
687     ".ascii \"  (gdb) set print pretty on\\n\"\n"
688     ".ascii \"\\n\"\n"
689     ".ascii \"Use |set print max-depth| to control the maximum print depth for nested\\n\"\n"
690     ".ascii \"structures:\\n\"\n"
691     ".ascii \"  (gdb) set print pretty on\\n\"\n"
692     ".ascii \"\\n\"\n"
693     ".ascii \"To interactively type Python for development of the printers, use\\n\"\n"
694     ".ascii \"  (gdb) python foo = gdb.parse_and_eval('bar')\\n\"\n"
695     ".ascii \"to put the C value 'bar' in the current scope into a Python variable 'foo'.\\n\"\n"
696     ".ascii \"Then you can interact with that variable:\\n\"\n"
697     ".ascii \"  (gdb) python print foo['impl_']\\n\"\n"
698     ".ascii \"\\\"\\\"\\\"\\n\"\n"
699     ".ascii \"\\n\"\n"
700     ".ascii \"import gdb\\n\"\n"
701     ".ascii \"import re\\n\"\n"
702     ".ascii \"\\n\"\n"
703     ".ascii \"pp_set = gdb.printing.RegexpCollectionPrettyPrinter(\\\"php\\\")\\n\"\n"
704     ".ascii \"\\n\"\n"
705     ".ascii \"class ZendStringPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
706     ".ascii \"    \\\"Print a zend_string\\\"\\n\"\n"
707     ".ascii \"\\n\"\n"
708     ".ascii \"    def __init__(self, val):\\n\"\n"
709     ".ascii \"        self.val = val\\n\"\n"
710     ".ascii \"\\n\"\n"
711     ".ascii \"    def to_string(self):\\n\"\n"
712     ".ascii \"        return self.format_string()\\n\"\n"
713     ".ascii \"\\n\"\n"
714     ".ascii \"    def children(self):\\n\"\n"
715     ".ascii \"        for field in self.val.type.fields():\\n\"\n"
716     ".ascii \"            if field.name == 'val':\\n\"\n"
717     ".ascii \"                yield ('val', self.format_string())\\n\"\n"
718     ".ascii \"            else:\\n\"\n"
719     ".ascii \"                yield (field.name, self.val[field.name])\\n\"\n"
720     ".ascii \"\\n\"\n"
721     ".ascii \"    def format_string(self):\\n\"\n"
722     ".ascii \"        len = int(self.val['len'])\\n\"\n"
723     ".ascii \"        truncated = False\\n\"\n"
724     ".ascii \"        if len > 50:\\n\"\n"
725     ".ascii \"            len = 50\\n\"\n"
726     ".ascii \"            truncated = True\\n\"\n"
727     ".ascii \"\\n\"\n"
728     ".ascii \"        ptr_type = gdb.lookup_type('char').pointer()\\n\"\n"
729     ".ascii \"        ary_type = gdb.lookup_type('char').array(len)\\n\"\n"
730     ".ascii \"        str = self.val['val'].cast(ptr_type).dereference().cast(ary_type)\\n\"\n"
731     ".ascii \"        str = str.format_string()\\n\"\n"
732     ".ascii \"        if truncated:\\n\"\n"
733     ".ascii \"            str += ' (%d bytes total)' % int(self.val['len'])\\n\"\n"
734     ".ascii \"\\n\"\n"
735     ".ascii \"        return str\\n\"\n"
736     ".ascii \"\\n\"\n"
737     ".ascii \"\\n\"\n"
738     ".ascii \"pp_set.add_printer('zend_string', '^_zend_string$', ZendStringPrettyPrinter)\\n\"\n"
739     ".ascii \"\\n\"\n"
740     ".ascii \"class ZendTypePrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
741     ".ascii \"    \\\"Print a zend_type\\\"\\n\"\n"
742     ".ascii \"\\n\"\n"
743     ".ascii \"    def __init__(self, val):\\n\"\n"
744     ".ascii \"        self.val = val\\n\"\n"
745     ".ascii \"        load_type_bits()\\n\"\n"
746     ".ascii \"\\n\"\n"
747     ".ascii \"    def to_string(self):\\n\"\n"
748     ".ascii \"        return self.format_type(self.val)\\n\"\n"
749     ".ascii \"\\n\"\n"
750     ".ascii \"    def children(self):\\n\"\n"
751     ".ascii \"        for field in self.val.type.fields():\\n\"\n"
752     ".ascii \"            yield (field.name, self.val[field.name])\\n\"\n"
753     ".ascii \"\\n\"\n"
754     ".ascii \"    def format_type(self, t):\\n\"\n"
755     ".ascii \"        type_mask = int(t['type_mask'])\\n\"\n"
756     ".ascii \"        type_mask_size = t['type_mask'].type.sizeof * 8\\n\"\n"
757     ".ascii \"        separator = '|'\\n\"\n"
758     ".ascii \"        parts = []\\n\"\n"
759     ".ascii \"        meta = []\\n\"\n"
760     ".ascii \"        for bit in range(0, type_mask_size):\\n\"\n"
761     ".ascii \"            if type_mask & (1 << bit):\\n\"\n"
762     ".ascii \"                type_name = type_bit_to_name.get(bit)\\n\"\n"
763     ".ascii \"                match type_name:\\n\"\n"
764     ".ascii \"                    case None:\\n\"\n"
765     ".ascii \"                        parts.append('(1<<%d)' % bit)\\n\"\n"
766     ".ascii \"                    case 'list':\\n\"\n"
767     ".ascii \"                        list = t['ptr'].cast(gdb.lookup_type('zend_type_list').pointer())\\n\"\n"
768     ".ascii \"                        num_types = int(list['num_types'])\\n\"\n"
769     ".ascii \"                        types = list['types'].dereference().cast(gdb.lookup_type('zend_type').array(num_types))\\n\"\n"
770     ".ascii \"                        for i in range(0, num_types):\\n\"\n"
771     ".ascii \"                            str = self.format_type(types[i])\\n\"\n"
772     ".ascii \"                            if any((c in set('|&()')) for c in str):\\n\"\n"
773     ".ascii \"                                str = '(%s)' % str\\n\"\n"
774     ".ascii \"                            parts.append(str)\\n\"\n"
775     ".ascii \"                    case 'union' | 'arena':\\n\"\n"
776     ".ascii \"                        meta.append(type_name)\\n\"\n"
777     ".ascii \"                    case 'intersection':\\n\"\n"
778     ".ascii \"                        meta.append(type_name)\\n\"\n"
779     ".ascii \"                        separator = '&'\\n\"\n"
780     ".ascii \"                    case 'name':\\n\"\n"
781     ".ascii \"                        str = t['ptr'].cast(gdb.lookup_type('zend_string').pointer())\\n\"\n"
782     ".ascii \"                        parts.append(ZendStringPrettyPrinter(str).to_string())\\n\"\n"
783     ".ascii \"                    case _:\\n\"\n"
784     ".ascii \"                        parts.append(type_name)\\n\"\n"
785     ".ascii \"\\n\"\n"
786     ".ascii \"        str = separator.join(parts)\\n\"\n"
787     ".ascii \"\\n\"\n"
788     ".ascii \"        if len(meta) > 0:\\n\"\n"
789     ".ascii \"            str = '[%s] %s' % (','.join(meta), str)\\n\"\n"
790     ".ascii \"\\n\"\n"
791     ".ascii \"        return str\\n\"\n"
792     ".ascii \"\\n\"\n"
793     ".ascii \"\\n\"\n"
794     ".ascii \"pp_set.add_printer('zend_type', '^zend_type$', ZendTypePrettyPrinter)\\n\"\n"
795     ".ascii \"\\n\"\n"
796     ".ascii \"class ZendAstKindPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
797     ".ascii \"    \\\"Print a zend_ast_kind\\\"\\n\"\n"
798     ".ascii \"\\n\"\n"
799     ".ascii \"    def __init__(self, val):\\n\"\n"
800     ".ascii \"        self.val = val\\n\"\n"
801     ".ascii \"\\n\"\n"
802     ".ascii \"    def to_string(self):\\n\"\n"
803     ".ascii \"        return self.val.cast(gdb.lookup_type('enum _zend_ast_kind'))\\n\"\n"
804     ".ascii \"\\n\"\n"
805     ".ascii \"\\n\"\n"
806     ".ascii \"pp_set.add_printer('zend_ast_kind', '^zend_ast_kind$', ZendAstKindPrettyPrinter)\\n\"\n"
807     ".ascii \"\\n\"\n"
808     ".ascii \"class ZendAstPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
809     ".ascii \"    \\\"Print a zend_ast\\\"\\n\"\n"
810     ".ascii \"\\n\"\n"
811     ".ascii \"    def __init__(self, val):\\n\"\n"
812     ".ascii \"        self.val = val\\n\"\n"
813     ".ascii \"\\n\"\n"
814     ".ascii \"    def to_string(self):\\n\"\n"
815     ".ascii \"        return '((%s*)0x%x)' % (str(self.cast().type), self.val.address)\\n\"\n"
816     ".ascii \"\\n\"\n"
817     ".ascii \"    def children(self):\\n\"\n"
818     ".ascii \"        val = self.cast()\\n\"\n"
819     ".ascii \"        for field in val.type.fields():\\n\"\n"
820     ".ascii \"            if field.name == 'child':\\n\"\n"
821     ".ascii \"                children = val[field.name]\\n\"\n"
822     ".ascii \"                num_children = self.num_children()\\n\"\n"
823     ".ascii \"\\n\"\n"
824     ".ascii \"                ptr_type = gdb.lookup_type('zend_ast').pointer().pointer()\\n\"\n"
825     ".ascii \"                children = children.cast(ptr_type)\\n\"\n"
826     ".ascii \"\\n\"\n"
827     ".ascii \"                for i in range(0, num_children):\\n\"\n"
828     ".ascii \"                    c = children[i]\\n\"\n"
829     ".ascii \"                    if int(c) != 0:\\n\"\n"
830     ".ascii \"                        c = c.dereference()\\n\"\n"
831     ".ascii \"                    yield ('child[%d]' % i, c)\\n\"\n"
832     ".ascii \"            elif field.name == 'name':\\n\"\n"
833     ".ascii \"                yield (field.name, ZendStringPrettyPrinter(val[field.name].dereference()).to_string())\\n\"\n"
834     ".ascii \"            elif field.name == 'val':\\n\"\n"
835     ".ascii \"                yield (field.name, ZvalPrettyPrinter(val[field.name]).to_string())\\n\"\n"
836     ".ascii \"            else:\\n\"\n"
837     ".ascii \"                yield (field.name, val[field.name])\\n\"\n"
838     ".ascii \"\\n\"\n"
839     ".ascii \"    def is_special(self):\\n\"\n"
840     ".ascii \"        special_shift = 6 # ZEND_AST_SPECIAL_SHIFT\\n\"\n"
841     ".ascii \"        kind = self.val['kind']\\n\"\n"
842     ".ascii \"        return (kind >> special_shift) & 1\\n\"\n"
843     ".ascii \"\\n\"\n"
844     ".ascii \"    def is_decl(self):\\n\"\n"
845     ".ascii \"        return self.is_special() and int(self.val['kind']) >= enum_value('ZEND_AST_FUNC_DECL')\\n\"\n"
846     ".ascii \"\\n\"\n"
847     ".ascii \"    def is_list(self):\\n\"\n"
848     ".ascii \"        list_shift = 7 # ZEND_AST_IS_LIST_SHIFT\\n\"\n"
849     ".ascii \"        kind = self.val['kind']\\n\"\n"
850     ".ascii \"        return (kind >> list_shift) & 1\\n\"\n"
851     ".ascii \"\\n\"\n"
852     ".ascii \"    def cast(self):\\n\"\n"
853     ".ascii \"        kind = int(self.val['kind'])\\n\"\n"
854     ".ascii \"\\n\"\n"
855     ".ascii \"        if kind == enum_value('ZEND_AST_ZVAL') or kind == enum_value('ZEND_AST_CONSTANT'):\\n\"\n"
856     ".ascii \"            return self.val.cast(gdb.lookup_type('zend_ast_zval'))\\n\"\n"
857     ".ascii \"        if kind == enum_value('ZEND_AST_ZNODE'):\\n\"\n"
858     ".ascii \"            return self.val.cast(gdb.lookup_type('zend_ast_znode'))\\n\"\n"
859     ".ascii \"        if self.is_decl():\\n\"\n"
860     ".ascii \"            return self.val.cast(gdb.lookup_type('zend_ast_decl'))\\n\"\n"
861     ".ascii \"        if self.is_list():\\n\"\n"
862     ".ascii \"            return self.val.cast(gdb.lookup_type('zend_ast_list'))\\n\"\n"
863     ".ascii \"\\n\"\n"
864     ".ascii \"        return self.val\\n\"\n"
865     ".ascii \"\\n\"\n"
866     ".ascii \"    def num_children(self):\\n\"\n"
867     ".ascii \"        if self.is_decl():\\n\"\n"
868     ".ascii \"            decl_type = gdb.lookup_type('zend_ast_decl')\\n\"\n"
869     ".ascii \"            child_type = decl_type['child'].type\\n\"\n"
870     ".ascii \"            return array_size(child_type)\\n\"\n"
871     ".ascii \"        if self.is_special():\\n\"\n"
872     ".ascii \"            return 0\\n\"\n"
873     ".ascii \"        elif self.is_list():\\n\"\n"
874     ".ascii \"            return int(self.cast()['children'])\\n\"\n"
875     ".ascii \"        else:\\n\"\n"
876     ".ascii \"            num_children_shift = 8 # ZEND_AST_NUM_CHILDREN_SHIFT\\n\"\n"
877     ".ascii \"            kind = self.val['kind']\\n\"\n"
878     ".ascii \"            return kind >> num_children_shift\\n\"\n"
879     ".ascii \"\\n\"\n"
880     ".ascii \"\\n\"\n"
881     ".ascii \"pp_set.add_printer('zend_ast', '^_zend_ast$', ZendAstPrettyPrinter)\\n\"\n"
882     ".ascii \"\\n\"\n"
883     ".ascii \"class ZvalPrettyPrinter(gdb.printing.PrettyPrinter):\\n\"\n"
884     ".ascii \"    \\\"Print a zval\\\"\\n\"\n"
885     ".ascii \"\\n\"\n"
886     ".ascii \"    def __init__(self, val):\\n\"\n"
887     ".ascii \"        self.val = val\\n\"\n"
888     ".ascii \"        load_type_bits()\\n\"\n"
889     ".ascii \"\\n\"\n"
890     ".ascii \"    def to_string(self):\\n\"\n"
891     ".ascii \"        return self.value_to_string()\\n\"\n"
892     ".ascii \"\\n\"\n"
893     ".ascii \"    def value_to_string(self):\\n\"\n"
894     ".ascii \"        t = int(self.val['u1']['v']['type'])\\n\"\n"
895     ".ascii \"        if t == type_name_to_bit['undef']:\\n\"\n"
896     ".ascii \"            return 'undef'\\n\"\n"
897     ".ascii \"        elif t == type_name_to_bit['null']:\\n\"\n"
898     ".ascii \"            return 'null'\\n\"\n"
899     ".ascii \"        elif t == type_name_to_bit['false']:\\n\"\n"
900     ".ascii \"            return 'false'\\n\"\n"
901     ".ascii \"        elif t == type_name_to_bit['true']:\\n\"\n"
902     ".ascii \"            return 'true'\\n\"\n"
903     ".ascii \"        elif t == type_name_to_bit['long']:\\n\"\n"
904     ".ascii \"            return str(self.val['value']['lval'])\\n\"\n"
905     ".ascii \"        elif t == type_name_to_bit['double']:\\n\"\n"
906     ".ascii \"            return str(self.val['value']['dval'])\\n\"\n"
907     ".ascii \"        elif t == type_name_to_bit['string']:\\n\"\n"
908     ".ascii \"            return ZendStringPrettyPrinter(self.val['value']['str'].dereference()).to_string()\\n\"\n"
909     ".ascii \"        elif t == type_name_to_bit['array']:\\n\"\n"
910     ".ascii \"            return 'array'\\n\"\n"
911     ".ascii \"        elif t == type_name_to_bit['object']:\\n\"\n"
912     ".ascii \"            return 'object(%s)' % ZendStringPrettyPrinter(self.val['value']['obj']['ce']['name'].dereference()).to_string()\\n\"\n"
913     ".ascii \"        elif t == type_name_to_bit['resource']:\\n\"\n"
914     ".ascii \"            return 'resource'\\n\"\n"
915     ".ascii \"        elif t == type_name_to_bit['reference']:\\n\"\n"
916     ".ascii \"            return 'reference'\\n\"\n"
917     ".ascii \"        elif t == type_name_to_bit['constant_ast']:\\n\"\n"
918     ".ascii \"            return 'constant_ast'\\n\"\n"
919     ".ascii \"        else:\\n\"\n"
920     ".ascii \"            return 'zval of type %d' % int(self.val['u1']['v']['type'])\\n\"\n"
921     ".ascii \"\\n\"\n"
922     ".ascii \"    def children(self):\\n\"\n"
923     ".ascii \"        for field in self.val.type.fields():\\n\"\n"
924     ".ascii \"            if field.name == 'value':\\n\"\n"
925     ".ascii \"                value = self.val['value']\\n\"\n"
926     ".ascii \"                t = int(self.val['u1']['v']['type'])\\n\"\n"
927     ".ascii \"                if t == type_name_to_bit['undef']:\\n\"\n"
928     ".ascii \"                    value = value['lval']\\n\"\n"
929     ".ascii \"                elif t == type_name_to_bit['null']:\\n\"\n"
930     ".ascii \"                    value = value['lval']\\n\"\n"
931     ".ascii \"                elif t == type_name_to_bit['false']:\\n\"\n"
932     ".ascii \"                    value = value['lval']\\n\"\n"
933     ".ascii \"                elif t == type_name_to_bit['true']:\\n\"\n"
934     ".ascii \"                    value = value['lval']\\n\"\n"
935     ".ascii \"                elif t == type_name_to_bit['long']:\\n\"\n"
936     ".ascii \"                    value = value['lval']\\n\"\n"
937     ".ascii \"                elif t == type_name_to_bit['double']:\\n\"\n"
938     ".ascii \"                    value = value['dval']\\n\"\n"
939     ".ascii \"                elif t == type_name_to_bit['string']:\\n\"\n"
940     ".ascii \"                    value = value['str'].dereference()\\n\"\n"
941     ".ascii \"                elif t == type_name_to_bit['array']:\\n\"\n"
942     ".ascii \"                    value = value['ht'].dereference()\\n\"\n"
943     ".ascii \"                elif t == type_name_to_bit['object']:\\n\"\n"
944     ".ascii \"                    value = value['obj'].dereference()\\n\"\n"
945     ".ascii \"                elif t == type_name_to_bit['resource']:\\n\"\n"
946     ".ascii \"                    value = value['res'].dereference()\\n\"\n"
947     ".ascii \"                elif t == type_name_to_bit['reference']:\\n\"\n"
948     ".ascii \"                    value = value['ref'].dereference()\\n\"\n"
949     ".ascii \"                elif t == type_name_to_bit['constant_ast']:\\n\"\n"
950     ".ascii \"                    value = value['ast'].dereference()\\n\"\n"
951     ".ascii \"                else:\\n\"\n"
952     ".ascii \"                    value = value['ptr']\\n\"\n"
953     ".ascii \"                yield (field.name, value)\\n\"\n"
954     ".ascii \"            elif field.name == 'u2':\\n\"\n"
955     ".ascii \"                yield ('u2', self.val[field.name]['extra'])\\n\"\n"
956     ".ascii \"            else:\\n\"\n"
957     ".ascii \"                yield (field.name, self.val[field.name])\\n\"\n"
958     ".ascii \"\\n\"\n"
959     ".ascii \"\\n\"\n"
960     ".ascii \"pp_set.add_printer('zval', '^_zval_struct$', ZvalPrettyPrinter)\\n\"\n"
961     ".ascii \"\\n\"\n"
962     ".ascii \"type_bit_to_name = None\\n\"\n"
963     ".ascii \"type_name_to_bit = None\\n\"\n"
964     ".ascii \"\\n\"\n"
965     ".ascii \"def load_type_bits():\\n\"\n"
966     ".ascii \"    global type_bit_to_name\\n\"\n"
967     ".ascii \"    global type_name_to_bit\\n\"\n"
968     ".ascii \"\\n\"\n"
969     ".ascii \"    if type_bit_to_name != None:\\n\"\n"
970     ".ascii \"        return\\n\"\n"
971     ".ascii \"\\n\"\n"
972     ".ascii \"    (symbol,_) = gdb.lookup_symbol(\\\"zend_gc_refcount\\\")\\n\"\n"
973     ".ascii \"    if symbol == None:\\n\"\n"
974     ".ascii \"        raise Exception(\\\"Could not find zend_types.h: symbol zend_gc_refcount not found\\\")\\n\"\n"
975     ".ascii \"    filename = symbol.symtab.fullname()\\n\"\n"
976     ".ascii \"\\n\"\n"
977     ".ascii \"    bits = {}\\n\"\n"
978     ".ascii \"\\n\"\n"
979     ".ascii \"    with open(filename, 'r') as file:\\n\"\n"
980     ".ascii \"        content = file.read()\\n\"\n"
981     ".ascii \"\\n\"\n"
982     ".ascii \"        pattern = re.compile(r'#define _ZEND_TYPE_([^\\\\s]+)_BIT\\\\s+\\\\(1u << (\\\\d+)\\\\)')\\n\"\n"
983     ".ascii \"        matches = pattern.findall(content)\\n\"\n"
984     ".ascii \"        for name, bit in matches:\\n\"\n"
985     ".ascii \"            bits[int(bit)] = name.lower()\\n\"\n"
986     ".ascii \"\\n\"\n"
987     ".ascii \"        pattern = re.compile(r'#define IS_([^\\\\s]+)\\\\s+(\\\\d+)')\\n\"\n"
988     ".ascii \"        matches = pattern.findall(content)\\n\"\n"
989     ".ascii \"        for name, bit in matches:\\n\"\n"
990     ".ascii \"            if not int(bit) in bits:\\n\"\n"
991     ".ascii \"                bits[int(bit)] = name.lower()\\n\"\n"
992     ".ascii \"\\n\"\n"
993     ".ascii \"    types = {}\\n\"\n"
994     ".ascii \"    for bit in bits:\\n\"\n"
995     ".ascii \"        types[bits[bit]] = bit\\n\"\n"
996     ".ascii \"\\n\"\n"
997     ".ascii \"    type_bit_to_name = bits\\n\"\n"
998     ".ascii \"    type_name_to_bit = types\\n\"\n"
999     ".ascii \"\\n\"\n"
1000     ".ascii \"def lookup_symbol(name):\\n\"\n"
1001     ".ascii \"    (symbol, _) = gdb.lookup_symbol(name)\\n\"\n"
1002     ".ascii \"    if symbol == None:\\n\"\n"
1003     ".ascii \"        raise Exception(\\\"Could not lookup symbol %s\\\" % name)\\n\"\n"
1004     ".ascii \"    return symbol\\n\"\n"
1005     ".ascii \"\\n\"\n"
1006     ".ascii \"def enum_value(name):\\n\"\n"
1007     ".ascii \"    symbol = lookup_symbol(name)\\n\"\n"
1008     ".ascii \"    return int(symbol.value())\\n\"\n"
1009     ".ascii \"\\n\"\n"
1010     ".ascii \"def array_size(ary_type):\\n\"\n"
1011     ".ascii \"    # array types have a single field whose type represents its range\\n\"\n"
1012     ".ascii \"    return ary_type.fields()[0].type.range()[1]+1\\n\"\n"
1013     ".ascii \"\\n\"\n"
1014     ".ascii \"gdb.printing.register_pretty_printer(gdb, pp_set, replace=True)\\n\"\n"
1015     ".ascii \"\\n\"\n"
1016     ".byte 0\n"
1017     ".popsection\n"
1018 );
1019