diff options
author | Indu Bhagat <indu.bhagat@oracle.com> | 2025-07-17 15:17:36 -0700 |
---|---|---|
committer | Indu Bhagat <indu.bhagat@oracle.com> | 2025-07-23 00:11:47 -0700 |
commit | 83eeaf917873a550656faf9a38cd14e0f4c521b1 (patch) | |
tree | b5cb73c9fe7d1efea926bad564a2e72ceaf6f42f | |
parent | 58fe9ce1d6c3a67e47d192ce153cc1edf2884a87 (diff) | |
download | binutils-83eeaf917873a550656faf9a38cd14e0f4c521b1.zip binutils-83eeaf917873a550656faf9a38cd14e0f4c521b1.tar.gz binutils-83eeaf917873a550656faf9a38cd14e0f4c521b1.tar.bz2 |
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.
-rw-r--r-- | gas/gen-sframe.c | 15 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s | 40 | ||||
-rw-r--r-- | gas/testsuite/gas/cfi-sframe/cfi-sframe.exp | 1 |
4 files changed, 71 insertions, 4 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 806ef5f..d082b97 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 0000000..85c358f --- /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 0000000..fa71984 --- /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 00a3ecc..82669cd 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" |