]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: Skip SFrame FDE if .cfi_val_offset specifies non-default offset
authorJens Remus <jremus@linux.ibm.com>
Tue, 4 Feb 2025 14:13:24 +0000 (15:13 +0100)
committerJens Remus <jremus@linux.ibm.com>
Tue, 4 Feb 2025 14:13:24 +0000 (15:13 +0100)
Unwinding of the stack pointer (SP) is performed using the assumed
default rule ".cfi_val_offset <SP-reg>, 0", so that SP unwinds as:

  SP = CFA

Warn if the CFI directive .cfi_val_offset is encountered for the
SP register with a different offset.

gas/
* gen-sframe.c (sframe_xlate_do_val_offset): Skip SFrame FDE
if non-default SP value offset.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
gas/gen-sframe.c

index e7397e040c65b768d82f9313e017831939f20716..13478efab6b966626a7016ea98360a0b12846b33 100644 (file)
@@ -1124,15 +1124,15 @@ sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
                            struct cfi_insn_data *cfi_insn)
 {
   /* Previous value of register is CFA + offset.  However, if the specified
-     register is not interesting (FP or RA reg), the current DW_CFA_val_offset
-     instruction can be safely skipped without sacrificing the asynchronicity of
-     stack trace information.  */
+     register is not interesting (SP, FP, or RA reg), the current
+     DW_CFA_val_offset instruction can be safely skipped without sacrificing
+     the asynchronicity of stack trace information.  */
   if (cfi_insn->u.ri.reg == SFRAME_CFA_FP_REG
 #ifdef SFRAME_FRE_RA_TRACKING
       || (sframe_ra_tracking_p () && cfi_insn->u.ri.reg == SFRAME_CFA_RA_REG)
 #endif
-      /* Ignore SP reg, as it can be recovered from the CFA tracking info.  */
-      )
+      /* Ignore SP reg, if offset matches assumed default rule.  */
+      || (cfi_insn->u.ri.reg == SFRAME_CFA_SP_REG && cfi_insn->u.ri.offset != 0))
     {
       as_warn (_("skipping SFrame FDE; %s register %u in .cfi_val_offset"),
               sframe_register_name (cfi_insn->u.ri.reg), cfi_insn->u.ri.reg);