[PATCH v4 2/4] include: libsframe: Add API to get FRE offset count

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


This API will be later used by libsframe when dumping SFrame stack trace
information (e.g. in objdump and readelf) to handle the special case of
a SFrame FRE without any offsets.  Such FREs without any offsets will be
used to represent RA undefined.  Other users of libsframe might need the
same capability.

Rename the existing static function of same name to re-use its name for
the global one.  The rename aligns the static function name to the
likes.

While at it pass SFrame FRE as pointer to const to sanity check helper.

include/
	* sframe-api.h (sframe_fre_get_offset_count): New declaration.

libsframe/
	* libsframe.ver (sframe_fre_get_offset_count): List new API.
	* sframe.c (sframe_fre_get_offset_count): Rename to ...
	(sframe_get_fre_offset_count): ... this.
	(sframe_fre_sanity_check_p, sframe_fre_offset_bytes_size,
	flip_fre, sframe_get_fre_offset): Likewise.
	(sframe_fre_get_offset_count): New definition.
	(sframe_fre_sanity_check_p): Make frep pointer to const.

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

Notes (jremus):
    Changes in V4:
    - New patch.
    
    Technically it would not be necessary to make sframe_fre_get_offset_count
    global (i.e. list it in the version file), as libsframe could use it
    in dumping SFrame. But other users of libsframe need the capability to
    differentiate between a failure to get the CFA offset and a FRE without
    any offsets.
    
    An alternative would be to add an API to test for RA undefined.  See
    a following patch.

 include/sframe-api.h    |  6 ++++++
 libsframe/libsframe.ver |  5 +++++
 libsframe/sframe.c      | 24 ++++++++++++++++++------
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/include/sframe-api.h b/include/sframe-api.h
index 8c26257fb643..02688e4edca4 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -201,6 +201,12 @@ dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr);
 extern uint8_t
 sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp);
 
+/* Get the number of offset from the FRE.  Set errp if failure.  */
+
+int
+sframe_fre_get_offset_count (const sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED,
+			     const sframe_frame_row_entry *fre, int *errp);
+
 /* Get the CFA offset from the FRE.  If the offset is invalid, sets errp.  */
 extern int32_t
 sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx,
diff --git a/libsframe/libsframe.ver b/libsframe/libsframe.ver
index 8cc80da2f26a..e02e29ae134f 100644
--- a/libsframe/libsframe.ver
+++ b/libsframe/libsframe.ver
@@ -41,3 +41,8 @@ LIBSFRAME_2.0 {
   local:
     *;
 } LIBSFRAME_0.0;
+
+LIBSFRAME_2.1 {
+  global:
+    sframe_fre_get_offset_count;
+} LIBSFRAME_2.0;
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 9814a3ae4c1f..108c2bf9d2a9 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -114,7 +114,7 @@ sframe_get_hdr_size (sframe_header *sfh)
 /* Access functions for frame row entry data.  */
 
 static uint8_t
-sframe_fre_get_offset_count (uint8_t fre_info)
+sframe_get_fre_offset_count (uint8_t fre_info)
 {
   return SFRAME_V1_FRE_OFFSET_COUNT (fre_info);
 }
@@ -284,7 +284,7 @@ sframe_fre_start_addr_size (uint32_t fre_type)
 /* Check if the FREP has valid data.  */
 
 static bool
-sframe_fre_sanity_check_p (sframe_frame_row_entry *frep)
+sframe_fre_sanity_check_p (const sframe_frame_row_entry *frep)
 {
   uint8_t offset_size, offset_cnt;
   uint8_t fre_info;
@@ -300,7 +300,7 @@ sframe_fre_sanity_check_p (sframe_frame_row_entry *frep)
       && offset_size != SFRAME_FRE_OFFSET_4B)
     return false;
 
-  offset_cnt = sframe_fre_get_offset_count (fre_info);
+  offset_cnt = sframe_get_fre_offset_count (fre_info);
   if (offset_cnt > MAX_NUM_STACK_OFFSETS)
     return false;
 
@@ -318,7 +318,7 @@ sframe_fre_offset_bytes_size (uint8_t fre_info)
 
   debug_printf ("offset_size =  %u\n", offset_size);
 
-  offset_cnt = sframe_fre_get_offset_count (fre_info);
+  offset_cnt = sframe_get_fre_offset_count (fre_info);
 
   if (offset_size == SFRAME_FRE_OFFSET_2B
       || offset_size == SFRAME_FRE_OFFSET_4B)	/* 2 or 4 bytes.  */
@@ -442,7 +442,7 @@ flip_fre (char *fp, uint32_t fre_type, size_t *fre_size)
   /* FRE info is uint8_t.  No need to flip.  */
   fre_info = *(uint8_t*)fp;
   offset_size = sframe_fre_get_offset_size (fre_info);
-  offset_cnt = sframe_fre_get_offset_count (fre_info);
+  offset_cnt = sframe_get_fre_offset_count (fre_info);
 
   /* Advance the buffer pointer to where the stack offsets are.  */
   fre_info_size = sizeof (uint8_t);
@@ -587,7 +587,7 @@ sframe_get_fre_offset (sframe_frame_row_entry *fre, int idx, int *errp)
   if (fre == NULL || !sframe_fre_sanity_check_p (fre))
     return sframe_set_errno (errp, SFRAME_ERR_FRE_INVAL);
 
-  offset_cnt = sframe_fre_get_offset_count (fre->fre_info);
+  offset_cnt = sframe_get_fre_offset_count (fre->fre_info);
   offset_size = sframe_fre_get_offset_size (fre->fre_info);
 
   if (offset_cnt < idx + 1)
@@ -692,6 +692,18 @@ sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp)
   return SFRAME_V1_FRE_CFA_BASE_REG_ID (fre_info);
 }
 
+/* Get the number of offset from the FRE.  Set errp if failure.  */
+
+int
+sframe_fre_get_offset_count (const sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED,
+			     const sframe_frame_row_entry *fre, int *errp)
+{
+  if (fre == NULL || !sframe_fre_sanity_check_p (fre))
+    return sframe_set_errno (errp, SFRAME_ERR_FRE_INVAL);
+
+  return sframe_get_fre_offset_count (fre->fre_info);
+}
+
 /* Get the CFA offset from the FRE.  If the offset is invalid, sets errp.  */
 
 int32_t
-- 
2.48.1



More information about the Binutils mailing list