diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-12-22 18:17:49 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-22 11:17:49 +0100 |
| commit | 25b4dd1457ac5fc4a9921af1b098bdc78ace4d14 (patch) | |
| tree | ee61070d41ed7310808c7f7471d9314e48b3fb32 /src | |
| parent | ea13414083efaaec827bf78978c3c0656b0ebc1a (diff) | |
| download | box64-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.c | 82 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.c | 31 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.h | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_functions.c | 81 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.c | 82 | ||||
| -rw-r--r-- | src/tools/gdbjit.c | 1 |
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; } |