[binutils-gdb] gas: Don't skip SFrame FDE if .cfi_register specifies SP register

Jens Remus jremus@sourceware.org
Thu Jul 4 08:40:10 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=42e6e6904bd9f49231045b62e0d1eb6a8ac9d176

commit 42e6e6904bd9f49231045b62e0d1eb6a8ac9d176
Author: Jens Remus <jremus@linux.ibm.com>
Date:   Thu Jul 4 10:34:12 2024 +0200

    gas: Don't skip SFrame FDE if .cfi_register specifies SP register
    
    Neither ".cfi_offset SP, <offset>", ".cfi_register SP, <regno>", nor
    ".cfi_val_offset SP, <offset>" alter the tracking information to recover
    the stack pointer (SP). Doing so would need an explicit .cfi_def_cfa,
    which SFrame tracks.
    
    The stack pointer (SP) register contents on entry can be reconstructed
    from the SFrame CFA tracking information using information from the
    current and initial SFrame FREs of the SFrame FDE:
    
    1. Compute CFA from the current CFA base register (SP or FP) and CFA
       offset from the SFrame CFA tracking information from the SFrame FRE
       for the current instruction address:
    
         CFA = <current_base_reg> + <current_cfa_offset>
    
    2. Compute SP from the current CFA and the CFA offset from the SFrame
       CFA tracking information from the initial SFrame FRE of the FDE:
    
         SP = CFA - <initial_cfa_offset>
    
    While at it add comments to the processing of .cfi_offset and
    .cfi_val_offset that the SP can be reconstructed from the CFA tracking
    information.
    
    gas/
            * gen-sframe.c (sframe_xlate_do_register): Do not skip SFrame
            FDE if .cfi_register specifies SP register.
            (sframe_xlate_do_offset,sframe_xlate_do_val_offset): Add comment
            that this is likewise.
    
    Signed-off-by: Jens Remus <jremus@linux.ibm.com>

Diff:
---
 gas/gen-sframe.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 31f2e511828..f4bdbb5944d 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1100,6 +1100,7 @@ sframe_xlate_do_offset (struct sframe_xlate_ctx *xlate_ctx,
   gas_assert (cur_fre);
   /* Change the rule for the register indicated by the register number to
      be the specified offset.  */
+  /* Ignore SP reg, as it can be recovered from the CFA tracking info.  */
   if (cfi_insn->u.r == SFRAME_CFA_FP_REG)
     {
       gas_assert (!cur_fre->base_reg);
@@ -1134,6 +1135,7 @@ sframe_xlate_do_val_offset (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
 #ifdef SFRAME_FRE_RA_TRACKING
       || (sframe_ra_tracking_p () && cfi_insn->u.r == SFRAME_CFA_RA_REG)
 #endif
+      /* Ignore SP reg, as it can be recovered from the CFA tracking info.  */
       )
     {
       as_warn (_("skipping SFrame FDE; %s register %u in .cfi_val_offset"),
@@ -1153,14 +1155,15 @@ sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
 			  struct cfi_insn_data *cfi_insn)
 {
   /* Previous value of register1 is register2.  However, if the specified
-     register1 is not interesting (SP, FP, or RA reg), the current DW_CFA_register
+     register1 is not interesting (FP or RA reg), the current DW_CFA_register
      instruction can be safely skipped without sacrificing the asynchronicity of
      stack trace information.  */
-  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_SP_REG
+  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG
 #ifdef SFRAME_FRE_RA_TRACKING
       || (sframe_ra_tracking_p () && cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG)
 #endif
-      || cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG)
+      /* Ignore SP reg, as it can be recovered from the CFA tracking info.  */
+      )
     {
       as_warn (_("skipping SFrame FDE; %s register %u in .cfi_register"),
 	       sframe_register_name (cfi_insn->u.rr.reg1), cfi_insn->u.rr.reg1);


More information about the Binutils-cvs mailing list