about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-05-09 16:21:41 +0800
committerGitHub <noreply@github.com>2025-05-09 10:21:41 +0200
commit22fdc90fe28171e3e7566684f60305a4f2d04dcf (patch)
tree8e0c1ded237fa62b6cf9dd56455a9338d5db5fd0 /src
parent78193c5f1acb4fd0311bbf96ed0f692016d6e350 (diff)
downloadbox64-22fdc90fe28171e3e7566684f60305a4f2d04dcf.tar.gz
box64-22fdc90fe28171e3e7566684f60305a4f2d04dcf.zip
[GDBJIT] Added a new option to register debuginfo only after trapped into signalhandler (#2614)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynablock_private.h3
-rw-r--r--src/dynarec/dynarec_native.c6
-rw-r--r--src/include/gdbjit.h2
-rw-r--r--src/libtools/signals.c4
-rw-r--r--src/tools/env.c2
-rw-r--r--src/tools/gdbjit.c19
6 files changed, 24 insertions, 12 deletions
diff --git a/src/dynarec/dynablock_private.h b/src/dynarec/dynablock_private.h
index 388fcc4d..8220be0c 100644
--- a/src/dynarec/dynablock_private.h
+++ b/src/dynarec/dynablock_private.h
@@ -31,6 +31,9 @@ typedef struct dynablock_s {
     void*           arch;       // arch dependant per inst info (can be NULL)
     callret_t*      callrets;   // array of callret return, with NOP / UDF depending if the block is clean or dirty
     void*           jmpnext;    // a branch jmpnext code when block is marked
+    #ifdef GDBJIT
+    void*           gdbjit_block;
+    #endif
 } dynablock_t;
 
 #endif //__DYNABLOCK_PRIVATE_H_
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 1de71094..9ea02962 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -886,7 +886,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
     block->x64_size = end-start;
     // all done...
     if (BOX64ENV(dynarec_gdbjit) && (!BOX64ENV(dynarec_gdbjit_end) || (addr >= BOX64ENV(dynarec_gdbjit_start) && addr < BOX64ENV(dynarec_gdbjit_end)))) {
-        GdbJITBlockReady(helper.gdbjit_block);
+        if (BOX64ENV(dynarec_gdbjit) != 3) GdbJITBlockReady(helper.gdbjit_block);
+        GdbJITBlockCleanup(helper.gdbjit_block);
+        #ifdef GDBJIT
+        block->gdbjit_block = helper.gdbjit_block;
+        #endif
     }
     ClearCache(actual_p+sizeof(void*), native_size);   // need to clear the cache before execution...
     block->hash = X31_hash_code(block->x64_addr, block->x64_size);
diff --git a/src/include/gdbjit.h b/src/include/gdbjit.h
index 40f1ad58..f8cb9714 100644
--- a/src/include/gdbjit.h
+++ b/src/include/gdbjit.h
@@ -21,12 +21,14 @@ typedef struct gdbjit_block_s {
 void GdbJITNewBlock(gdbjit_block_t* block, GDB_CORE_ADDR start, GDB_CORE_ADDR end, uintptr_t x64start);
 gdbjit_block_t* GdbJITBlockAddLine(gdbjit_block_t* block, GDB_CORE_ADDR addr, const char* line);
 void GdbJITBlockReady(gdbjit_block_t* block);
+void GdbJITBlockCleanup(gdbjit_block_t* block);
 
 #else
 
 #define GdbJITNewBlock(a, b, c, d)
 #define GdbJITBlockAddLine(a, b, c) NULL
 #define GdbJITBlockReady(a)
+#define GdbJITBlockCleanup(a)
 
 #endif
 
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 36e57104..de77a29c 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -40,6 +40,7 @@
 #include "../dynarec/dynablock_private.h"
 #include "dynarec_native.h"
 #include "dynarec/dynarec_arch.h"
+#include "gdbjit.h"
 #endif
 
 
@@ -2064,6 +2065,9 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "%04d|Repeated SIGSEGV with Access error on %
             static const char* seg_name[] = {"ES", "CS", "SS", "DS", "FS", "GS"};
             int shown_regs = 0;
 #ifdef DYNAREC
+            #ifdef GDBJIT
+            if(db && BOX64ENV(dynarec_gdbjit) == 3) GdbJITBlockReady(db->gdbjit_block);
+            #endif
             uint32_t hash = 0;
             if(db)
                 hash = X31_hash_code(db->x64_addr, db->x64_size);
diff --git a/src/tools/env.c b/src/tools/env.c
index 16c4b194..95012386 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -138,7 +138,7 @@ static void applyCustomRules()
 
     if (box64env.is_dynarec_gdbjit_str_overridden) {
         if (strlen(box64env.dynarec_gdbjit_str) == 1) {
-            if (box64env.dynarec_gdbjit_str[0] >= '0' && box64env.dynarec_gdbjit_str[0] <= '2')
+            if (box64env.dynarec_gdbjit_str[0] >= '0' && box64env.dynarec_gdbjit_str[0] <= '3')
                 box64env.dynarec_gdbjit = box64env.dynarec_gdbjit_str[0] - '0';
 
             box64env.dynarec_gdbjit_start = 0x0;
diff --git a/src/tools/gdbjit.c b/src/tools/gdbjit.c
index 5813f562..f1a3b0ce 100644
--- a/src/tools/gdbjit.c
+++ b/src/tools/gdbjit.c
@@ -98,22 +98,21 @@ gdbjit_block_t* GdbJITBlockAddLine(gdbjit_block_t* block, GDB_CORE_ADDR addr, co
     return block;
 }
 
+void GdbJITBlockCleanup(gdbjit_block_t* block) {
+    if (block && block->file) {
+        fclose(block->file);
+        block->file = NULL;
+    }
+}
+
 void GdbJITBlockReady(gdbjit_block_t* block)
 {
     if (!block) return;
 
-    if (block->nlines == 0) {
-        fclose(block->file);
-        return;
-    }
+    if (block->nlines == 0) return;
 
     gdbjit_code_entry_t* entry = (gdbjit_code_entry_t*)box_malloc(sizeof(gdbjit_code_entry_t));
-    if (!entry) {
-        fclose(block->file);
-        return;
-    }
-
-    fclose(block->file);
+    if (!entry) return;
 
     entry->symfile_addr = (const char*)block;
     entry->symfile_size = sizeof(gdbjit_block_t) + block->nlines * sizeof(struct gdb_line_mapping);