Message ID | 20230119104618.15503-4-tdevries@suse.de |
---|---|
State | Committed |
Headers |
Return-Path: <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 808B4385B513 for <patchwork@sourceware.org>; Thu, 19 Jan 2023 10:46:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 808B4385B513 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1674125206; bh=lzo28Hz/G3X51TIg6UAD/kGcnroG0zrSuECkuNpugY8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=DX3GJRXHP0FsTbJazL7kT062+pmAS33D3hECtCStETpbDwGEbv7GEHkLnR/AoIeug MpTje/gI2Q7KrRZ505mWglAuptLruAv5ds9QqcU7KnAK8DV1LNhkNajZitzS/eYZnU kGoCsQx0WAr1rg5CeHWe2Mnd+KaRx3etSpMzF1pY= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id 448983858C00 for <gdb-patches@sourceware.org>; Thu, 19 Jan 2023 10:46:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 448983858C00 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 8183F5CC63; Thu, 19 Jan 2023 10:46:19 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 61890139ED; Thu, 19 Jan 2023 10:46:19 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id iHu4FnsfyWOMJwAAMHmgww (envelope-from <tdevries@suse.de>); Thu, 19 Jan 2023 10:46:19 +0000 To: gdb-patches@sourceware.org Cc: Bruno Larsen <blarsen@redhat.com>, Andrew Burgess <aburgess@redhat.com>, Luis Machado <luis.machado@arm.com> Subject: [PATCH 3/4] [gdb/tdep, aarch64] Fix frame address of last insn in leaf function Date: Thu, 19 Jan 2023 11:46:17 +0100 Message-Id: <20230119104618.15503-4-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230119104618.15503-1-tdevries@suse.de> References: <20230119104618.15503-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list <gdb-patches.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=subscribe> From: Tom de Vries via Gdb-patches <gdb-patches@sourceware.org> Reply-To: Tom de Vries <tdevries@suse.de> Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" <gdb-patches-bounces+patchwork=sourceware.org@sourceware.org> |
Series |
Test-case gdb.base/unwind-on-each-insn.exp improvements
|
|
Commit Message
Tom de Vries
Jan. 19, 2023, 10:46 a.m. UTC
Consider the test-case test.c, compiled without debug info: ... void foo (const char *s) { } int main (void) { foo ("foo"); return 0; } ... Disassembly of foo: ... 0000000000400564 <foo>: 400564: d10043ff sub sp, sp, #0x10 400568: f90007e0 str x0, [sp, #8] 40056c: d503201f nop 400570: 910043ff add sp, sp, #0x10 400574: d65f03c0 ret ... Now, let's do "info frame" at each insn in foo, as well as printing $sp and $x29 (and strip the output of info frame to the first line, for brevity): ... $ gdb -q a.out Reading symbols from a.out... (gdb) b *foo Breakpoint 1 at 0x400564 (gdb) r Starting program: a.out Breakpoint 1, 0x0000000000400564 in foo () (gdb) display /x $sp 1: /x $sp = 0xfffffffff3a0 (gdb) display /x $x29 2: /x $x29 = 0xfffffffff3a0 (gdb) info frame Stack level 0, frame at 0xfffffffff3a0: (gdb) si 0x0000000000400568 in foo () 1: /x $sp = 0xfffffffff390 2: /x $x29 = 0xfffffffff3a0 (gdb) info frame Stack level 0, frame at 0xfffffffff3a0: (gdb) si 0x000000000040056c in foo () 1: /x $sp = 0xfffffffff390 2: /x $x29 = 0xfffffffff3a0 (gdb) info frame Stack level 0, frame at 0xfffffffff3a0: (gdb) si 0x0000000000400570 in foo () 1: /x $sp = 0xfffffffff390 2: /x $x29 = 0xfffffffff3a0 (gdb) info frame Stack level 0, frame at 0xfffffffff3a0: (gdb) si 0x0000000000400574 in foo () 1: /x $sp = 0xfffffffff3a0 2: /x $x29 = 0xfffffffff3a0 (gdb) info frame Stack level 0, frame at 0xfffffffff3b0: pc = 0x400574 in foo; saved pc = 0x40058c (gdb) si 0x000000000040058c in main () 1: /x $sp = 0xfffffffff3a0 2: /x $x29 = 0xfffffffff3a0 ... The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it lists 0xfffffffff3b0. The frame address is calculated here in aarch64_make_prologue_cache_1: ... unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg); if (unwound_fp == 0) return; cache->prev_sp = unwound_fp + cache->framesize; ... For insns after the prologue, we have cache->framereg == sp and cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong answer once sp has been restored to entry value by the before-last insn. Fix this by detecting the situation that the sp has been restored. This fixes PR tdep/30011. This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721. Tested on aarch64-linux. PR tdep/30011 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30011 --- gdb/aarch64-tdep.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Comments
On 1/19/23 11:46, Tom de Vries via Gdb-patches wrote: > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c > index b576d3b9d99..06349353716 100644 > --- a/gdb/aarch64-tdep.c > +++ b/gdb/aarch64-tdep.c > @@ -996,7 +996,11 @@ aarch64_make_prologue_cache_1 (frame_info_ptr this_frame, > if (unwound_fp == 0) > return; > > - cache->prev_sp = unwound_fp + cache->framesize; > + if (cache->framereg == AARCH64_SP_REGNUM > + && get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM) == unwound_fp) > + cache->prev_sp = unwound_fp; > + else > + cache->prev_sp = unwound_fp + cache->framesize; > > /* Calculate actual addresses of saved registers using offsets > determined by aarch64_analyze_prologue. */ I came across the aarch64 version of stack_frame_destroyed_p, and realized I can do the fix like this: ... @@ -999,7 +1001,10 @@ aarch64_make_prologue_cache_1 (frame_info_ptr this_frame, if (unwound_fp == 0) return; - cache->prev_sp = unwound_fp + cache->framesize; + cache->prev_sp = unwound_fp; + if (!aarch64_stack_frame_destroyed_p (get_frame_arch (this_frame), + cache->prev_pc)) + cache->prev_sp += cache->framesize; /* Calculate actual addresses of saved registers using offsets determined by aarch64_analyze_prologue. */ ... This fixes both the leaf and non-leaf case. Thanks, - Tom
On 1/19/23 10:46, Tom de Vries wrote: > Consider the test-case test.c, compiled without debug info: > ... > void > foo (const char *s) > { > } > > int > main (void) > { > foo ("foo"); > return 0; > } > ... > > Disassembly of foo: > ... > 0000000000400564 <foo>: > 400564: d10043ff sub sp, sp, #0x10 > 400568: f90007e0 str x0, [sp, #8] > 40056c: d503201f nop > 400570: 910043ff add sp, sp, #0x10 > 400574: d65f03c0 ret > ... > > Now, let's do "info frame" at each insn in foo, as well as printing $sp > and $x29 (and strip the output of info frame to the first line, for brevity): > ... > $ gdb -q a.out > Reading symbols from a.out... > (gdb) b *foo > Breakpoint 1 at 0x400564 > (gdb) r > Starting program: a.out > > Breakpoint 1, 0x0000000000400564 in foo () > (gdb) display /x $sp > 1: /x $sp = 0xfffffffff3a0 > (gdb) display /x $x29 > 2: /x $x29 = 0xfffffffff3a0 > (gdb) info frame > Stack level 0, frame at 0xfffffffff3a0: > (gdb) si > 0x0000000000400568 in foo () > 1: /x $sp = 0xfffffffff390 > 2: /x $x29 = 0xfffffffff3a0 > (gdb) info frame > Stack level 0, frame at 0xfffffffff3a0: > (gdb) si > 0x000000000040056c in foo () > 1: /x $sp = 0xfffffffff390 > 2: /x $x29 = 0xfffffffff3a0 > (gdb) info frame > Stack level 0, frame at 0xfffffffff3a0: > (gdb) si > 0x0000000000400570 in foo () > 1: /x $sp = 0xfffffffff390 > 2: /x $x29 = 0xfffffffff3a0 > (gdb) info frame > Stack level 0, frame at 0xfffffffff3a0: > (gdb) si > 0x0000000000400574 in foo () > 1: /x $sp = 0xfffffffff3a0 > 2: /x $x29 = 0xfffffffff3a0 > (gdb) info frame > Stack level 0, frame at 0xfffffffff3b0: > pc = 0x400574 in foo; saved pc = 0x40058c > (gdb) si > 0x000000000040058c in main () > 1: /x $sp = 0xfffffffff3a0 > 2: /x $x29 = 0xfffffffff3a0 > ... > > The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it > lists 0xfffffffff3b0. > > The frame address is calculated here in aarch64_make_prologue_cache_1: > ... > unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg); > if (unwound_fp == 0) > return; > > cache->prev_sp = unwound_fp + cache->framesize; > ... > > For insns after the prologue, we have cache->framereg == sp and > cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong > answer once sp has been restored to entry value by the before-last insn. > > Fix this by detecting the situation that the sp has been restored. > > This fixes PR tdep/30011. > > This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and > gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721. I still see failures for gdb.reverse/solib-precsave.exp and gdb.reverse/solib-reverse.exp for both Ubuntu 22.04 and 20.04 on aarch64-linux. Running /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-prec save.exp ... FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function one FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function one FAIL: gdb.reverse/solib-precsave.exp: reverse-step back to main one FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function two FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function two Running /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-reve rse.exp ... FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main one FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two Maybe it addresses a different issue, but what I'm seeing is possibly something else (the linetable issue? I vaguely recall the situation for that). > > Tested on aarch64-linux. > PR tdep/30011 > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30011 > --- > gdb/aarch64-tdep.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c > index b576d3b9d99..06349353716 100644 > --- a/gdb/aarch64-tdep.c > +++ b/gdb/aarch64-tdep.c > @@ -996,7 +996,11 @@ aarch64_make_prologue_cache_1 (frame_info_ptr this_frame, > if (unwound_fp == 0) > return; > > - cache->prev_sp = unwound_fp + cache->framesize; > + if (cache->framereg == AARCH64_SP_REGNUM > + && get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM) == unwound_fp) > + cache->prev_sp = unwound_fp; > + else > + cache->prev_sp = unwound_fp + cache->framesize; > > /* Calculate actual addresses of saved registers using offsets > determined by aarch64_analyze_prologue. */
On 1/23/23 11:07, Luis Machado wrote: > On 1/19/23 10:46, Tom de Vries wrote: >> Consider the test-case test.c, compiled without debug info: >> ... >> void >> foo (const char *s) >> { >> } >> >> int >> main (void) >> { >> foo ("foo"); >> return 0; >> } >> ... >> >> Disassembly of foo: >> ... >> 0000000000400564 <foo>: >> 400564: d10043ff sub sp, sp, #0x10 >> 400568: f90007e0 str x0, [sp, #8] >> 40056c: d503201f nop >> 400570: 910043ff add sp, sp, #0x10 >> 400574: d65f03c0 ret >> ... >> >> Now, let's do "info frame" at each insn in foo, as well as printing $sp >> and $x29 (and strip the output of info frame to the first line, for >> brevity): >> ... >> $ gdb -q a.out >> Reading symbols from a.out... >> (gdb) b *foo >> Breakpoint 1 at 0x400564 >> (gdb) r >> Starting program: a.out >> >> Breakpoint 1, 0x0000000000400564 in foo () >> (gdb) display /x $sp >> 1: /x $sp = 0xfffffffff3a0 >> (gdb) display /x $x29 >> 2: /x $x29 = 0xfffffffff3a0 >> (gdb) info frame >> Stack level 0, frame at 0xfffffffff3a0: >> (gdb) si >> 0x0000000000400568 in foo () >> 1: /x $sp = 0xfffffffff390 >> 2: /x $x29 = 0xfffffffff3a0 >> (gdb) info frame >> Stack level 0, frame at 0xfffffffff3a0: >> (gdb) si >> 0x000000000040056c in foo () >> 1: /x $sp = 0xfffffffff390 >> 2: /x $x29 = 0xfffffffff3a0 >> (gdb) info frame >> Stack level 0, frame at 0xfffffffff3a0: >> (gdb) si >> 0x0000000000400570 in foo () >> 1: /x $sp = 0xfffffffff390 >> 2: /x $x29 = 0xfffffffff3a0 >> (gdb) info frame >> Stack level 0, frame at 0xfffffffff3a0: >> (gdb) si >> 0x0000000000400574 in foo () >> 1: /x $sp = 0xfffffffff3a0 >> 2: /x $x29 = 0xfffffffff3a0 >> (gdb) info frame >> Stack level 0, frame at 0xfffffffff3b0: >> pc = 0x400574 in foo; saved pc = 0x40058c >> (gdb) si >> 0x000000000040058c in main () >> 1: /x $sp = 0xfffffffff3a0 >> 2: /x $x29 = 0xfffffffff3a0 >> ... >> >> The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it >> lists 0xfffffffff3b0. >> >> The frame address is calculated here in aarch64_make_prologue_cache_1: >> ... >> unwound_fp = get_frame_register_unsigned (this_frame, >> cache->framereg); >> if (unwound_fp == 0) >> return; >> >> cache->prev_sp = unwound_fp + cache->framesize; >> ... >> >> For insns after the prologue, we have cache->framereg == sp and >> cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong >> answer once sp has been restored to entry value by the before-last insn. >> >> Fix this by detecting the situation that the sp has been restored. >> >> This fixes PR tdep/30011. >> >> This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and >> gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721. > > I still see failures for gdb.reverse/solib-precsave.exp and > gdb.reverse/solib-reverse.exp for both Ubuntu 22.04 and 20.04 > on aarch64-linux. > > Running > /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-prec > save.exp ... > FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function one > FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function > one > FAIL: gdb.reverse/solib-precsave.exp: reverse-step back to main one > FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function two > FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function > two > > Running > /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-reve > rse.exp ... > FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one > FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one > FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main one > FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two > FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two > > Maybe it addresses a different issue, but what I'm seeing is possibly > something else (the linetable issue? I vaguely recall the situation for > that). >> Hi, that is very well possible. I'm not claiming to fix the test-case on aarch64 in general, I'm very specifically claiming to fix the FAILs I reported in a PR. BTW the first FAIL in the PR is also different than the one you report above, which is usually a hint that there may be a different root cause. I'll commit (using an updated commit message claiming both PRs tdep/30010 and tdep/30011) once I do another round of testing. Thanks, - Tom >> Tested on aarch64-linux. >> PR tdep/30011 >> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30011 >> --- >> gdb/aarch64-tdep.c | 6 +++++- >> 1 file changed, 5 insertions(+), 1 deletion(-) >> >> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c >> index b576d3b9d99..06349353716 100644 >> --- a/gdb/aarch64-tdep.c >> +++ b/gdb/aarch64-tdep.c >> @@ -996,7 +996,11 @@ aarch64_make_prologue_cache_1 (frame_info_ptr >> this_frame, >> if (unwound_fp == 0) >> return; >> - cache->prev_sp = unwound_fp + cache->framesize; >> + if (cache->framereg == AARCH64_SP_REGNUM >> + && get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM) >> == unwound_fp) >> + cache->prev_sp = unwound_fp; >> + else >> + cache->prev_sp = unwound_fp + cache->framesize; >> /* Calculate actual addresses of saved registers using offsets >> determined by aarch64_analyze_prologue. */ >
On 1/23/23 11:59, Tom de Vries wrote: > On 1/23/23 11:07, Luis Machado wrote: >> On 1/19/23 10:46, Tom de Vries wrote: >>> Consider the test-case test.c, compiled without debug info: >>> ... >>> void >>> foo (const char *s) >>> { >>> } >>> >>> int >>> main (void) >>> { >>> foo ("foo"); >>> return 0; >>> } >>> ... >>> >>> Disassembly of foo: >>> ... >>> 0000000000400564 <foo>: >>> 400564: d10043ff sub sp, sp, #0x10 >>> 400568: f90007e0 str x0, [sp, #8] >>> 40056c: d503201f nop >>> 400570: 910043ff add sp, sp, #0x10 >>> 400574: d65f03c0 ret >>> ... >>> >>> Now, let's do "info frame" at each insn in foo, as well as printing $sp >>> and $x29 (and strip the output of info frame to the first line, for brevity): >>> ... >>> $ gdb -q a.out >>> Reading symbols from a.out... >>> (gdb) b *foo >>> Breakpoint 1 at 0x400564 >>> (gdb) r >>> Starting program: a.out >>> >>> Breakpoint 1, 0x0000000000400564 in foo () >>> (gdb) display /x $sp >>> 1: /x $sp = 0xfffffffff3a0 >>> (gdb) display /x $x29 >>> 2: /x $x29 = 0xfffffffff3a0 >>> (gdb) info frame >>> Stack level 0, frame at 0xfffffffff3a0: >>> (gdb) si >>> 0x0000000000400568 in foo () >>> 1: /x $sp = 0xfffffffff390 >>> 2: /x $x29 = 0xfffffffff3a0 >>> (gdb) info frame >>> Stack level 0, frame at 0xfffffffff3a0: >>> (gdb) si >>> 0x000000000040056c in foo () >>> 1: /x $sp = 0xfffffffff390 >>> 2: /x $x29 = 0xfffffffff3a0 >>> (gdb) info frame >>> Stack level 0, frame at 0xfffffffff3a0: >>> (gdb) si >>> 0x0000000000400570 in foo () >>> 1: /x $sp = 0xfffffffff390 >>> 2: /x $x29 = 0xfffffffff3a0 >>> (gdb) info frame >>> Stack level 0, frame at 0xfffffffff3a0: >>> (gdb) si >>> 0x0000000000400574 in foo () >>> 1: /x $sp = 0xfffffffff3a0 >>> 2: /x $x29 = 0xfffffffff3a0 >>> (gdb) info frame >>> Stack level 0, frame at 0xfffffffff3b0: >>> pc = 0x400574 in foo; saved pc = 0x40058c >>> (gdb) si >>> 0x000000000040058c in main () >>> 1: /x $sp = 0xfffffffff3a0 >>> 2: /x $x29 = 0xfffffffff3a0 >>> ... >>> >>> The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it >>> lists 0xfffffffff3b0. >>> >>> The frame address is calculated here in aarch64_make_prologue_cache_1: >>> ... >>> unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg); >>> if (unwound_fp == 0) >>> return; >>> >>> cache->prev_sp = unwound_fp + cache->framesize; >>> ... >>> >>> For insns after the prologue, we have cache->framereg == sp and >>> cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong >>> answer once sp has been restored to entry value by the before-last insn. >>> >>> Fix this by detecting the situation that the sp has been restored. >>> >>> This fixes PR tdep/30011. >>> >>> This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and >>> gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721. >> >> I still see failures for gdb.reverse/solib-precsave.exp and gdb.reverse/solib-reverse.exp for both Ubuntu 22.04 and 20.04 >> on aarch64-linux. >> >> Running /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-prec >> save.exp ... >> FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function one >> FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function one >> FAIL: gdb.reverse/solib-precsave.exp: reverse-step back to main one >> FAIL: gdb.reverse/solib-precsave.exp: reverse-step into solib function two >> FAIL: gdb.reverse/solib-precsave.exp: reverse-step within solib function two >> >> Running /work/luimac01/work/builds/binutils-gdb-arm64-jammy/gdb/testsuite/../../../../repos/binutils-gdb/gdb/testsuite/gdb.reverse/solib-reve >> rse.exp ... >> FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one >> FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one >> FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main one >> FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two >> FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two >> >> Maybe it addresses a different issue, but what I'm seeing is possibly something else (the linetable issue? I vaguely recall the situation for that). >>> > > Hi, > > that is very well possible. I'm not claiming to fix the test-case on aarch64 in general, I'm very specifically claiming to fix the FAILs I reported in a PR. > > BTW the first FAIL in the PR is also different than the one you report above, which is usually a hint that there may be a different root cause. > > I'll commit (using an updated commit message claiming both PRs tdep/30010 and tdep/30011) once I do another round of testing. > > Thanks, > - Tom > Sounds good to me. Thanks for the patch.
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index b576d3b9d99..06349353716 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -996,7 +996,11 @@ aarch64_make_prologue_cache_1 (frame_info_ptr this_frame, if (unwound_fp == 0) return; - cache->prev_sp = unwound_fp + cache->framesize; + if (cache->framereg == AARCH64_SP_REGNUM + && get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM) == unwound_fp) + cache->prev_sp = unwound_fp; + else + cache->prev_sp = unwound_fp + cache->framesize; /* Calculate actual addresses of saved registers using offsets determined by aarch64_analyze_prologue. */