From eb1b9fca9ca66d051179d8d2f35edb4624118b26 Mon Sep 17 00:00:00 2001 From: wanglei Date: Fri, 20 Dec 2024 09:03:08 +0800 Subject: [PATCH] [lldb][LoongArch] Fix the incorrect floating-point register dwarf number According to the documentation described at https://github.com/loongson/la-abi-specs/blob/release/ladwarf.adoc, the dwarf numbers for floating-point registers range from 32 to 63. An incorrect dwarf number will prevent the register values from being properly restored during unwinding. This test reflects this problem: ``` loongson@linux:~$ cat test.c void foo() { asm volatile ("movgr2fr.d $fs2, $ra":::"$fs2"); } int main() { asm volatile ("movgr2fr.d $fs2, $sp":::"$fs2"); foo(); return 0; } loongson@linux:~$ clang -g test.c -o test ``` Without this patch: ``` loongson@linux:~$ ./_build/bin/lldb ./t (lldb) target create "./t" Current executable set to '/home/loongson/llvm-project/_build_lldb/t' (loongarch64). (lldb) b foo Breakpoint 1: where = t`foo + 20 at test.c:4:1, address = 0x0000000000000714 (lldb) r Process 2455626 launched: '/home/loongson/llvm-project/_build_lldb/t' (loongarch64) Process 2455626 stopped * thread #1, name = 't', stop reason = breakpoint 1.1 frame #0: 0x0000555555554714 t`foo at test.c:4:1 1 #include 2 3 void foo() { -> 4 asm volatile ("movgr2fr.d $fs2, $ra":::"$fs2"); 5 } 6 int main() { 7 asm volatile ("movgr2fr.d $fs2, $sp":::"$fs2"); (lldb) si Process 2455626 stopped * thread #1, name = 't', stop reason = instruction step into frame #0: 0x0000555555554718 t`foo at test.c:4:1 1 #include 2 3 void foo() { -> 4 asm volatile ("movgr2fr.d $fs2, $ra":::"$fs2"); 5 } 6 int main() { 7 asm volatile ("movgr2fr.d $fs2, $sp":::"$fs2"); (lldb) f 1 frame #1: 0x0000555555554768 t`main at test.c:8:1 5 } 6 int main() { 7 asm volatile ("movgr2fr.d $fs2, $sp":::"$fs2"); -> 8 foo(); 9 return 0; 10 } (lldb) register read -a General Purpose Registers: r1 = 0x0000555555554768 t`main + 40 at test.c:8:1 r3 = 0x00007ffffffef780 r22 = 0x00007ffffffef7b0 r23 = 0x00007ffffffef918 r24 = 0x0000000000000001 r25 = 0x0000000000000000 r26 = 0x000055555555be08 t`__do_global_dtors_aux_fini_array_entry r27 = 0x0000555555554740 t`main at test.c:6 r28 = 0x00007ffffffef928 r29 = 0x00007ffff7febc88 ld-linux-loongarch-lp64d.so.1`_rtld_global_ro r30 = 0x000055555555be08 t`__do_global_dtors_aux_fini_array_entry pc = 0x0000555555554768 t`main + 40 at test.c:8:1 33 registers were unavailable. Floating Point Registers: f13 = 0x00007ffffffef780 !!!!! wrong register f24 = 0xffffffffffffffff f25 = 0xffffffffffffffff f26 = 0x0000555555554768 t`main + 40 at test.c:8:1 f27 = 0xffffffffffffffff f28 = 0xffffffffffffffff f29 = 0xffffffffffffffff f30 = 0xffffffffffffffff f31 = 0xffffffffffffffff 32 registers were unavailable. ``` With this patch: ``` The previous operations are the same. (lldb) register read -a General Purpose Registers: r1 = 0x0000555555554768 t`main + 40 at test.c:8:1 r3 = 0x00007ffffffef780 r22 = 0x00007ffffffef7b0 r23 = 0x00007ffffffef918 r24 = 0x0000000000000001 r25 = 0x0000000000000000 r26 = 0x000055555555be08 t`__do_global_dtors_aux_fini_array_entry r27 = 0x0000555555554740 t`main at test.c:6 r28 = 0x00007ffffffef928 r29 = 0x00007ffff7febc88 ld-linux-loongarch-lp64d.so.1`_rtld_global_ro r30 = 0x000055555555be08 t`__do_global_dtors_aux_fini_array_entry pc = 0x0000555555554768 t`main + 40 at test.c:8:1 33 registers were unavailable. Floating Point Registers: f24 = 0xffffffffffffffff f25 = 0xffffffffffffffff f26 = 0x00007ffffffef780 f27 = 0xffffffffffffffff f28 = 0xffffffffffffffff f29 = 0xffffffffffffffff f30 = 0xffffffffffffffff f31 = 0xffffffffffffffff 33 registers were unavailable. ``` Reviewed By: SixWeining Pull Request: https://github.com/llvm/llvm-project/pull/120391 --- .../Utility/LoongArch_DWARF_Registers.h | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lldb/source/Utility/LoongArch_DWARF_Registers.h b/lldb/source/Utility/LoongArch_DWARF_Registers.h index 34e40a066051ee..596806348ee245 100644 --- a/lldb/source/Utility/LoongArch_DWARF_Registers.h +++ b/lldb/source/Utility/LoongArch_DWARF_Registers.h @@ -47,22 +47,7 @@ enum { dwarf_gpr_r30, dwarf_gpr_r31 = 31, - dwarf_gpr_orig_a0, - dwarf_gpr_pc, - dwarf_gpr_badv, - - dwarf_gpr_reserved0 = 35, - dwarf_gpr_reserved1, - dwarf_gpr_reserved2, - dwarf_gpr_reserved3, - dwarf_gpr_reserved4, - dwarf_gpr_reserved5, - dwarf_gpr_reserved6, - dwarf_gpr_reserved7, - dwarf_gpr_reserved8, - dwarf_gpr_reserved9, - - dwarf_fpr_f0 = 45, + dwarf_fpr_f0 = 32, dwarf_fpr_f1, dwarf_fpr_f2, dwarf_fpr_f3, @@ -93,7 +78,7 @@ enum { dwarf_fpr_f28, dwarf_fpr_f29, dwarf_fpr_f30, - dwarf_fpr_f31 = 76, + dwarf_fpr_f31 = 63, dwarf_fpr_fcc0, dwarf_fpr_fcc1, @@ -170,6 +155,23 @@ enum { dwarf_fpr_fs5 = dwarf_fpr_f29, dwarf_fpr_fs6 = dwarf_fpr_f30, dwarf_fpr_fs7 = dwarf_fpr_f31, + + // mock pc regnum + dwarf_gpr_pc = 57005, + + // fake registers are only used to define `RegisterInfo` + dwarf_gpr_orig_a0, + dwarf_gpr_badv, + dwarf_gpr_reserved0, + dwarf_gpr_reserved1, + dwarf_gpr_reserved2, + dwarf_gpr_reserved3, + dwarf_gpr_reserved4, + dwarf_gpr_reserved5, + dwarf_gpr_reserved6, + dwarf_gpr_reserved7, + dwarf_gpr_reserved8, + dwarf_gpr_reserved9, }; } // namespace loongarch_dwarf