[v4,10/15] gas: Skip SFrame FDE if FP without RA on stack

Message ID 20240624142334.3283823-11-jremus@linux.ibm.com
State New
Headers
Series sframe: Enhancements to SFrame info generation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jens Remus June 24, 2024, 2:23 p.m. UTC
  The SFrame format cannot represent the frame pointer (FP) being saved
on the stack without the return address (RA) also being saved on the
stack, if RA tracking is used.

A SFrame FDE is followed by 1-3 offsets with the following information:

Without RA tracking:
1. Offset from base pointer (SP or FP) to locate the CFA
2. Optional: Offset to CFA to restore the frame pointer (FP)

With RA tracking:
1. Offset from base pointer (SP or FP) to locate the CFA
2. Optional: Offset to CFA to restore the return address (RA)
3. Optional: Offset to CFA to restore the frame pointer (FP)

When RA tracking is used and a FDE is followed by two offsets the
SFrame format does not provide any information to distinguish whether
the second offset is the RA or FP offset. SFrame assumes the offset to
be the RA offset, which may be wrong.

Therefore skip generation of SFrame FDE information and print the
following warning, if RA tracking is used and the FP is saved on the
stack without the RA being saved as well:

  skipping SFrame FDE; FP without RA on stack

gas/
	* gen-sframe.c (sframe_do_fde): Skip SFrame FDE if FP without RA
	on stack, as the SFrame format cannot represent this case.

Reviewed-by: Indu Bhagat <indu.bhagat@oracle.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---

Notes (jremus):
    Changes v3 -> v4:
    - Dropped misleading comment "No errors encountered". as suggtested by
      Indu.
    - Changed warning message text as follows for consistency:
      skipping SFrame FDE; FP without RA on stack
    
    Changes v2 -> v3:
    - New patch.
    
    Without this patch the assembler would generate incorrect SFrame
    information without warning for the s390-specific SFrame error test
    case 5, that gets introduced by patch "s390: Initial support to
    generate .sframe from CFI directives in assembler". The FRE would
    be followed by two offsets for the CFA and FP. SFrame would
    erroneously interpret them as CFA and RA offsets, as it cannot
    represent FP without RA on stack.

 gas/gen-sframe.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 3d9824a7a080..c29c407cc86f 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1423,8 +1423,6 @@  sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
 	}
     }
 
-  /* No errors encountered.  */
-
   /* Link in the scratchpad FRE that the last few CFI insns helped create.  */
   if (xlate_ctx->cur_fre)
     {
@@ -1438,6 +1436,25 @@  sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
 	= get_dw_fde_end_addrS (xlate_ctx->dw_fde);
     }
 
+#ifdef SFRAME_FRE_RA_TRACKING
+  if (sframe_ra_tracking_p ())
+    {
+      struct sframe_row_entry *fre;
+
+      /* Iterate over the scratchpad FREs and validate them.  */
+      for (fre = xlate_ctx->first_fre; fre; fre = fre->next)
+	{
+	  /* SFrame format cannot represent FP on stack without RA on stack.  */
+	  if (fre->ra_loc != SFRAME_FRE_ELEM_LOC_STACK
+	      && fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+	    {
+	      as_warn (_("skipping SFrame FDE; FP without RA on stack"));
+	      return SFRAME_XLATE_ERR_NOTREPRESENTED;
+	    }
+	}
+    }
+#endif /* SFRAME_FRE_RA_TRACKING  */
+
   return SFRAME_XLATE_OK;
 }