about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-12-22 18:17:49 +0800
committerGitHub <noreply@github.com>2024-12-22 11:17:49 +0100
commit25b4dd1457ac5fc4a9921af1b098bdc78ace4d14 (patch)
treeee61070d41ed7310808c7f7471d9314e48b3fb32 /src
parentea13414083efaaec827bf78978c3c0656b0ebc1a (diff)
downloadbox64-25b4dd1457ac5fc4a9921af1b098bdc78ace4d14.tar.gz
box64-25b4dd1457ac5fc4a9921af1b098bdc78ace4d14.zip
[GDBJIT] Display register mapping annotations (#2185)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c82
-rw-r--r--src/dynarec/dynarec_native_functions.c31
-rw-r--r--src/dynarec/dynarec_native_functions.h7
-rw-r--r--src/dynarec/la64/dynarec_la64_functions.c81
-rw-r--r--src/dynarec/rv64/dynarec_rv64_functions.c82
-rw-r--r--src/tools/gdbjit.c1
6 files changed, 276 insertions, 8 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index 1bcfe663..020341d5 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -659,6 +659,79 @@ const char* getCacheName(int t, int n)
     return buff;
 }
 
+static register_mapping_t register_mappings[] = {
+    { "rax", "x10" },
+    { "eax", "w10" },
+    { "ax", "x10" },
+    { "ah", "x10" },
+    { "al", "x10" },
+    { "rcx", "x11" },
+    { "ecx", "w11" },
+    { "cx", "x11" },
+    { "ch", "x11" },
+    { "cl", "x11" },
+    { "rdx", "x12" },
+    { "edx", "w12" },
+    { "dx", "x12" },
+    { "dh", "x12" },
+    { "dl", "x12" },
+    { "rbx", "x13" },
+    { "ebx", "w13" },
+    { "bx", "x13" },
+    { "bh", "x13" },
+    { "bl", "x13" },
+    { "rsi", "x14" },
+    { "esi", "w14" },
+    { "si", "x14" },
+    { "sil", "x14" },
+    { "rdi", "x15" },
+    { "edi", "w15" },
+    { "di", "x15" },
+    { "dil", "x15" },
+    { "rsp", "x16" },
+    { "esp", "w16" },
+    { "sp", "x16" },
+    { "spl", "x16" },
+    { "rbp", "x17" },
+    { "ebp", "w17" },
+    { "bp", "x17" },
+    { "bpl", "x17" },
+    { "r8", "x18" },
+    { "r8d", "w18" },
+    { "r8w", "x18" },
+    { "r8b", "x18" },
+    { "r9", "x19" },
+    { "r9d", "w19" },
+    { "r9w", "x19" },
+    { "r9b", "x19" },
+    { "r10", "x20" },
+    { "r10d", "w20" },
+    { "r10w", "x20" },
+    { "r10b", "x20" },
+    { "r11", "x21" },
+    { "r11d", "w21" },
+    { "r11w", "x21" },
+    { "r11b", "x21" },
+    { "r12", "x22" },
+    { "r12d", "w22" },
+    { "r12w", "x22" },
+    { "r12b", "x22" },
+    { "r13", "x23" },
+    { "r13d", "w23" },
+    { "r13w", "x23" },
+    { "r13b", "x23" },
+    { "r14", "x24" },
+    { "r14d", "w24" },
+    { "r14w", "x24" },
+    { "r14b", "x24" },
+    { "r15", "x25" },
+    { "r15d", "w25" },
+    { "r15w", "x25" },
+    { "r15b", "x25" },
+    { "rip", "x27" },
+};
+
+
 void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
 {
     if (!box64_dynarec_dump && !box64_dynarec_gdbjit) return;
@@ -762,13 +835,18 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
             (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, ninst, buf, (box64_dynarec_dump > 1) ? "\e[m" : "");
     }
     if (box64_dynarec_gdbjit) {
+        static char buf2[512];
         if (box64_dynarec_gdbjit > 1) {
-            static char buf2[512];
             sprintf(buf2, "; %d: %d opcodes, %s", ninst, dyn->insts[ninst].size / 4, buf);
             dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), buf2);
         }
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
+        const char* inst_name = name;
+        if (dec) {
+            inst_name = DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0);
+            x64disas_add_register_mapping_annotations(buf2, inst_name, register_mappings, sizeof(register_mappings) / sizeof(register_mappings[0]));
+            inst_name = buf2;
+        }
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index 4b72ea01..683d8256 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -669,4 +669,33 @@ void propagate_nodf(dynarec_native_t* dyn, int ninst)
         dyn->insts[ninst].df_notneeded = 1;
         --ninst;       
     }
