File gdb-tdep-fix-recording-of-t1-push.patch of Package gdb
From 0494211cb5f418654ca3a4ac1b9f10518426732f Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 13 Nov 2024 19:44:21 +0100
Subject: [PATCH 15/46] [gdb/tdep] Fix recording of T1 push
When running test-case gdb.reverse/recursion.exp on arm-linux with target
board unix/-mthumb, I run into:
...
(gdb) PASS: gdb.reverse/recursion.exp: Skipping recursion from inside
reverse-next^M
bar (x=4195569) at /home/linux/gdb/src/gdb/testsuite/gdb.reverse/recursion.c:34^M
34 int r = foo (x);^M
(gdb) FAIL: gdb.reverse/recursion.exp: print frame when stepping out
...
The problem is the recording of the T1 push instruction [1,2], specifically:
...
000004d8 <foo>:
4d8: b580 push {r7, lr}
...
The current code fails to add a memory record for the memory written with the
value of the lr register.
Fix this by adding the missing memory record.
Tested on arm-linux.
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Approved-By: Luis Machado <luis.machado@arm.com>
[1] https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Encoding-of-lists-of-ARM-core-registers
[2] https://developer.arm.com/documentation/ddi0597/2024-09/T32-Instructions-by-Encoding/16-bit?lang=en#pushpop16
---
gdb/arm-tdep.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index f36ce631a08..d898a426609 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -13561,9 +13561,12 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r)
record_buf[0] = bits (thumb_insn_r->arm_insn, 0, 2);
thumb_insn_r->reg_rec_count = 1;
break;
- case 4: /* fall through */
case 5:
- /* PUSH. */
+ /* PUSH with lr. */
+ register_count++;
+ [[fallthrough]];
+ case 4:
+ /* PUSH without lr. */
register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM, &u_regval);
while (register_bits)
@@ -13572,8 +13575,7 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r)
register_count++;
register_bits = register_bits >> 1;
}
- start_address = u_regval - \
- (4 * (bit (thumb_insn_r->arm_insn, 8) + register_count));
+ start_address = u_regval - (4 * register_count);
thumb_insn_r->mem_rec_count = register_count;
while (register_count)
{
--
2.43.0