From: Indu Bhagat Date: Thu, 17 Jul 2025 22:17:36 +0000 (-0700) Subject: gas: sframe: fix PR gas/33170 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83eeaf917873a550656faf9a38cd14e0f4c521b1;p=thirdparty%2Fbinutils-gdb.git gas: sframe: fix PR gas/33170 SFrame generation code assumes that since DW_CFA_restore means restoration of the state of the register to the one at the beginning of the function, there must be a state to restore to (hence the gas_assert (cie_fre)). This assumption needs adjustment. DW_CFA_restore may be present in the very beginning of a (e.g., cold) function, with no initialized state for SFrame functions to restore to. gas/ PR gas/33170 * gas/gen-sframe.c (sframe_xlate_do_restore): Use current FRE if CIE FRE is not yet setup. gas/testsuite/ PR gas/33170 * gas/cfi-sframe/cfi-sframe.exp: New test. * gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d: New test. * gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s: New test. --- diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 806ef5f9b5b..d082b974be3 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -1286,11 +1286,18 @@ sframe_xlate_do_restore (struct sframe_xlate_ctx *xlate_ctx, list of FREs for the specific function. */ struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre; + /* PR gas/33170. It is valid to have a: + .cfi_restore N + even at the entry of a function; in which case cie_fre is not yet setup. + Point cie_fre to cur_fre, and let the machinery proceed to update + merge_candidate as usual. */ + if (cie_fre == NULL) + cie_fre = cur_fre; + /* Change the rule for the indicated register to the rule assigned to - it by the initial_instructions in the CIE. */ - gas_assert (cie_fre); - /* SFrame FREs track only CFA and FP / RA for backtracing purposes; - skip the other .cfi_restore directives. */ + it by the initial_instructions in the CIE. SFrame FREs track only CFA + and FP / RA for backtracing purposes; skip the other .cfi_restore + directives. */ if (cfi_insn->u.r == SFRAME_CFA_FP_REG) { gas_assert (cur_fre); diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d new file mode 100644 index 00000000000..85c358fa30f --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d @@ -0,0 +1,19 @@ +#as: --gsframe +#objdump: --sframe=.sframe +#name: SFrame generation on x86_64 pr31170 +#... +Contents of the SFrame section .sframe: + Header : + + Version: SFRAME_VERSION_2 + Flags: SFRAME_F_FDE_FUNC_START_PCREL + CFA fixed RA offset: \-8 + Num FDEs: 1 + Num FREs: 2 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 50 bytes + STARTPC +CFA +FP +RA + + 0+0000 +fp\+16 +c\-16 +f + + 0+002d +fp\+16 +c\-16 +f + diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s new file mode 100644 index 00000000000..fa7198415f6 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s @@ -0,0 +1,40 @@ +# PR gas/33170 +# Ennsure graceful handling. + .section .text.unlikely + .cfi_startproc + .type XZ.cold, @function +XZ.cold: +.L1: + .cfi_def_cfa 6, 16 + .cfi_offset 3, -56 + .cfi_offset 6, -16 + .cfi_offset 12, -48 + .cfi_offset 13, -40 + .cfi_offset 14, -32 + .cfi_offset 15, -24 +.L2: + .cfi_restore 12 + .cfi_restore 13 + movl $56, %esi + movq %r14, %rdi + call _Z@PLT + movq %r12, -32(%rbp) + movq %r13, -24(%rbp) + movq %r14, -16(%rbp) + movq %r15, -8(%rbp) + .cfi_offset 12, -48 + .cfi_offset 13, -40 + .cfi_offset 14, -32 + .cfi_offset 15, -24 + jne .L3 + movq %rbx, %rdi + call bar@PLT +.L3: + movq -32(%rbp), %r12 + .cfi_remember_state + .cfi_restore 12 + jmp .L4 +.L4: + .cfi_restore_state + call _ZF@PLT + .cfi_endproc diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp index 00a3ecc067c..82669cd0475 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -58,6 +58,7 @@ if { [istarget "x86_64-*-*"] && [gas_sframe_check] } then { set ASFLAGS "$ASFLAGS --64" run_dump_test "cfi-sframe-x86_64-1" run_dump_test "cfi-sframe-x86_64-2" + run_dump_test "cfi-sframe-x86_64-pr33170" run_dump_test "cfi-sframe-x86_64-empty-1" run_dump_test "cfi-sframe-x86_64-empty-2" run_dump_test "cfi-sframe-x86_64-empty-3"