php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
ir_gdb.c
Go to the documentation of this file.
1/*
2 * IR - Lightweight JIT Compilation Framework
3 * (GDB interface)
4 * Copyright (C) 2022 Zend by Perforce.
5 * Authors: Dmitry Stogov <dmitry@php.net>
6 *
7 * Based on Mike Pall's implementation of GDB interface for LuaJIT.
8 */
9
10#include <stddef.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <fcntl.h>
14
15#ifdef __FreeBSD__
16# include <sys/types.h>
17# include <sys/sysctl.h>
18# include <sys/user.h>
19#endif
20
21#include "ir.h"
22#include "ir_private.h"
23#include "ir_elf.h"
24
25/* DWARF definitions. */
26#define DW_CIE_VERSION 1
27
28/* CFA (Canonical frame address) */
29enum {
37};
38
39enum {
42};
43
44enum {
46};
47
48enum {
51};
52
53enum {
54 DW_AT_name = 0x03,
58};
59
60enum {
64};
65
66enum {
71};
72
73enum {
76};
77
78enum {
79#if defined(IR_TARGET_X86)
80 DW_REG_AX, DW_REG_CX, DW_REG_DX, DW_REG_BX,
81 DW_REG_SP, DW_REG_BP, DW_REG_SI, DW_REG_DI,
82 DW_REG_RA,
83#elif defined(IR_TARGET_X64)
84 /* Yes, the order is strange, but correct. */
85 DW_REG_AX, DW_REG_DX, DW_REG_CX, DW_REG_BX,
86 DW_REG_SI, DW_REG_DI, DW_REG_BP, DW_REG_SP,
87 DW_REG_8, DW_REG_9, DW_REG_10, DW_REG_11,
88 DW_REG_12, DW_REG_13, DW_REG_14, DW_REG_15,
89 DW_REG_RA,
90#elif defined(IR_TARGET_AARCH64)
91 DW_REG_SP = 31,
92 DW_REG_RA = 30,
93 DW_REG_X29 = 29,
94#else
95#error "Unsupported target architecture"
96#endif
97};
98
99enum {
110};
111
112enum {
117};
118
125
126static const ir_elf_header ir_elfhdr_template = {
127 .emagic = { 0x7f, 'E', 'L', 'F' },
128#ifdef ELF64
129 .eclass = 2,
130#else
131 .eclass = 1,
132#endif
133#ifdef WORDS_BIGENDIAN
134 .eendian = 2,
135#else
136 .eendian = 1,
137#endif
138 .eversion = 1,
139#if defined(Linux)
140 .eosabi = 0, /* TODO: Nope, it's not 3. ??? */
141#elif defined(__FreeBSD__)
142 .eosabi = 9,
143#elif defined(__OpenBSD__)
144 .eosabi = 12,
145#elif defined(__NetBSD__)
146 .eosabi = 2,
147#elif defined(__DragonFly__)
148 .eosabi = 0,
149#elif (defined(__sun__) && defined(__svr4__))
150 .eosabi = 6,
151#else
152 .eosabi = 0,
153#endif
154 .eabiversion = 0,
155 .epad = { 0, 0, 0, 0, 0, 0, 0 },
156 .type = 1,
157#if defined(IR_TARGET_X86)
158 .machine = 3,
159#elif defined(IR_TARGET_X64)
160 .machine = 62,
161#elif defined(IR_TARGET_AARCH64)
162 .machine = 183,
163#else
164# error "Unsupported target architecture"
165#endif
166 .version = 1,
167 .entry = 0,
168 .phofs = 0,
169 .shofs = offsetof(ir_gdbjit_obj, sect),
170 .flags = 0,
171 .ehsize = sizeof(ir_elf_header),
172 .phentsize = 0,
173 .phnum = 0,
174 .shentsize = sizeof(ir_elf_sectheader),
175 .shnum = GDBJIT_SECT__MAX,
176 .shstridx = GDBJIT_SECT_shstrtab
177};
178
179/* Context for generating the ELF object for the GDB JIT API. */
180typedef struct _ir_gdbjit_ctx {
181 uint8_t *p; /* Pointer to next address in obj.space. */
182 uint8_t *startp; /* Pointer to start address in obj.space. */
183 uintptr_t mcaddr; /* Machine code address. */
184 uint32_t szmcode; /* Size of machine code. */
185 int32_t lineno; /* Starting line number. */
186 const char *name; /* JIT function name */
187 const char *filename; /* Starting file name. */
188 size_t objsize; /* Final size of ELF object. */
189 ir_gdbjit_obj obj; /* In-memory ELF object. */
191
192/* Add a zero-terminated string */
193static uint32_t ir_gdbjit_strz(ir_gdbjit_ctx *ctx, const char *str)
194{
195 uint8_t *p = ctx->p;
196 uint32_t ofs = (uint32_t)(p - ctx->startp);
197 do {
198 *p++ = (uint8_t)*str;
199 } while (*str++);
200 ctx->p = p;
201 return ofs;
202}
203
204/* Add a ULEB128 value */
205static void ir_gdbjit_uleb128(ir_gdbjit_ctx *ctx, uint32_t v)
206{
207 uint8_t *p = ctx->p;
208 for (; v >= 0x80; v >>= 7)
209 *p++ = (uint8_t)((v & 0x7f) | 0x80);
210 *p++ = (uint8_t)v;
211 ctx->p = p;
212}
213
214/* Add a SLEB128 value */
215static void ir_gdbjit_sleb128(ir_gdbjit_ctx *ctx, int32_t v)
216{
217 uint8_t *p = ctx->p;
218 for (; (uint32_t)(v+0x40) >= 0x80; v >>= 7)
219 *p++ = (uint8_t)((v & 0x7f) | 0x80);
220 *p++ = (uint8_t)(v & 0x7f);
221 ctx->p = p;
222}
223
224static void ir_gdbjit_secthdr(ir_gdbjit_ctx *ctx)
225{
226 ir_elf_sectheader *sect;
227
228 *ctx->p++ = '\0';
229
230#define SECTDEF(id, tp, al) \
231 sect = &ctx->obj.sect[GDBJIT_SECT_##id]; \
232 sect->name = ir_gdbjit_strz(ctx, "." #id); \
233 sect->type = ELFSECT_TYPE_##tp; \
234 sect->align = (al)
235
236 SECTDEF(text, NOBITS, 16);
238 sect->addr = ctx->mcaddr;
239 sect->ofs = 0;
240 sect->size = ctx->szmcode;
241
242 SECTDEF(eh_frame, PROGBITS, sizeof(uintptr_t));
244
245 SECTDEF(shstrtab, STRTAB, 1);
246 SECTDEF(strtab, STRTAB, 1);
247
248 SECTDEF(symtab, SYMTAB, sizeof(uintptr_t));
249 sect->ofs = offsetof(ir_gdbjit_obj, sym);
250 sect->size = sizeof(ctx->obj.sym);
251 sect->link = GDBJIT_SECT_strtab;
252 sect->entsize = sizeof(ir_elf_symbol);
253 sect->info = GDBJIT_SYM_FUNC;
254
255 SECTDEF(debug_info, PROGBITS, 1);
256 SECTDEF(debug_abbrev, PROGBITS, 1);
257 SECTDEF(debug_line, PROGBITS, 1);
258
259#undef SECTDEF
260}
261
262static void ir_gdbjit_symtab(ir_gdbjit_ctx *ctx)
263{
264 ir_elf_symbol *sym;
265
266 *ctx->p++ = '\0';
267
268 sym = &ctx->obj.sym[GDBJIT_SYM_FILE];
269 sym->name = ir_gdbjit_strz(ctx, "JIT code");
272
273 sym = &ctx->obj.sym[GDBJIT_SYM_FUNC];
274 sym->name = ir_gdbjit_strz(ctx, ctx->name);
276 sym->value = 0;
277 sym->size = ctx->szmcode;
279}
280
281typedef IR_SET_ALIGNED(1, uint16_t unaligned_uint16_t);
282typedef IR_SET_ALIGNED(1, uint32_t unaligned_uint32_t);
283typedef IR_SET_ALIGNED(1, uintptr_t unaligned_uintptr_t);
284
285#define SECTALIGN(p, a) \
286 ((p) = (uint8_t *)(((uintptr_t)(p) + ((a)-1)) & ~(uintptr_t)((a)-1)))
287
288/* Shortcuts to generate DWARF structures. */
289#define DB(x) (*p++ = (x))
290#define DI8(x) (*(int8_t *)p = (x), p++)
291#define DU16(x) (*(unaligned_uint16_t *)p = (x), p += 2)
292#define DU32(x) (*(unaligned_uint32_t *)p = (x), p += 4)
293#define DADDR(x) (*(unaligned_uintptr_t *)p = (x), p += sizeof(uintptr_t))
294#define DUV(x) (ctx->p = p, ir_gdbjit_uleb128(ctx, (x)), p = ctx->p)
295#define DSV(x) (ctx->p = p, ir_gdbjit_sleb128(ctx, (x)), p = ctx->p)
296#define DSTR(str) (ctx->p = p, ir_gdbjit_strz(ctx, (str)), p = ctx->p)
297#define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop
298#define DSECT(name, stmt) \
299 { unaligned_uint32_t *szp_##name = (uint32_t *)p; p += 4; stmt \
300 *szp_##name = (uint32_t)((p-(uint8_t *)szp_##name)-4); }
301
302static void ir_gdbjit_ehframe(ir_gdbjit_ctx *ctx, uint32_t sp_offset, uint32_t sp_adjustment)
303{
304 uint8_t *p = ctx->p;
305 uint8_t *framep = p;
306
307 /* DWARF EH CIE (Common Information Entry) */
308 DSECT(CIE,
309 DU32(0); /* CIE ID. */
310 DB(DW_CIE_VERSION); /* Version */
311 DSTR("zR"); /* Augmentation String. */
312 DUV(1); /* Code alignment factor. */
313 DSV(-(int32_t)sizeof(uintptr_t)); /* Data alignment factor. */
314 DB(DW_REG_RA); /* Return address register. */
315 DB(1); DB(DW_EH_PE_textrel|DW_EH_PE_udata4); /* Augmentation data. */
316#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
317 DB(DW_CFA_def_cfa); DUV(DW_REG_SP); DUV(sizeof(uintptr_t));
318 DB(DW_CFA_offset|DW_REG_RA); DUV(1);
319#elif defined(IR_TARGET_AARCH64)
320 DB(DW_CFA_def_cfa); DUV(DW_REG_SP); DUV(0);
321#endif
322 DALIGNNOP(sizeof(uintptr_t));
323 )
324
325 /* DWARF EH FDE (Frame Description Entry). */
326 DSECT(FDE,
327 DU32((uint32_t)(p-framep)); /* Offset to CIE Pointer. */
328 DU32(0); /* Machine code offset relative to .text. */
329 DU32(ctx->szmcode); /* Machine code length. */
330 DB(0); /* Augmentation data. */
331 DB(DW_CFA_def_cfa_offset); DUV(sp_offset);
332#if defined(IR_TARGET_AARCH64)
333 if (sp_offset) {
334 if (sp_adjustment && sp_adjustment < sp_offset) {
335 DB(DW_CFA_offset|DW_REG_X29); DUV(sp_adjustment / sizeof(uintptr_t));
336 DB(DW_CFA_offset|DW_REG_RA); DUV((sp_adjustment / sizeof(uintptr_t)) - 1);
337 } else {
338 DB(DW_CFA_offset|DW_REG_X29); DUV(sp_offset / sizeof(uintptr_t));
339 DB(DW_CFA_offset|DW_REG_RA); DUV((sp_offset / sizeof(uintptr_t)) - 1);
340 }
341 }
342#endif
343 if (sp_adjustment && sp_adjustment > sp_offset) {
344 DB(DW_CFA_advance_loc|1); DB(DW_CFA_def_cfa_offset); DUV(sp_adjustment);
345#if defined(IR_TARGET_AARCH64)
346 if (!sp_offset) {
347 DB(DW_CFA_offset|DW_REG_X29); DUV(sp_adjustment / sizeof(uintptr_t));
348 DB(DW_CFA_offset|DW_REG_RA); DUV((sp_adjustment / sizeof(uintptr_t)) - 1);
349 }
350#endif
351 }
352 DALIGNNOP(sizeof(uintptr_t));
353 )
354
355 ctx->p = p;
356}
357
358static void ir_gdbjit_debuginfo(ir_gdbjit_ctx *ctx)
359{
360 uint8_t *p = ctx->p;
361
362 DSECT(info,
363 DU16(2); /* DWARF version. */
364 DU32(0); /* Abbrev offset. */
365 DB(sizeof(uintptr_t)); /* Pointer size. */
366
367 DUV(1); /* Abbrev #1: DW_TAG_compile_unit. */
368 DSTR(ctx->filename); /* DW_AT_name. */
369 DADDR(ctx->mcaddr); /* DW_AT_low_pc. */
370 DADDR(ctx->mcaddr + ctx->szmcode); /* DW_AT_high_pc. */
371 DU32(0); /* DW_AT_stmt_list. */
372 );
373
374 ctx->p = p;
375}
376
377static void ir_gdbjit_debugabbrev(ir_gdbjit_ctx *ctx)
378{
379 uint8_t *p = ctx->p;
380
381 /* Abbrev #1: DW_TAG_compile_unit. */
382 DUV(1);
393 DB(0);
394 DB(0);
395 DB(0);
396
397 ctx->p = p;
398}
399
400#define DLNE(op, s) (DB(DW_LNS_extended_op), DUV(1+(s)), DB((op)))
401
402static void ir_gdbjit_debugline(ir_gdbjit_ctx *ctx)
403{
404 uint8_t *p = ctx->p;
405
406 DSECT(line,
407 DU16(2); /* DWARF version. */
409 DB(1); /* Minimum instruction length. */
410 DB(1); /* is_stmt. */
411 DI8(0); /* Line base for special opcodes. */
412 DB(2); /* Line range for special opcodes. */
413 DB(3+1); /* Opcode base at DW_LNS_advance_line+1. */
414 DB(0); DB(1); DB(1); /* Standard opcode lengths. */
415 /* Directory table. */
416 DB(0);
417 /* File name table. */
418 DSTR(ctx->filename); DUV(0); DUV(0); DUV(0);
419 DB(0);
420 );
421 DLNE(DW_LNE_set_address, sizeof(uintptr_t));
422 DADDR(ctx->mcaddr);
423 if (ctx->lineno) (DB(DW_LNS_advance_line), DSV(ctx->lineno-1));
427 );
428
429 ctx->p = p;
430}
431
432
433#undef DLNE
434
435/* Undef shortcuts. */
436#undef DB
437#undef DI8
438#undef DU16
439#undef DU32
440#undef DADDR
441#undef DUV
442#undef DSV
443#undef DSTR
444#undef DALIGNNOP
445#undef DSECT
446
448
449static void ir_gdbjit_initsect(ir_gdbjit_ctx *ctx, int sect)
450{
451 ctx->startp = ctx->p;
452 ctx->obj.sect[sect].ofs = (uintptr_t)((char *)ctx->p - (char *)&ctx->obj);
453}
454
455static void ir_gdbjit_initsect_done(ir_gdbjit_ctx *ctx, int sect)
456{
457 ctx->obj.sect[sect].size = (uintptr_t)(ctx->p - ctx->startp);
458}
459
460static void ir_gdbjit_buildobj(ir_gdbjit_ctx *ctx, uint32_t sp_offset, uint32_t sp_adjustment)
461{
462 ir_gdbjit_obj *obj = &ctx->obj;
463
464 /* Fill in ELF header and clear structures. */
465 memcpy(&obj->hdr, &ir_elfhdr_template, sizeof(ir_elf_header));
466 memset(&obj->sect, 0, sizeof(ir_elf_sectheader) * GDBJIT_SECT__MAX);
467 memset(&obj->sym, 0, sizeof(ir_elf_symbol) * GDBJIT_SYM__MAX);
468
469 /* Initialize sections. */
470 ctx->p = obj->space;
471 ir_gdbjit_initsect(ctx, GDBJIT_SECT_shstrtab); ir_gdbjit_secthdr(ctx); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_shstrtab);
472 ir_gdbjit_initsect(ctx, GDBJIT_SECT_strtab); ir_gdbjit_symtab(ctx); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_strtab);
473 ir_gdbjit_initsect(ctx, GDBJIT_SECT_debug_info); ir_gdbjit_debuginfo(ctx); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_info);
474 ir_gdbjit_initsect(ctx, GDBJIT_SECT_debug_abbrev); ir_gdbjit_debugabbrev(ctx); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_abbrev);
475 ir_gdbjit_initsect(ctx, GDBJIT_SECT_debug_line); ir_gdbjit_debugline(ctx); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_line);
476 SECTALIGN(ctx->p, sizeof(uintptr_t));
477 ir_gdbjit_initsect(ctx, GDBJIT_SECT_eh_frame); ir_gdbjit_ehframe(ctx, sp_offset, sp_adjustment); ir_gdbjit_initsect_done(ctx, GDBJIT_SECT_eh_frame);
478 ctx->objsize = (size_t)((char *)ctx->p - (char *)obj);
479
480 IR_ASSERT(ctx->objsize < sizeof(ir_gdbjit_obj));
481}
482
483enum {
487};
488
495
502
503#ifdef IR_EXTERNAL_GDB_ENTRY
506#else
510
512{
513 __asm__ __volatile__("");
514}
515#endif
516
517static bool ir_gdb_register_code(const void *object, size_t size)
518{
520
521 entry = malloc(sizeof(ir_gdbjit_code_entry) + size);
522 if (entry == NULL) {
523 return 0;
524 }
525
526 entry->symfile_addr = ((char*)entry) + sizeof(ir_gdbjit_code_entry);
527 entry->symfile_size = size;
528
529 memcpy((char *)entry->symfile_addr, object, size);
530
531 entry->prev_entry = NULL;
532 entry->next_entry = __jit_debug_descriptor.first_entry;
533
534 if (entry->next_entry) {
535 entry->next_entry->prev_entry = entry;
536 }
537 __jit_debug_descriptor.first_entry = entry;
538
539 /* Notify GDB */
540 __jit_debug_descriptor.relevant_entry = entry;
543
544 return 1;
545}
546
548{
550
552 while ((entry = __jit_debug_descriptor.first_entry)) {
553 __jit_debug_descriptor.first_entry = entry->next_entry;
554 if (entry->next_entry) {
555 entry->next_entry->prev_entry = NULL;
556 }
557 /* Notify GDB */
558 __jit_debug_descriptor.relevant_entry = entry;
560
561 free(entry);
562 }
563}
564
565#if defined(__FreeBSD__)
566static bool ir_gdb_info_proc(pid_t pid, struct kinfo_proc *proc)
567{
568 size_t len, plen;
569 len = plen = sizeof(*proc);
570 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
571
572 if (sysctl(mib, 4, proc, &len, NULL, 0) < 0 || len != plen ||
573 proc->ki_structsize != (int)plen || proc->ki_pid != pid) {
574 return false;
575 }
576
577 return true;
578}
579#endif
580
582{
583 bool ret = 0;
584#if defined(__linux__) /* netbsd while having this procfs part, does not hold the tracer pid */
585 int fd = open("/proc/self/status", O_RDONLY);
586
587 if (fd > 0) {
588 char buf[1024];
589 ssize_t n = read(fd, buf, sizeof(buf) - 1);
590 char *s;
591 pid_t pid;
592
593 if (n > 0) {
594 buf[n] = 0;
595 s = strstr(buf, "TracerPid:");
596 if (s) {
597 s += sizeof("TracerPid:") - 1;
598 while (*s == ' ' || *s == '\t') {
599 s++;
600 }
601 pid = atoi(s);
602 if (pid) {
603 char out[1024];
604 snprintf(buf, sizeof(buf), "/proc/%d/exe", (int)pid);
605 if (readlink(buf, out, sizeof(out) - 1) > 0) {
606 if (strstr(out, "gdb")) {
607 ret = 1;
608 }
609 }
610 }
611 }
612 }
613
614 close(fd);
615 }
616#elif defined(__FreeBSD__)
617 struct kinfo_proc proc, dbg;
618
619 if (ir_gdb_info_proc(getpid(), &proc)) {
620 if ((proc.ki_flag & P_TRACED) != 0) {
621 if (ir_gdb_info_proc(proc.ki_tracer, &dbg)) {
622 ret = strstr(dbg.ki_comm, "gdb");
623 }
624 }
625 }
626#endif
627
628 return ret;
629}
630
631int ir_gdb_register(const char *name,
632 const void *start,
633 size_t size,
634 uint32_t sp_offset,
635 uint32_t sp_adjustment)
636{
637 ir_gdbjit_ctx ctx;
638
639 ctx.mcaddr = (uintptr_t)start;
640 ctx.szmcode = (uint32_t)size;
641 ctx.name = name;
642 ctx.filename = "unknown";
643 ctx.lineno = 0;
644
645 ir_gdbjit_buildobj(&ctx, sp_offset, sp_adjustment);
646
647 return ir_gdb_register_code(&ctx.obj, ctx.objsize);
648}
649
650void ir_gdb_init(void)
651{
652 /* This might enable registration of all JIT-ed code, but unfortunately,
653 * in case of many functions, this takes enormous time. */
654 if (ir_gdb_present()) {
655#if 0
656 _debug |= IR_DEBUG_GDB;
657#endif
658 }
659}
size_t len
Definition apprentice.c:174
readlink(string $path)
header(string $header, bool $replace=true, int $response_code=0)
strstr(string $haystack, string $needle, bool $before_needle=false)
char s[4]
Definition cdf.c:77
uint32_t v
Definition cdf.c:1237
zend_long n
Definition ffi.c:4979
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
buf start
Definition ffi.c:4687
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
#define IR_NEVER_INLINE
Definition ir.h:111
struct _ir_elf_header ir_elf_header
@ ELFSYM_BIND_GLOBAL
Definition ir_elf.h:98
@ ELFSYM_BIND_LOCAL
Definition ir_elf.h:97
#define ELFSECT_FLAGS_EXEC
Definition ir_elf.h:65
#define ELFSYM_INFO(bind, type)
Definition ir_elf.h:88
@ ELFSYM_TYPE_FILE
Definition ir_elf.h:93
@ ELFSYM_TYPE_FUNC
Definition ir_elf.h:92
#define ELFSECT_IDX_ABS
Definition ir_elf.h:53
#define ELFSECT_FLAGS_ALLOC
Definition ir_elf.h:64
#define DSV(x)
Definition ir_gdb.c:295
#define SECTALIGN(p, a)
Definition ir_gdb.c:285
struct _ir_gdbjit_descriptor ir_gdbjit_descriptor
struct _ir_gdbjit_ctx ir_gdbjit_ctx
@ IR_GDBJIT_UNREGISTER
Definition ir_gdb.c:486
@ IR_GDBJIT_REGISTER
Definition ir_gdb.c:485
@ IR_GDBJIT_NOACTION
Definition ir_gdb.c:484
struct _ir_gdbjit_code_entry ir_gdbjit_code_entry
struct _ir_gdbjit_obj ir_gdbjit_obj
#define DU16(x)
Definition ir_gdb.c:291
#define DSECT(name, stmt)
Definition ir_gdb.c:298
#define DB(x)
Definition ir_gdb.c:289
#define SECTDEF(id, tp, al)
int ir_gdb_register(const char *name, const void *start, size_t size, uint32_t sp_offset, uint32_t sp_adjustment)
Definition ir_gdb.c:631
IR_NEVER_INLINE void __jit_debug_register_code(void)
Definition ir_gdb.c:511
#define DU32(x)
Definition ir_gdb.c:292
#define DALIGNNOP(s)
Definition ir_gdb.c:297
#define DUV(x)
Definition ir_gdb.c:294
@ DW_EH_PE_textrel
Definition ir_gdb.c:41
@ DW_EH_PE_udata4
Definition ir_gdb.c:40
@ DW_CFA_offset_extended
Definition ir_gdb.c:31
@ DW_CFA_offset_extended_sf
Definition ir_gdb.c:34
@ DW_CFA_nop
Definition ir_gdb.c:30
@ DW_CFA_def_cfa
Definition ir_gdb.c:32
@ DW_CFA_offset
Definition ir_gdb.c:36
@ DW_CFA_def_cfa_offset
Definition ir_gdb.c:33
@ DW_CFA_advance_loc
Definition ir_gdb.c:35
@ DW_LNE_set_address
Definition ir_gdb.c:75
@ DW_LNE_end_sequence
Definition ir_gdb.c:74
void(* ir_gdbjit_initf)(ir_gdbjit_ctx *ctx)
Definition ir_gdb.c:447
@ DW_LNS_copy
Definition ir_gdb.c:68
@ DW_LNS_extended_op
Definition ir_gdb.c:67
@ DW_LNS_advance_pc
Definition ir_gdb.c:69
@ DW_LNS_advance_line
Definition ir_gdb.c:70
@ DW_TAG_compile_unit
Definition ir_gdb.c:45
void ir_gdb_unregister_all(void)
Definition ir_gdb.c:547
@ GDBJIT_SYM_UNDEF
Definition ir_gdb.c:113
@ GDBJIT_SYM_FUNC
Definition ir_gdb.c:115
@ GDBJIT_SYM_FILE
Definition ir_gdb.c:114
@ GDBJIT_SYM__MAX
Definition ir_gdb.c:116
@ DW_children_yes
Definition ir_gdb.c:50
@ DW_children_no
Definition ir_gdb.c:49
@ GDBJIT_SECT_strtab
Definition ir_gdb.c:104
@ GDBJIT_SECT__MAX
Definition ir_gdb.c:109
@ GDBJIT_SECT_debug_info
Definition ir_gdb.c:106
@ GDBJIT_SECT_NULL
Definition ir_gdb.c:100
@ GDBJIT_SECT_eh_frame
Definition ir_gdb.c:102
@ GDBJIT_SECT_symtab
Definition ir_gdb.c:105
@ GDBJIT_SECT_debug_line
Definition ir_gdb.c:108
@ GDBJIT_SECT_debug_abbrev
Definition ir_gdb.c:107
@ GDBJIT_SECT_shstrtab
Definition ir_gdb.c:103
@ GDBJIT_SECT_text
Definition ir_gdb.c:101
void ir_gdb_init(void)
Definition ir_gdb.c:650
@ DW_AT_high_pc
Definition ir_gdb.c:57
@ DW_AT_low_pc
Definition ir_gdb.c:56
@ DW_AT_name
Definition ir_gdb.c:54
@ DW_AT_stmt_list
Definition ir_gdb.c:55
#define DI8(x)
Definition ir_gdb.c:290
#define DLNE(op, s)
Definition ir_gdb.c:400
#define DADDR(x)
Definition ir_gdb.c:293
@ DW_FORM_string
Definition ir_gdb.c:63
@ DW_FORM_addr
Definition ir_gdb.c:61
@ DW_FORM_data4
Definition ir_gdb.c:62
bool ir_gdb_present(void)
Definition ir_gdb.c:581
#define DW_CIE_VERSION
Definition ir_gdb.c:26
#define DSTR(str)
Definition ir_gdb.c:296
#define IR_ASSERT(x)
Definition ir_private.h:17
#define IR_SET_ALIGNED(alignment, decl)
Definition ir_private.h:51
MYSQLND_DEBUG * dbg
Definition mysqlnd.h:300
int line
Definition php_ffi.h:54
unsigned const char * text
Definition php_ffi.h:53
#define offsetof(STRUCTURE, FIELD)
int fd
Definition phpdbg.h:282
p
Definition session.c:1105
Definition ir_gdb.c:489
struct _ir_gdbjit_code_entry * next_entry
Definition ir_gdb.c:490
const char * symfile_addr
Definition ir_gdb.c:492
struct _ir_gdbjit_code_entry * prev_entry
Definition ir_gdb.c:491
uint64_t symfile_size
Definition ir_gdb.c:493
const char * name
Definition ir_gdb.c:186
ir_gdbjit_obj obj
Definition ir_gdb.c:189
const char * filename
Definition ir_gdb.c:187
uint8_t * p
Definition ir_gdb.c:181
uint8_t * startp
Definition ir_gdb.c:182
uint32_t szmcode
Definition ir_gdb.c:184
uintptr_t mcaddr
Definition ir_gdb.c:183
size_t objsize
Definition ir_gdb.c:188
int32_t lineno
Definition ir_gdb.c:185
struct _ir_gdbjit_code_entry * relevant_entry
Definition ir_gdb.c:499
uint32_t action_flag
Definition ir_gdb.c:498
struct _ir_gdbjit_code_entry * first_entry
Definition ir_gdb.c:500
ir_elf_symbol sym[GDBJIT_SYM__MAX]
Definition ir_gdb.c:122
uint8_t space[4096]
Definition ir_gdb.c:123
ir_elf_header hdr
Definition ir_gdb.c:120
ir_elf_sectheader sect[GDBJIT_SECT__MAX]
Definition ir_gdb.c:121
uintptr_t ofs
Definition ir_elf.h:45
uintptr_t flags
Definition ir_elf.h:43
uintptr_t entsize
Definition ir_elf.h:50
uintptr_t size
Definition ir_elf.h:46
uint32_t info
Definition ir_elf.h:48
uint32_t link
Definition ir_elf.h:47
uintptr_t addr
Definition ir_elf.h:44
uint16_t sectidx
Definition ir_elf.h:82
uintptr_t value
Definition ir_elf.h:78
uint32_t name
Definition ir_elf.h:77
uint8_t info
Definition ir_elf.h:80
uint32_t size
Definition ir_elf.h:79
#define close(a)
#define snprintf
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API zend_gdbjit_descriptor __jit_debug_descriptor
Definition zend_gdb.c:53
zend_string * name
zval * ret
out($f, $s)