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) */
29 enum {
30 DW_CFA_nop = 0x0,
31 DW_CFA_offset_extended = 0x5,
32 DW_CFA_def_cfa = 0xc,
33 DW_CFA_def_cfa_offset = 0xe,
34 DW_CFA_offset_extended_sf = 0x11,
35 DW_CFA_advance_loc = 0x40,
36 DW_CFA_offset = 0x80
37 };
38
39 enum {
40 DW_EH_PE_udata4 = 0x03,
41 DW_EH_PE_textrel = 0x20
42 };
43
44 enum {
45 DW_TAG_compile_unit = 0x11
46 };
47
48 enum {
49 DW_children_no = 0,
50 DW_children_yes = 1
51 };
52
53 enum {
54 DW_AT_name = 0x03,
55 DW_AT_stmt_list = 0x10,
56 DW_AT_low_pc = 0x11,
57 DW_AT_high_pc = 0x12
58 };
59
60 enum {
61 DW_FORM_addr = 0x01,
62 DW_FORM_data4 = 0x06,
63 DW_FORM_string = 0x08
64 };
65
66 enum {
67 DW_LNS_extended_op = 0,
68 DW_LNS_copy = 1,
69 DW_LNS_advance_pc = 2,
70 DW_LNS_advance_line = 3
71 };
72
73 enum {
74 DW_LNE_end_sequence = 1,
75 DW_LNE_set_address = 2
76 };
77
78 enum {
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
99 enum {
100 GDBJIT_SECT_NULL,
101 GDBJIT_SECT_text,
102 GDBJIT_SECT_eh_frame,
103 GDBJIT_SECT_shstrtab,
104 GDBJIT_SECT_strtab,
105 GDBJIT_SECT_symtab,
106 GDBJIT_SECT_debug_info,
107 GDBJIT_SECT_debug_abbrev,
108 GDBJIT_SECT_debug_line,
109 GDBJIT_SECT__MAX
110 };
111
112 enum {
113 GDBJIT_SYM_UNDEF,
114 GDBJIT_SYM_FILE,
115 GDBJIT_SYM_FUNC,
116 GDBJIT_SYM__MAX
117 };
118
119 typedef struct _ir_gdbjit_obj {
120 ir_elf_header hdr;
121 ir_elf_sectheader sect[GDBJIT_SECT__MAX];
122 ir_elf_symbol sym[GDBJIT_SYM__MAX];
123 uint8_t space[4096];
124 } ir_gdbjit_obj;
125
126 static 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. */
180 typedef 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. */
190 } ir_gdbjit_ctx;
191
192 /* Add a zero-terminated string */
ir_gdbjit_strz(ir_gdbjit_ctx * ctx,const char * str)193 static 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 */
ir_gdbjit_uleb128(ir_gdbjit_ctx * ctx,uint32_t v)205 static 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 */
ir_gdbjit_sleb128(ir_gdbjit_ctx * ctx,int32_t v)215 static 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
ir_gdbjit_secthdr(ir_gdbjit_ctx * ctx)224 static 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);
237 sect->flags = ELFSECT_FLAGS_ALLOC|ELFSECT_FLAGS_EXEC;
238 sect->addr = ctx->mcaddr;
239 sect->ofs = 0;
240 sect->size = ctx->szmcode;
241
242 SECTDEF(eh_frame, PROGBITS, sizeof(uintptr_t));
243 sect->flags = ELFSECT_FLAGS_ALLOC;
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
ir_gdbjit_symtab(ir_gdbjit_ctx * ctx)262 static 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");
270 sym->sectidx = ELFSECT_IDX_ABS;
271 sym->info = ELFSYM_INFO(ELFSYM_BIND_LOCAL, ELFSYM_TYPE_FILE);
272
273 sym = &ctx->obj.sym[GDBJIT_SYM_FUNC];
274 sym->name = ir_gdbjit_strz(ctx, ctx->name);
275 sym->sectidx = GDBJIT_SECT_text;
276 sym->value = 0;
277 sym->size = ctx->szmcode;
278 sym->info = ELFSYM_INFO(ELFSYM_BIND_GLOBAL, ELFSYM_TYPE_FUNC);
279 }
280
281 typedef IR_SET_ALIGNED(1, uint16_t unaligned_uint16_t);
282 typedef IR_SET_ALIGNED(1, uint32_t unaligned_uint32_t);
283 typedef 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
ir_gdbjit_ehframe(ir_gdbjit_ctx * ctx,uint32_t sp_offset,uint32_t sp_adjustment)302 static 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
ir_gdbjit_debuginfo(ir_gdbjit_ctx * ctx)358 static 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
ir_gdbjit_debugabbrev(ir_gdbjit_ctx * ctx)377 static 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);
383 DUV(DW_TAG_compile_unit);
384 DB(DW_children_no);
385 DUV(DW_AT_name);
386 DUV(DW_FORM_string);
387 DUV(DW_AT_low_pc);
388 DUV(DW_FORM_addr);
389 DUV(DW_AT_high_pc);
390 DUV(DW_FORM_addr);
391 DUV(DW_AT_stmt_list);
392 DUV(DW_FORM_data4);
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
ir_gdbjit_debugline(ir_gdbjit_ctx * ctx)402 static void ir_gdbjit_debugline(ir_gdbjit_ctx *ctx)
403 {
404 uint8_t *p = ctx->p;
405
406 DSECT(line,
407 DU16(2); /* DWARF version. */
408 DSECT(header,
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));
424 DB(DW_LNS_copy);
425 DB(DW_LNS_advance_pc); DUV(ctx->szmcode);
426 DLNE(DW_LNE_end_sequence, 0);
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
447 typedef void (*ir_gdbjit_initf) (ir_gdbjit_ctx *ctx);
448
ir_gdbjit_initsect(ir_gdbjit_ctx * ctx,int sect)449 static 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
ir_gdbjit_initsect_done(ir_gdbjit_ctx * ctx,int sect)455 static 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
ir_gdbjit_buildobj(ir_gdbjit_ctx * ctx,uint32_t sp_offset,uint32_t sp_adjustment)460 static 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
483 enum {
484 IR_GDBJIT_NOACTION,
485 IR_GDBJIT_REGISTER,
486 IR_GDBJIT_UNREGISTER
487 };
488
489 typedef struct _ir_gdbjit_code_entry {
490 struct _ir_gdbjit_code_entry *next_entry;
491 struct _ir_gdbjit_code_entry *prev_entry;
492 const char *symfile_addr;
493 uint64_t symfile_size;
494 } ir_gdbjit_code_entry;
495
496 typedef struct _ir_gdbjit_descriptor {
497 uint32_t version;
498 uint32_t action_flag;
499 struct _ir_gdbjit_code_entry *relevant_entry;
500 struct _ir_gdbjit_code_entry *first_entry;
501 } ir_gdbjit_descriptor;
502
503 #ifdef IR_EXTERNAL_GDB_ENTRY
504 extern ir_gdbjit_descriptor __jit_debug_descriptor;
505 void __jit_debug_register_code(void);
506 #else
507 ir_gdbjit_descriptor __jit_debug_descriptor = {
508 1, IR_GDBJIT_NOACTION, NULL, NULL
509 };
510
__jit_debug_register_code(void)511 IR_NEVER_INLINE void __jit_debug_register_code(void)
512 {
513 __asm__ __volatile__("");
514 }
515 #endif
516
ir_gdb_register_code(const void * object,size_t size)517 static bool ir_gdb_register_code(const void *object, size_t size)
518 {
519 ir_gdbjit_code_entry *entry;
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;
541 __jit_debug_descriptor.action_flag = IR_GDBJIT_REGISTER;
542 __jit_debug_register_code();
543
544 return 1;
545 }
546
ir_gdb_unregister_all(void)547 void ir_gdb_unregister_all(void)
548 {
549 ir_gdbjit_code_entry *entry;
550
551 __jit_debug_descriptor.action_flag = IR_GDBJIT_UNREGISTER;
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;
559 __jit_debug_register_code();
560
561 free(entry);
562 }
563 }
564
565 #if defined(__FreeBSD__)
ir_gdb_info_proc(pid_t pid,struct kinfo_proc * proc)566 static 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
ir_gdb_present(void)581 bool ir_gdb_present(void)
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
ir_gdb_register(const char * name,const void * start,size_t size,uint32_t sp_offset,uint32_t sp_adjustment)631 int 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
ir_gdb_init(void)650 void 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 }
660