[RFC PATCH v4 1/3] sframe: Support for RA undefined as indication for outermost frame

Jens Remus jremus@linux.ibm.com
Fri Jul 25 16:32:25 GMT 2025


SFrame V2 has been enhanced to represent return address (RA) undefined
as a SFrame FRE without any offsets.  This is backward compatible, as
stack tracers are expected to stop if a formerly invalid FRE with an
offset count of zero is encountered.

In sense of DWARF an undefined rule for the RA indicates that there is
no return address and the stack trace is complete because an explicitly
as such marked outermost frame has been reached.

Use a SFrame FRE without any offsets as indication that an outermost
frame has been reached and the stack trace is complete.

sysdeps/generic/
	* sframe.h (SFRAME_V2_FRE_RA_UNDEFINED_P): New macro to test
	FRE info word for RA undefined.
	* sframe-read.h (__sframe_fre_get_ra_undefined_p): New function
	declaration.
	* sframe-read.c (sframe_get_fre_ra_undefined_p): New helper to
	test FRE info word for RA undefined.
	(__sframe_fre_get_ra_undefined_p): New function to test FRE for
	RA undefined.
	* sframe.c (__stacktrace_sframe): Stop stack trace if outermost
	frame reached, as indicated by FRE with RA undefined.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---

Notes:
    Changes in v4:
    - Adapt to SFrame change to represent RA undefined as FRE without any
      offsets instead of FDE without any FREs and an RA undefined flag.
      This aligns more closely to DWARF and spares the FDE info word flag.
    - Reword commit message.
    
    Changes in v3:
    - New patch.

 sysdeps/generic/sframe-read.c | 14 ++++++++++++++
 sysdeps/generic/sframe-read.h |  5 +++++
 sysdeps/generic/sframe.c      |  4 ++++
 sysdeps/generic/sframe.h      |  1 +
 4 files changed, 24 insertions(+)

diff --git a/sysdeps/generic/sframe-read.c b/sysdeps/generic/sframe-read.c
index a6ebc42d6689..2d6f171105a6 100644
--- a/sysdeps/generic/sframe-read.c
+++ b/sysdeps/generic/sframe-read.c
@@ -49,6 +49,12 @@ sframe_get_fre_ra_mangled_p (uint8_t fre_info)
   return SFRAME_V1_FRE_MANGLED_RA_P (fre_info);
 }
 
+static inline bool
+sframe_get_fre_ra_undefined_p (uint8_t fre_info)
+{
+  return SFRAME_V2_FRE_RA_UNDEFINED_P (fre_info);
+}
+
 /* Access functions for info from function descriptor entry.  */
 
 static uint32_t
@@ -454,6 +460,14 @@ sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *ctx)
   return dhp->sfh_cfa_fixed_ra_offset;
 }
 
+/* Get  RA undefined from the FRE info.  Set errp if failure.  */
+
+bool
+__sframe_fre_get_ra_undefined_p (const sframe_frame_row_entry *fre)
+{
+  return sframe_get_fre_ra_undefined_p (fre->fre_info);
+}
+
 /* Get the base reg id from the FRE info.  Set errp if failure.  */
 
 uint8_t
diff --git a/sysdeps/generic/sframe-read.h b/sysdeps/generic/sframe-read.h
index 146142143c6b..3adeee4a628a 100644
--- a/sysdeps/generic/sframe-read.h
+++ b/sysdeps/generic/sframe-read.h
@@ -70,6 +70,11 @@ extern _Unwind_Reason_Code
 __sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc,
 		   sframe_frame_row_entry *frep);
 
+/* Get  RA undefined from the FRE info.  Set errp if failure.  */
+
+extern bool
+__sframe_fre_get_ra_undefined_p (const sframe_frame_row_entry *fre);
+
 /* Get the base reg id from the FRE info.  */
 
 extern uint8_t
diff --git a/sysdeps/generic/sframe.c b/sysdeps/generic/sframe.c
index ba0830da3d30..6ff46b40ba7d 100644
--- a/sysdeps/generic/sframe.c
+++ b/sysdeps/generic/sframe.c
@@ -117,6 +117,10 @@ __stacktrace_sframe (void **ra_lst, int count, frame *frame)
 	  return 0;
 	}
 
+      /* RA undefined indicates an outermost frame.  */
+      if (__sframe_fre_get_ra_undefined_p (frep))
+	return i;
+
       /* Get the CFA offset from the FRE.  If offset is unavailable,
 	 sets err.  */
       cfa_offset = __sframe_fre_get_cfa_offset (dctx, frep, &err);
diff --git a/sysdeps/generic/sframe.h b/sysdeps/generic/sframe.h
index e38adcfe1769..603fd9a91a3d 100644
--- a/sysdeps/generic/sframe.h
+++ b/sysdeps/generic/sframe.h
@@ -280,6 +280,7 @@ typedef struct sframe_fre_info
 #define SFRAME_V1_FRE_OFFSET_COUNT(data)	  (((data) >> 1) & 0xf)
 #define SFRAME_V1_FRE_OFFSET_SIZE(data)		  (((data) >> 5) & 0x3)
 #define SFRAME_V1_FRE_MANGLED_RA_P(data)	  (((data) >> 7) & 0x1)
+#define SFRAME_V2_FRE_RA_UNDEFINED_P(data)	  (SFRAME_V1_FRE_OFFSET_COUNT (data) == 0)
 
 /* SFrame Frame Row Entry definitions.
 
-- 
2.48.1



More information about the Libc-alpha mailing list