diff options
Diffstat (limited to 'src/lj_gdbjit.c')
-rw-r--r-- | src/lj_gdbjit.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index c2a9e901..a20d9ae2 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include "lj_err.h" | 14 | #include "lj_err.h" |
15 | #include "lj_debug.h" | 15 | #include "lj_debug.h" |
16 | #include "lj_frame.h" | 16 | #include "lj_frame.h" |
17 | #include "lj_buf.h" | ||
18 | #include "lj_strfmt.h" | ||
17 | #include "lj_jit.h" | 19 | #include "lj_jit.h" |
18 | #include "lj_dispatch.h" | 20 | #include "lj_dispatch.h" |
19 | 21 | ||
@@ -294,6 +296,9 @@ enum { | |||
294 | #elif LJ_TARGET_ARM | 296 | #elif LJ_TARGET_ARM |
295 | DW_REG_SP = 13, | 297 | DW_REG_SP = 13, |
296 | DW_REG_RA = 14, | 298 | DW_REG_RA = 14, |
299 | #elif LJ_TARGET_ARM64 | ||
300 | DW_REG_SP = 31, | ||
301 | DW_REG_RA = 30, | ||
297 | #elif LJ_TARGET_PPC | 302 | #elif LJ_TARGET_PPC |
298 | DW_REG_SP = 1, | 303 | DW_REG_SP = 1, |
299 | DW_REG_RA = 65, | 304 | DW_REG_RA = 65, |
@@ -372,6 +377,8 @@ static const ELFheader elfhdr_template = { | |||
372 | .machine = 62, | 377 | .machine = 62, |
373 | #elif LJ_TARGET_ARM | 378 | #elif LJ_TARGET_ARM |
374 | .machine = 40, | 379 | .machine = 40, |
380 | #elif LJ_TARGET_ARM64 | ||
381 | .machine = 183, | ||
375 | #elif LJ_TARGET_PPC | 382 | #elif LJ_TARGET_PPC |
376 | .machine = 20, | 383 | .machine = 20, |
377 | #elif LJ_TARGET_MIPS | 384 | #elif LJ_TARGET_MIPS |
@@ -428,16 +435,6 @@ static void gdbjit_catnum(GDBJITctx *ctx, uint32_t n) | |||
428 | *ctx->p++ = '0' + n; | 435 | *ctx->p++ = '0' + n; |
429 | } | 436 | } |
430 | 437 | ||
431 | /* Add a ULEB128 value. */ | ||
432 | static void gdbjit_uleb128(GDBJITctx *ctx, uint32_t v) | ||
433 | { | ||
434 | uint8_t *p = ctx->p; | ||
435 | for (; v >= 0x80; v >>= 7) | ||
436 | *p++ = (uint8_t)((v & 0x7f) | 0x80); | ||
437 | *p++ = (uint8_t)v; | ||
438 | ctx->p = p; | ||
439 | } | ||
440 | |||
441 | /* Add a SLEB128 value. */ | 438 | /* Add a SLEB128 value. */ |
442 | static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) | 439 | static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) |
443 | { | 440 | { |
@@ -454,7 +451,7 @@ static void gdbjit_sleb128(GDBJITctx *ctx, int32_t v) | |||
454 | #define DU16(x) (*(uint16_t *)p = (x), p += 2) | 451 | #define DU16(x) (*(uint16_t *)p = (x), p += 2) |
455 | #define DU32(x) (*(uint32_t *)p = (x), p += 4) | 452 | #define DU32(x) (*(uint32_t *)p = (x), p += 4) |
456 | #define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t)) | 453 | #define DADDR(x) (*(uintptr_t *)p = (x), p += sizeof(uintptr_t)) |
457 | #define DUV(x) (ctx->p = p, gdbjit_uleb128(ctx, (x)), p = ctx->p) | 454 | #define DUV(x) (p = (uint8_t *)lj_strfmt_wuleb128((char *)p, (x))) |
458 | #define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p) | 455 | #define DSV(x) (ctx->p = p, gdbjit_sleb128(ctx, (x)), p = ctx->p) |
459 | #define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p) | 456 | #define DSTR(str) (ctx->p = p, gdbjit_strz(ctx, (str)), p = ctx->p) |
460 | #define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop | 457 | #define DALIGNNOP(s) while ((uintptr_t)p & ((s)-1)) *p++ = DW_CFA_nop |
@@ -564,13 +561,20 @@ static void LJ_FASTCALL gdbjit_ehframe(GDBJITctx *ctx) | |||
564 | DB(DW_CFA_offset|DW_REG_15); DUV(4); | 561 | DB(DW_CFA_offset|DW_REG_15); DUV(4); |
565 | DB(DW_CFA_offset|DW_REG_14); DUV(5); | 562 | DB(DW_CFA_offset|DW_REG_14); DUV(5); |
566 | /* Extra registers saved for JIT-compiled code. */ | 563 | /* Extra registers saved for JIT-compiled code. */ |
567 | DB(DW_CFA_offset|DW_REG_13); DUV(9); | 564 | DB(DW_CFA_offset|DW_REG_13); DUV(LJ_GC64 ? 10 : 9); |
568 | DB(DW_CFA_offset|DW_REG_12); DUV(10); | 565 | DB(DW_CFA_offset|DW_REG_12); DUV(LJ_GC64 ? 11 : 10); |
569 | #elif LJ_TARGET_ARM | 566 | #elif LJ_TARGET_ARM |
570 | { | 567 | { |
571 | int i; | 568 | int i; |
572 | for (i = 11; i >= 4; i--) { DB(DW_CFA_offset|i); DUV(2+(11-i)); } | 569 | for (i = 11; i >= 4; i--) { DB(DW_CFA_offset|i); DUV(2+(11-i)); } |
573 | } | 570 | } |
571 | #elif LJ_TARGET_ARM64 | ||
572 | { | ||
573 | int i; | ||
574 | DB(DW_CFA_offset|31); DUV(2); | ||
575 | for (i = 28; i >= 19; i--) { DB(DW_CFA_offset|i); DUV(3+(28-i)); } | ||
576 | for (i = 15; i >= 8; i--) { DB(DW_CFA_offset|32|i); DUV(28-i); } | ||
577 | } | ||
574 | #elif LJ_TARGET_PPC | 578 | #elif LJ_TARGET_PPC |
575 | { | 579 | { |
576 | int i; | 580 | int i; |
@@ -727,6 +731,20 @@ static void gdbjit_buildobj(GDBJITctx *ctx) | |||
727 | 731 | ||
728 | /* -- Interface to GDB JIT API -------------------------------------------- */ | 732 | /* -- Interface to GDB JIT API -------------------------------------------- */ |
729 | 733 | ||
734 | static int gdbjit_lock; | ||
735 | |||
736 | static void gdbjit_lock_acquire() | ||
737 | { | ||
738 | while (__sync_lock_test_and_set(&gdbjit_lock, 1)) { | ||
739 | /* Just spin; futexes or pthreads aren't worth the portability cost. */ | ||
740 | } | ||
741 | } | ||
742 | |||
743 | static void gdbjit_lock_release() | ||
744 | { | ||
745 | __sync_lock_release(&gdbjit_lock); | ||
746 | } | ||
747 | |||
730 | /* Add new entry to GDB JIT symbol chain. */ | 748 | /* Add new entry to GDB JIT symbol chain. */ |
731 | static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) | 749 | static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) |
732 | { | 750 | { |
@@ -738,6 +756,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) | |||
738 | ctx->T->gdbjit_entry = (void *)eo; | 756 | ctx->T->gdbjit_entry = (void *)eo; |
739 | /* Link new entry to chain and register it. */ | 757 | /* Link new entry to chain and register it. */ |
740 | eo->entry.prev_entry = NULL; | 758 | eo->entry.prev_entry = NULL; |
759 | gdbjit_lock_acquire(); | ||
741 | eo->entry.next_entry = __jit_debug_descriptor.first_entry; | 760 | eo->entry.next_entry = __jit_debug_descriptor.first_entry; |
742 | if (eo->entry.next_entry) | 761 | if (eo->entry.next_entry) |
743 | eo->entry.next_entry->prev_entry = &eo->entry; | 762 | eo->entry.next_entry->prev_entry = &eo->entry; |
@@ -747,6 +766,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx) | |||
747 | __jit_debug_descriptor.relevant_entry = &eo->entry; | 766 | __jit_debug_descriptor.relevant_entry = &eo->entry; |
748 | __jit_debug_descriptor.action_flag = GDBJIT_REGISTER; | 767 | __jit_debug_descriptor.action_flag = GDBJIT_REGISTER; |
749 | __jit_debug_register_code(); | 768 | __jit_debug_register_code(); |
769 | gdbjit_lock_release(); | ||
750 | } | 770 | } |
751 | 771 | ||
752 | /* Add debug info for newly compiled trace and notify GDB. */ | 772 | /* Add debug info for newly compiled trace and notify GDB. */ |
@@ -778,6 +798,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T) | |||
778 | { | 798 | { |
779 | GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry; | 799 | GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry; |
780 | if (eo) { | 800 | if (eo) { |
801 | gdbjit_lock_acquire(); | ||
781 | if (eo->entry.prev_entry) | 802 | if (eo->entry.prev_entry) |
782 | eo->entry.prev_entry->next_entry = eo->entry.next_entry; | 803 | eo->entry.prev_entry->next_entry = eo->entry.next_entry; |
783 | else | 804 | else |
@@ -787,6 +808,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T) | |||
787 | __jit_debug_descriptor.relevant_entry = &eo->entry; | 808 | __jit_debug_descriptor.relevant_entry = &eo->entry; |
788 | __jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER; | 809 | __jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER; |
789 | __jit_debug_register_code(); | 810 | __jit_debug_register_code(); |
811 | gdbjit_lock_release(); | ||
790 | lj_mem_free(J2G(J), eo, eo->sz); | 812 | lj_mem_free(J2G(J), eo, eo->sz); |
791 | } | 813 | } |
792 | } | 814 | } |