]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
gdb: LoongArch: Improve loongarch_scan_prologue for correct backtrace
authorHui Li <lihui@loongson.cn>
Tue, 26 Aug 2025 01:45:57 +0000 (09:45 +0800)
committerTiezhu Yang <yangtiezhu@loongson.cn>
Tue, 26 Aug 2025 13:58:36 +0000 (21:58 +0800)
commitaa2b674af942a4d9defa1a1d53707684dd393095
tree43f36c9bf0642f987f1542090a37269dcdc3c05e
parentab31109c8a9a5543c3448b98c640eb56fccc6d07
gdb: LoongArch: Improve loongarch_scan_prologue for correct backtrace

(1) Description of Problem:

When debugging the following code, the execution result of
the backtrace command is incorrect.

$ cat test.S
.text
.globl fun1
.type fun1, @function
fun1:
or $r12,$r0,$r0
or $r4,$r12,$r0
jr $r1
.globl fun
.type fun, @function
fun:
addi.d $r3,$r3,-16
st.d $r1,$r3,8
bl fun1
or $r12,$r4,$r0
or $r4,$r12,$r0
ld.d $r1,$r3,8
addi.d $r3,$r3,16
jr $r1
.globl main
.type main, @function
main:
addi.d $r3,$r3,-16
st.d $r1,$r3,8
bl fun
nop
ld.d $r1,$r3,8
addi.d $r3,$r3,16
jr $r1
$ gcc test.S -o test
$ gdb test
...
(gdb) b fun1
Breakpoint 1 at 0x748
(gdb) r
Breakpoint 1, 0x0000555555554748 in fun1 ()
(gdb) bt
  #0  0x0000555555554748 in fun1 ()
  #1  0x0000555555554758 in fun ()
  #2  0x0000555555554758 in fun ()
  #3  0x0000555555554758 in fun ()
....
--Type <RET> for more, q to quit, c to continue without paging

(2) Root Cause Analysis:

The return address of fun() in r1(ra) is saved on the stack:

addi.d $r3,$r3,-16
st.d $r1,$r3,8

The bl instruction in fun () will call the fun1 () and save
the value of pc+4 to r1(ra).

bl fun1
or $r12,$r4,$r0

Because registers such as fp and ra saved in the stack of the sub-function
are not recorded in current code. When trace back fun() to main(), the pc
of the previous frame to be read from ra register instead of the saved location
on the stack. At this time, the value of ra register in fun() is already the
address of the next instruction after the bl. So it is impossible to trace
back to the main().

(3) Solution:

Record the location of ra, fp, s0 to s8 on the stack to ensure the correct
execution of backtrace.

(4) Test:

$ gdb test
...
(gdb) b fun1
Breakpoint 1 at 0x748
(gdb) r
Breakpoint 1, 0x0000555555554748 in fun1 ()
(gdb) bt
  #0  0x0000555555554748 in fun1 ()
  #1  0x0000555555554758 in fun ()
  #2  0x0000555555554778 in main ()

Signed-off-by: Hui Li <lihui@loongson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
gdb/loongarch-tdep.c