-}
\ No newline at end of file
+}
+
+void x64disas_add_register_mapping_annotations(char* buf, const char* disas, const register_mapping_t* mappings, size_t mappings_sz)
+{
+    static char tmp[32];
+    tmp[0] = '\0';
+    int len = 0;
+    // skip the mnemonic
+    char* p = strchr(disas, ' ');
+    if (!p) {
+        sprintf(buf, "%s", disas);
+        return;
+    }
+    p++; // skip the space
+    while (*p) {
+        while (*p && !(*p >= 'a' && *p <= 'e') && *p != 's' && *p != 'r') // skip non-register characters
+            p++;
+        if (!*p) break;
+        for (int i = 0; i < mappings_sz; ++i) {
+            if (!strncmp(p, mappings[i].name, strlen(mappings[i].name))) {
+                len += sprintf(tmp + len, " %s,", mappings[i].native);
+                p += strlen(mappings[i].name) - 1;
+                break;
+            }
+        }
+        p++;
+        }
+    if (tmp[0]) tmp[strlen(tmp) - 1] = '\0';
+    sprintf(buf, "%-35s ;%s", disas, tmp);
+}
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index 827a02a4..1fad8ef1 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -83,6 +83,13 @@ int is_avx_zero_unset(dynarec_native_t* dyn, int ninst, int reg);
 void avx_mark_zero_reset(dynarec_native_t* dyn, int ninst);
 void avx_unmark_zero(dynarec_native_t* dyn, int ninst, int reg);
 
+typedef struct register_mapping_s {
+    const char* name;
+    const char* native;
+} register_mapping_t;
+
+void x64disas_add_register_mapping_annotations(char* buf, const char* disas, const register_mapping_t* mappings, size_t mappings_sz);
+
 ADDITIONNAL_DEFINITION()
 
 #endif //__DYNAREC_NATIVE_FUNCTIONS_H__
diff --git a/src/dynarec/la64/dynarec_la64_functions.c b/src/dynarec/la64/dynarec_la64_functions.c
index ecb08e85..02735625 100644
--- a/src/dynarec/la64/dynarec_la64_functions.c
+++ b/src/dynarec/la64/dynarec_la64_functions.c
@@ -257,6 +257,78 @@ const char* getCacheName(int t, int n)
     return buff;
 }
 
+static register_mapping_t register_mappings[] = {
+    { "rax", "t0" },
+    { "eax", "t0" },
+    { "ax", "t0" },
+    { "ah", "t0" },
+    { "al", "t0" },
+    { "rcx", "t1" },
+    { "ecx", "t1" },
+    { "cx", "t1" },
+    { "ch", "t1" },
+    { "cl", "t1" },
+    { "rdx", "t2" },
+    { "edx", "t2" },
+    { "dx", "t2" },
+    { "dh", "t2" },
+    { "dl", "t2" },
+    { "rbx", "t3" },
+    { "ebx", "t3" },
+    { "bx", "t3" },
+    { "bh", "t3" },
+    { "bl", "t3" },
+    { "rsi", "t4" },
+    { "esi", "t4" },
+    { "si", "t4" },
+    { "sil", "t4" },
+    { "rdi", "t5" },
+    { "edi", "t5" },
+    { "di", "t5" },
+    { "dil", "t5" },
+    { "rsp", "t6" },
+    { "esp", "t6" },
+    { "sp", "t6" },
+    { "spl", "t6" },
+    { "rbp", "t7" },
+    { "ebp", "t7" },
+    { "bp", "t7" },
+    { "bpl", "t7" },
+    { "r8", "s0" },
+    { "r8d", "s0" },
+    { "r8w", "s0" },
+    { "r8b", "s0" },
+    { "r9", "s1" },
+    { "r9d", "s1" },
+    { "r9w", "s1" },
+    { "r9b", "s1" },
+    { "r10", "s2" },
+    { "r10d", "s2" },
+    { "r10w", "s2" },
+    { "r10b", "s2" },
+    { "r11", "s3" },
+    { "r11d", "s3" },
+    { "r11w", "s3" },
+    { "r11b", "s3" },
+    { "r12", "s4" },
+    { "r12d", "s4" },
+    { "r12w", "s4" },
+    { "r12b", "s4" },
+    { "r13", "s5" },
+    { "r13d", "s5" },
+    { "r13w", "s5" },
+    { "r13b", "s5" },
+    { "r14", "s6" },
+    { "r14d", "s6" },
+    { "r14w", "s6" },
+    { "r14b", "s6" },
+    { "r15", "s7" },
+    { "r15d", "s7" },
+    { "r15w", "s7" },
+    { "r15b", "s7" },
+    { "rip", "t8" },
+};
+
 void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
 {
     if (!box64_dynarec_dump && !box64_dynarec_gdbjit) return;
@@ -310,13 +382,18 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
             (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, ninst, buf, (box64_dynarec_dump > 1) ? "\e[m" : "");
     }
     if (box64_dynarec_gdbjit) {
+        static char buf2[512];
         if (box64_dynarec_gdbjit > 1) {
-            static char buf2[512];
             sprintf(buf2, "; %d: %d opcodes, %s", ninst, dyn->insts[ninst].size / 4, buf);
             dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), buf2);
         }
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
+        const char* inst_name = name;
+        if (dec) {
+            inst_name = DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0);
+            x64disas_add_register_mapping_annotations(buf2, inst_name, register_mappings, sizeof(register_mappings) / sizeof(register_mappings[0]));
+            inst_name = buf2;
+        }
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c
index d1fd158d..b26b2aad 100644
--- a/src/dynarec/rv64/dynarec_rv64_functions.c
+++ b/src/dynarec/rv64/dynarec_rv64_functions.c
@@ -623,6 +623,79 @@ const char* getCacheName(int t, int n)
     return buff;
 }
 
