forked from Imagelibrary/binutils-gdb
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
19
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d
Normal file
19
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.d
Normal file
@@ -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 +
|
||||
40
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s
Normal file
40
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-pr33170.s
Normal file
@@ -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
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user