zend_jit_gdb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend JIT |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | https://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Dmitry Stogov <dmitry@php.net> |
  16. | Xinchen Hui <laruence@php.net> |
  17. +----------------------------------------------------------------------+
  18. | Based on Mike Pall's implementation of GDB interface for LuaJIT. |
  19. | LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ |
  20. +----------------------------------------------------------------------+
  21. */
  22. #define HAVE_GDB
  23. #include "zend_jit_gdb.h"
  24. #include "zend_elf.h"
  25. #include "zend_gdb.h"
  26. /* DWARF definitions. */
  27. #define DW_CIE_VERSION 1
  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. enum {
  39. DW_EH_PE_udata4 = 0x03,
  40. DW_EH_PE_textrel = 0x20
  41. };
  42. enum {
  43. DW_TAG_compile_unit = 0x11
  44. };
  45. enum {
  46. DW_children_no = 0,
  47. DW_children_yes = 1
  48. };
  49. enum {
  50. DW_AT_name = 0x03,
  51. DW_AT_stmt_list = 0x10,
  52. DW_AT_low_pc = 0x11,
  53. DW_AT_high_pc = 0x12
  54. };
  55. enum {
  56. DW_FORM_addr = 0x01,
  57. DW_FORM_data4 = 0x06,
  58. DW_FORM_string = 0x08
  59. };
  60. enum {
  61. DW_LNS_extended_op = 0,
  62. DW_LNS_copy = 1,
  63. DW_LNS_advance_pc = 2,
  64. DW_LNS_advance_line = 3
  65. };
  66. enum {
  67. DW_LNE_end_sequence = 1,
  68. DW_LNE_set_address = 2
  69. };
  70. enum {
  71. #if defined(__i386__)
  72. DW_REG_AX, DW_REG_CX, DW_REG_DX, DW_REG_BX,
  73. DW_REG_SP, DW_REG_BP, DW_REG_SI, DW_REG_DI,
  74. DW_REG_RA,
  75. #elif defined(__x86_64__)
  76. /* Yes, the order is strange, but correct. */
  77. DW_REG_AX, DW_REG_DX, DW_REG_CX, DW_REG_BX,
  78. DW_REG_SI, DW_REG_DI, DW_REG_BP, DW_REG_SP,
  79. DW_REG_8, DW_REG_9, DW_REG_10, DW_REG_11,
  80. DW_REG_12, DW_REG_13, DW_REG_14, DW_REG_15,
  81. DW_REG_RA,
  82. #elif defined(__aarch64__)
  83. DW_REG_SP = 31,
  84. DW_REG_RA = 30,
  85. DW_REG_X29 = 29,
  86. #else
  87. #error "Unsupported target architecture"
  88. #endif
  89. };
  90. enum {
  91. GDBJIT_SECT_NULL,
  92. GDBJIT_SECT_text,
  93. GDBJIT_SECT_eh_frame,
  94. GDBJIT_SECT_shstrtab,
  95. GDBJIT_SECT_strtab,
  96. GDBJIT_SECT_symtab,
  97. GDBJIT_SECT_debug_info,
  98. GDBJIT_SECT_debug_abbrev,
  99. GDBJIT_SECT_debug_line,
  100. GDBJIT_SECT__MAX
  101. };
  102. enum {
  103. GDBJIT_SYM_UNDEF,
  104. GDBJIT_SYM_FILE,
  105. GDBJIT_SYM_FUNC,
  106. GDBJIT_SYM__MAX
  107. };
  108. typedef struct _zend_gdbjit_obj {
  109. zend_elf_header hdr;
  110. zend_elf_sectheader sect[GDBJIT_SECT__MAX];
  111. zend_elf_symbol sym[GDBJIT_SYM__MAX];
  112. uint8_t space[4096];
  113. } zend_gdbjit_obj;
  114. static const zend_elf_header zend_elfhdr_template = {
  115. .emagic = { 0x7f, 'E', 'L', 'F' },
  116. #ifdef ELF64
  117. .eclass = 2,
  118. #else
  119. .eclass = 1,
  120. #endif
  121. #ifdef WORDS_BIGENDIAN
  122. .eendian = 2,
  123. #else
  124. .eendian = 1,
  125. #endif
  126. .eversion = 1,
  127. #if defined(Linux)
  128. .eosabi = 0, /* Nope, it's not 3. ??? */
  129. #elif defined(__FreeBSD__)
  130. .eosabi = 9,
  131. #elif defined(__OpenBSD__)
  132. .eosabi = 12,
  133. #elif defined(__NetBSD__)
  134. .eosabi = 2,
  135. #elif defined(__DragonFly__)
  136. .eosabi = 0,
  137. #elif (defined(__sun__) && defined(__svr4__))
  138. .eosabi = 6,
  139. #else
  140. .eosabi = 0,
  141. #endif
  142. .eabiversion = 0,
  143. .epad = { 0, 0, 0, 0, 0, 0, 0 },
  144. .type = 1,
  145. #if defined(__i386__)
  146. .machine = 3,
  147. #elif defined(__x86_64__)
  148. .machine = 62,
  149. #elif defined(__aarch64__)
  150. .machine = 183,
  151. #else
  152. # error "Unsupported target architecture"
  153. #endif
  154. .version = 1,
  155. .entry = 0,
  156. .phofs = 0,
  157. .shofs = offsetof(zend_gdbjit_obj, sect),
  158. .flags = 0,
  159. .ehsize = sizeof(zend_elf_header),
  160. .phentsize = 0,
  161. .phnum = 0,
  162. .shentsize = sizeof(zend_elf_sectheader),
  163. .shnum = GDBJIT_SECT__MAX,
  164. .shstridx = GDBJIT_SECT_shstrtab
  165. };
  166. /* Context for generating the ELF object for the GDB JIT API. */
  167. typedef struct _zend_gdbjit_ctx {
  168. uint8_t *p; /* Pointer to next address in obj.space. */
  169. uint8_t *startp; /* Pointer to start address in obj.space. */
  170. uintptr_t mcaddr; /* Machine code address. */
  171. uint32_t szmcode; /* Size of machine code. */
  172. int32_t lineno; /* Starting line number. */
  173. const char *name; /* JIT function name */
  174. const char *filename; /* Starting file name. */
  175. size_t objsize; /* Final size of ELF object. */
  176. zend_gdbjit_obj obj; /* In-memory ELF object. */
  177. } zend_gdbjit_ctx;
  178. /* Add a zero-terminated string */
  179. static uint32_t zend_gdbjit_strz(zend_gdbjit_ctx *ctx, const char *str)
  180. {
  181. uint8_t *p = ctx->p;
  182. uint32_t ofs = (uint32_t)(p - ctx->startp);
  183. do {
  184. *p++ = (uint8_t)*str;
  185. } while (*str++);
  186. ctx->p = p;
  187. return ofs;
  188. }
  189. /* Add a ULEB128 value */
  190. static void zend_gdbjit_uleb128(zend_gdbjit_ctx *ctx, uint32_t v)
  191. {
  192. uint8_t *p = ctx->p;
  193. for (; v >= 0x80; v >>= 7)
  194. *p++ = (uint8_t)((v & 0x7f) | 0x80);
  195. *p++ = (uint8_t)v;
  196. ctx->p = p;
  197. }
  198. /* Add a SLEB128 value */
  199. static void zend_gdbjit_sleb128(zend_gdbjit_ctx *ctx, int32_t v)
  200. {
  201. uint8_t *p = ctx->p;
  202. for (; (uint32_t)(v+0x40) >= 0x80; v >>= 7)
  203. *p++ = (uint8_t)((v & 0x7f) | 0x80);
  204. *p++ = (uint8_t)(v & 0x7f);
  205. ctx->p = p;
  206. }
  207. static void zend_gdbjit_secthdr(zend_gdbjit_ctx *ctx)
  208. {
  209. zend_elf_sectheader *sect;
  210. *ctx->p++ = '\0';
  211. #define SECTDEF(id, tp, al) \
  212. sect = &ctx->obj.sect[GDBJIT_SECT_##id]; \
  213. sect->name = zend_gdbjit_strz(ctx, "." #id); \
  214. sect->type = ELFSECT_TYPE_##tp; \
  215. sect->align = (al)
  216. SECTDEF(text, NOBITS, 16);
  217. sect->flags = ELFSECT_FLAGS_ALLOC|ELFSECT_FLAGS_EXEC;
  218. sect->addr = ctx->mcaddr;
  219. sect->ofs = 0;
  220. sect->size = ctx->szmcode;
  221. SECTDEF(eh_frame, PROGBITS, sizeof(uintptr_t));
  222. sect->flags = ELFSECT_FLAGS_ALLOC;
  223. SECTDEF(shstrtab, STRTAB, 1);
  224. SECTDEF(strtab, STRTAB, 1);
  225. SECTDEF(symtab, SYMTAB, sizeof(uintptr_t));
  226. sect->ofs = offsetof(zend_gdbjit_obj, sym);
  227. sect->size = sizeof(ctx->obj.sym);
  228. sect->link = GDBJIT_SECT_strtab;
  229. sect->entsize = sizeof(zend_elf_symbol);
  230. sect->info = GDBJIT_SYM_FUNC;
  231. SECTDEF(debug_info, PROGBITS, 1);
  232. SECTDEF(debug_abbrev, PROGBITS, 1);
  233. SECTDEF(debug_line, PROGBITS, 1);
  234. #undef SECTDEF
  235. }
  236. static void zend_gdbjit_symtab(zend_gdbjit_ctx *ctx)
  237. {
  238. zend_elf_symbol *sym;
  239. *ctx->p++ = '\0';
  240. sym = &ctx->obj.sym[GDBJIT_SYM_FILE];
  241. sym->name = zend_gdbjit_strz(ctx, "JIT code");
  242. sym->sectidx = ELFSECT_IDX_ABS;
  243. sym->info = ELFSYM_INFO(ELFSYM_BIND_LOCAL, ELFSYM_TYPE_FILE);
  244. sym = &ctx->obj.sym[GDBJIT_SYM_FUNC];
  245. sym->name = zend_gdbjit_strz(ctx, ctx->name);
  246. sym->sectidx = GDBJIT_SECT_text;
  247. sym->value = 0;
  248. sym->size = ctx->szmcode;
  249. sym->info = ELFSYM_INFO(ELFSYM_BIND_GLOBAL, ELFSYM_TYPE_FUNC);
  250. }
  251. typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t);
  252. typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t);
  253. typedef ZEND_SET_ALIGNED(1, uintptr_t unaligned_uintptr_t);
  254. #define SECTALIGN(p, a) \
  255. ((p) = (uint8_t *)(((uintptr_t)(p) + ((a)-1)) & ~(uintptr_t)((a)-1)))
  256. /* Shortcuts to generate DWARF structures. */
  257. #define DB(x) (*p++ = (x))
  258. #define DI8(x) (*(int8_t *)p = (x), p++)
  259. #define DU16(x) (*(unaligned_uint16_t *)p = (x), p += 2)
  260. #define DU32(x) (*(unaligned_uint32_t *)p = (x), p += 4)
  261. #define DADDR(x) (*(unaligned_uintptr_t *)p = (x), p += sizeof(uintptr_t))
  262. #define DUV(x) (ctx->p = p, zend_gdbjit_uleb128(ctx, (x)), p = ctx->p)
  263. #define DSV(x) (ctx->p = p, zend_gdbjit_sleb128(ctx, (x)), p = ctx->p)
  264. #define DSTR(str) (ctx->p = p, zend_gdbjit_strz(ctx, (str)), p = ctx->p)
  265. #define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop
  266. #define DSECT(name, stmt) \
  267. { unaligned_uint32_t *szp_##name = (uint32_t *)p; p += 4; stmt \
  268. *szp_##name = (uint32_t)((p-(uint8_t *)szp_##name)-4); }
  269. static void zend_gdbjit_ehframe(zend_gdbjit_ctx *ctx, uint32_t sp_offset, uint32_t sp_adjustment)
  270. {
  271. uint8_t *p = ctx->p;
  272. uint8_t *framep = p;
  273. /* DWARF EH CIE (Common Information Entry) */
  274. DSECT(CIE,
  275. DU32(0); /* CIE ID. */
  276. DB(DW_CIE_VERSION); /* Version */
  277. DSTR("zR"); /* Augmentation String. */
  278. DUV(1); /* Code alignment factor. */
  279. DSV(-(int32_t)sizeof(uintptr_t)); /* Data alignment factor. */
  280. DB(DW_REG_RA); /* Return address register. */
  281. DB(1); DB(DW_EH_PE_textrel|DW_EH_PE_udata4); /* Augmentation data. */
  282. #if defined(__x86_64__) || defined(i386)
  283. DB(DW_CFA_def_cfa); DUV(DW_REG_SP); DUV(sizeof(uintptr_t));
  284. DB(DW_CFA_offset|DW_REG_RA); DUV(1);
  285. #elif defined(__aarch64__)
  286. DB(DW_CFA_def_cfa); DUV(DW_REG_SP); DUV(0);
  287. #endif
  288. DALIGNNOP(sizeof(uintptr_t));
  289. )
  290. /* DWARF EH FDE (Frame Description Entry). */
  291. DSECT(FDE,
  292. DU32((uint32_t)(p-framep)); /* Offset to CIE Pointer. */
  293. DU32(0); /* Machine code offset relative to .text. */
  294. DU32(ctx->szmcode); /* Machine code length. */
  295. DB(0); /* Augmentation data. */
  296. DB(DW_CFA_def_cfa_offset); DUV(sp_offset);
  297. #if defined(__aarch64__)
  298. if (sp_offset) {
  299. if (sp_adjustment && sp_adjustment < sp_offset) {
  300. DB(DW_CFA_offset|DW_REG_X29); DUV(sp_adjustment / sizeof(uintptr_t));
  301. DB(DW_CFA_offset|DW_REG_RA); DUV((sp_adjustment / sizeof(uintptr_t)) - 1);
  302. } else {
  303. DB(DW_CFA_offset|DW_REG_X29); DUV(sp_offset / sizeof(uintptr_t));
  304. DB(DW_CFA_offset|DW_REG_RA); DUV((sp_offset / sizeof(uintptr_t)) - 1);
  305. }
  306. }
  307. #endif
  308. if (sp_adjustment && sp_adjustment > sp_offset) {
  309. DB(DW_CFA_advance_loc|1); DB(DW_CFA_def_cfa_offset); DUV(sp_adjustment);
  310. #if defined(__aarch64__)
  311. if (!sp_offset) {
  312. DB(DW_CFA_offset|DW_REG_X29); DUV(sp_adjustment / sizeof(uintptr_t));
  313. DB(DW_CFA_offset|DW_REG_RA); DUV((sp_adjustment / sizeof(uintptr_t)) - 1);
  314. }
  315. #endif
  316. }
  317. DALIGNNOP(sizeof(uintptr_t));
  318. )
  319. ctx->p = p;
  320. }
  321. static void zend_gdbjit_debuginfo(zend_gdbjit_ctx *ctx)
  322. {
  323. uint8_t *p = ctx->p;
  324. DSECT(info,
  325. DU16(2); /* DWARF version. */
  326. DU32(0); /* Abbrev offset. */
  327. DB(sizeof(uintptr_t)); /* Pointer size. */
  328. DUV(1); /* Abbrev #1: DW_TAG_compile_unit. */
  329. DSTR(ctx->filename); /* DW_AT_name. */
  330. DADDR(ctx->mcaddr); /* DW_AT_low_pc. */
  331. DADDR(ctx->mcaddr + ctx->szmcode); /* DW_AT_high_pc. */
  332. DU32(0); /* DW_AT_stmt_list. */
  333. );
  334. ctx->p = p;
  335. }
  336. static void zend_gdbjit_debugabbrev(zend_gdbjit_ctx *ctx)
  337. {
  338. uint8_t *p = ctx->p;
  339. /* Abbrev #1: DW_TAG_compile_unit. */
  340. DUV(1);
  341. DUV(DW_TAG_compile_unit);
  342. DB(DW_children_no);
  343. DUV(DW_AT_name);
  344. DUV(DW_FORM_string);
  345. DUV(DW_AT_low_pc);
  346. DUV(DW_FORM_addr);
  347. DUV(DW_AT_high_pc);
  348. DUV(DW_FORM_addr);
  349. DUV(DW_AT_stmt_list);
  350. DUV(DW_FORM_data4);
  351. DB(0);
  352. DB(0);
  353. ctx->p = p;
  354. }
  355. #define DLNE(op, s) (DB(DW_LNS_extended_op), DUV(1+(s)), DB((op)))
  356. static void zend_gdbjit_debugline(zend_gdbjit_ctx *ctx)
  357. {
  358. uint8_t *p = ctx->p;
  359. DSECT(line,
  360. DU16(2); /* DWARF version. */
  361. DSECT(header,
  362. DB(1); /* Minimum instruction length. */
  363. DB(1); /* is_stmt. */
  364. DI8(0); /* Line base for special opcodes. */
  365. DB(2); /* Line range for special opcodes. */
  366. DB(3+1); /* Opcode base at DW_LNS_advance_line+1. */
  367. DB(0); DB(1); DB(1); /* Standard opcode lengths. */
  368. /* Directory table. */
  369. DB(0);
  370. /* File name table. */
  371. DSTR(ctx->filename); DUV(0); DUV(0); DUV(0);
  372. DB(0);
  373. );
  374. DLNE(DW_LNE_set_address, sizeof(uintptr_t));
  375. DADDR(ctx->mcaddr);
  376. if (ctx->lineno) (DB(DW_LNS_advance_line), DSV(ctx->lineno-1));
  377. DB(DW_LNS_copy);
  378. DB(DW_LNS_advance_pc); DUV(ctx->szmcode);
  379. DLNE(DW_LNE_end_sequence, 0);
  380. );
  381. ctx->p = p;
  382. }
  383. #undef DLNE
  384. /* Undef shortcuts. */
  385. #undef DB
  386. #undef DI8
  387. #undef DU16
  388. #undef DU32
  389. #undef DADDR
  390. #undef DUV
  391. #undef DSV
  392. #undef DSTR
  393. #undef DALIGNNOP
  394. #undef DSECT
  395. typedef void (*zend_gdbjit_initf) (zend_gdbjit_ctx *ctx);
  396. static void zend_gdbjit_initsect(zend_gdbjit_ctx *ctx, int sect)
  397. {
  398. ctx->startp = ctx->p;
  399. ctx->obj.sect[sect].ofs = (uintptr_t)((char *)ctx->p - (char *)&ctx->obj);
  400. }
  401. static void zend_gdbjit_initsect_done(zend_gdbjit_ctx *ctx, int sect)
  402. {
  403. ctx->obj.sect[sect].size = (uintptr_t)(ctx->p - ctx->startp);
  404. }
  405. static void zend_gdbjit_buildobj(zend_gdbjit_ctx *ctx, uint32_t sp_offset, uint32_t sp_adjustment)
  406. {
  407. zend_gdbjit_obj *obj = &ctx->obj;
  408. /* Fill in ELF header and clear structures. */
  409. memcpy(&obj->hdr, &zend_elfhdr_template, sizeof(zend_elf_header));
  410. memset(&obj->sect, 0, sizeof(zend_elf_sectheader) * GDBJIT_SECT__MAX);
  411. memset(&obj->sym, 0, sizeof(zend_elf_symbol) * GDBJIT_SYM__MAX);
  412. /* Initialize sections. */
  413. ctx->p = obj->space;
  414. zend_gdbjit_initsect(ctx, GDBJIT_SECT_shstrtab); zend_gdbjit_secthdr(ctx); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_shstrtab);
  415. zend_gdbjit_initsect(ctx, GDBJIT_SECT_strtab); zend_gdbjit_symtab(ctx); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_strtab);
  416. zend_gdbjit_initsect(ctx, GDBJIT_SECT_debug_info); zend_gdbjit_debuginfo(ctx); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_info);
  417. zend_gdbjit_initsect(ctx, GDBJIT_SECT_debug_abbrev); zend_gdbjit_debugabbrev(ctx); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_abbrev);
  418. zend_gdbjit_initsect(ctx, GDBJIT_SECT_debug_line); zend_gdbjit_debugline(ctx); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_debug_line);
  419. SECTALIGN(ctx->p, sizeof(uintptr_t));
  420. zend_gdbjit_initsect(ctx, GDBJIT_SECT_eh_frame); zend_gdbjit_ehframe(ctx, sp_offset, sp_adjustment); zend_gdbjit_initsect_done(ctx, GDBJIT_SECT_eh_frame);
  421. ctx->objsize = (size_t)((char *)ctx->p - (char *)obj);
  422. ZEND_ASSERT(ctx->objsize < sizeof(zend_gdbjit_obj));
  423. }
  424. int zend_jit_gdb_register(const char *name,
  425. const zend_op_array *op_array,
  426. const void *start,
  427. size_t size,
  428. uint32_t sp_offset,
  429. uint32_t sp_adjustment)
  430. {
  431. zend_gdbjit_ctx ctx;
  432. ctx.mcaddr = (uintptr_t)start;
  433. ctx.szmcode = (uint32_t)size;
  434. ctx.name = name;
  435. ctx.filename = op_array ? ZSTR_VAL(op_array->filename) : "unknown";
  436. ctx.lineno = op_array ? op_array->line_start : 0;
  437. zend_gdbjit_buildobj(&ctx, sp_offset, sp_adjustment);
  438. return zend_gdb_register_code(&ctx.obj, ctx.objsize);
  439. }
  440. int zend_jit_gdb_unregister(void)
  441. {
  442. zend_gdb_unregister_all();
  443. return 1;
  444. }
  445. void zend_jit_gdb_init(void)
  446. {
  447. #if 0
  448. /* This might enable registration of all JIT-ed code, but unfortunately,
  449. * in case of many functions, this takes enormous time. */
  450. if (zend_gdb_present()) {
  451. JIT_G(debug) |= ZEND_JIT_DEBUG_GDB;
  452. }
  453. #endif
  454. }