+static register_mapping_t register_mappings[] = {
+    { "rax", "a6" },
+    { "eax", "a6" },
+    { "ax", "a6" },
+    { "ah", "a6" },
+    { "al", "a6" },
+    { "rcx", "a3" },
+    { "ecx", "a3" },
+    { "cx", "a3" },
+    { "ch", "a3" },
+    { "cl", "a3" },
+    { "rdx", "a2" },
+    { "edx", "a2" },
+    { "dx", "a2" },
+    { "dh", "a2" },
+    { "dl", "a2" },
+    { "rbx", "s8" },
+    { "ebx", "s8" },
+    { "bx", "s8" },
+    { "bh", "s8" },
+    { "bl", "s8" },
+    { "rsi", "a1" },
+    { "esi", "a1" },
+    { "si", "a1" },
+    { "sil", "a1" },
+    { "rdi", "a0" },
+    { "edi", "a0" },
+    { "di", "a0" },
+    { "dil", "a0" },
+    { "rsp", "s1" },
+    { "esp", "s1" },
+    { "sp", "s1" },
+    { "spl", "s1" },
+    { "rbp", "s0" },
+    { "ebp", "s0" },
+    { "bp", "s0" },
+    { "bpl", "s0" },
+    { "r8", "a4" },
+    { "r8d", "a4" },
+    { "r8w", "a4" },
+    { "r8b", "a4" },
+    { "r9", "a5" },
+    { "r9d", "a5" },
+    { "r9w", "a5" },
+    { "r9b", "a5" },
+    { "r10", "s10" },
+    { "r10d", "s10" },
+    { "r10w", "s10" },
+    { "r10b", "s10" },
+    { "r11", "s11" },
+    { "r11d", "s11" },
+    { "r11w", "s11" },
+    { "r11b", "s11" },
+    { "r12", "s2" },
+    { "r12d", "s2" },
+    { "r12w", "s2" },
+    { "r12b", "s2" },
+    { "r13", "s3" },
+    { "r13d", "s3" },
+    { "r13w", "s3" },
+    { "r13b", "s3" },
+    { "r14", "s4" },
+    { "r14d", "s4" },
+    { "r14w", "s4" },
+    { "r14b", "s4" },
+    { "r15", "s5" },
+    { "r15d", "s5" },
+    { "r15w", "s5" },
+    { "r15b", "s5" },
+    { "rip", "s6" },
+};
+
+
 void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
 {
     if (!box64_dynarec_dump && !box64_dynarec_gdbjit) return;
@@ -685,13 +758,18 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
             (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, ninst, buf, (box64_dynarec_dump > 1) ? "\e[m" : "");
     }
     if (box64_dynarec_gdbjit) {
+        static char buf2[512];
         if (box64_dynarec_gdbjit > 1) {
-            static char buf2[512];
             sprintf(buf2, "; %d: %d opcodes, %s", ninst, dyn->insts[ninst].size / 4, buf);
             dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), buf2);
         }
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
+        const char* inst_name = name;
+        if (dec) {
+            inst_name = DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0);
+            x64disas_add_register_mapping_annotations(buf2, inst_name, register_mappings, sizeof(register_mappings) / sizeof(register_mappings[0]));
+            inst_name = buf2;
+        }
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/tools/gdbjit.c b/src/tools/gdbjit.c
index a1ae725f..07731e9f 100644
--- a/src/tools/gdbjit.c
+++ b/src/tools/gdbjit.c
@@ -95,7 +95,6 @@ gdbjit_block_t* GdbJITBlockAddLine(gdbjit_block_t* block, GDB_CORE_ADDR addr, co
     block->lines[block->nlines-1].pc = addr;
     block->lines[block->nlines-1].line = block->nlines;
     fprintf(block->file, "%s\n", line);
-    fflush(block->file);
     return block;
 }