[V3 07/36] [SFrame-V3] libsframe: add V3 APIs for adding and getting SFrame FDE

Indu Bhagat indu.bhagat@oracle.com
Tue Jan 13 11:12:11 GMT 2026


(Similar to V2) Add two new APIs for adding and getting SFrame FDE:
 - sframe_encoder_add_funcdesc_v3
 - sframe_decoder_get_funcdesc_v3

Note the argument for the function start address is int64_t instead of
int32_t (the latter is used in sframe_encoder_add_funcdesc_v2 and
sframe_encoder_get_funcdesc_v2).  The new V3 APIs will be used in a
subsequent commit to extend SFrame V3 to support text > 2 GiB by
allowing int64_t offsets by default.

Similar to the analogous V2 APIs, they return 0 on success and
SFRAME_ERR (in case of sframe_decoder_get_funcdesc_v3) or error code (in
case of sframe_encoder_add_funcdesc_v3) on failure.

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

include/
	* sframe-api.h (sframe_decoder_get_funcdesc_v3): New
	declaration.
	(sframe_encoder_add_funcdesc_v3): Likewise.
libsframe/
	* libsframe.ver: Add the new APIs.
	* sframe.c (sframe_decoder_get_funcdesc_v3): New definition.
	(sframe_encoder_add_funcdesc_v3): Likewise.

---
[Changes in V1]
  - Rename start_adddr to the more appropriate name start_pc_offset
    [Jan].
  - Update function-level comment to include the expectations from the
    return value.  It is a bit non-homogeneous (but consistent with
    other similar sframe_encoder_add_funcdesc* and
    sframe_decoder_get_funcdesc_* APIs) that
    sframe_encoder_add_funcdesc_v3 returns error code on failure, and
    sframe_decoder_get_funcdesc_v3 returns SFRAME_ERR on failure.  Make
    a note in the function-level comments for now [Indu].
[End of changes in V1]

[No changes in V2, V3]
---
 include/sframe-api.h    | 23 ++++++++++++++
 libsframe/libsframe.ver |  2 ++
 libsframe/sframe.c      | 68 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)

diff --git a/include/sframe-api.h b/include/sframe-api.h
index 3b4edd9994b..3bcb92b0664 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -182,6 +182,18 @@ sframe_decoder_get_funcdesc_v2 (const sframe_decoder_ctx *ctx,
 				unsigned char *func_info,
 				uint8_t *rep_block_size);
 
+/* Get the data (NUM_FRES, FUNC_SIZE, START_PC_OFFSET, FUNC_INFO,
+   REP_BLOCK_SIZE) from the SFrame function descriptor entry at the I'th index
+   in the decoder object DCTX.  Return SFRAME_ERR on failure.  */
+extern int
+sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx,
+				unsigned int i,
+				uint32_t *num_fres,
+				uint32_t *func_size,
+				int64_t *start_pc_offset,
+				unsigned char *func_info,
+				uint8_t *rep_block_size);
+
 /* SFrame textual dump.  */
 extern void
 dump_sframe (const sframe_decoder_ctx *decoder, uint64_t addr);
@@ -295,6 +307,17 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *ectx,
 				uint8_t rep_block_size,
 				uint32_t num_fres);
 
+/* Add a new SFrame function descriptor entry with START_PC_OFFSET, FUNC_SIZE,
+   FUNC_INFO and REP_BLOCK_SIZE to the encoder context ECTX.  Return error
+   code on failure.  */
+extern int
+sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx,
+				int64_t start_pc_offset,
+				uint32_t func_size,
+				unsigned char func_info,
+				uint8_t rep_block_size,
+				uint32_t num_fres);
+
 /* Serialize the contents of the encoder context ECTX and return the buffer.
    Sort the SFrame FDEs on start PC if SORT_FDE_P is true.  ENCODED_SIZE is
    updated to the size of the buffer.  Sets ERRP if failure.  */
diff --git a/libsframe/libsframe.ver b/libsframe/libsframe.ver
index 4086a397c89..99027497486 100644
--- a/libsframe/libsframe.ver
+++ b/libsframe/libsframe.ver
@@ -22,6 +22,7 @@ LIBSFRAME_3.0 {
     sframe_find_fre;
     sframe_decoder_get_num_fidx;
     sframe_decoder_get_funcdesc_v2;
+    sframe_decoder_get_funcdesc_v3;
     sframe_decoder_get_fre;
     sframe_encode;
     sframe_encoder_free;
@@ -34,6 +35,7 @@ LIBSFRAME_3.0 {
     sframe_encoder_add_fre;
     sframe_encoder_add_funcdesc;
     sframe_encoder_add_funcdesc_v2;
+    sframe_encoder_add_funcdesc_v3;
     sframe_encoder_write;
     dump_sframe;
     sframe_errmsg;
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 0cf00ee7d08..7dccdc097d4 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -1525,6 +1525,43 @@ sframe_decoder_get_funcdesc_v2 (const sframe_decoder_ctx *dctx,
 
   return 0;
 }
+
+/* Get the data (NUM_FRES, FUNC_SIZE, START_PC_OFFSET, FUNC_INFO,
+   REP_BLOCK_SIZE) from the SFrame function descriptor entry at the I'th index
+   in the decoder object DCTX.  Return SFRAME_ERR on failure.  */
+
+int
+sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx,
+				unsigned int i,
+				uint32_t *num_fres,
+				uint32_t *func_size,
+				int64_t *start_pc_offset,
+				unsigned char *func_info,
+				uint8_t *rep_block_size)
+{
+  int err = 0;
+  if (dctx == NULL || sframe_decoder_get_version (dctx) != SFRAME_VERSION_3)
+    return sframe_set_errno (&err, SFRAME_ERR_INVAL);
+
+  sframe_func_desc_entry_int *fdp
+    = sframe_decoder_get_funcdesc_at_index (dctx, i);
+  if (fdp == NULL)
+    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);
+
+  if (num_fres)
+    *num_fres = fdp->func_num_fres;
+  if (start_pc_offset)
+    *start_pc_offset = fdp->func_start_pc_offset;
+  if (func_size)
+    *func_size = fdp->func_size;
+  if (func_info)
+    *func_info = fdp->func_info;
+  if (rep_block_size)
+    *rep_block_size = fdp->func_rep_size;
+
+  return 0;
+}
+
 /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function
    descriptor entry in the SFrame decoder CTX.  Returns error code as
    applicable.  */
@@ -1950,6 +1987,37 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *ectx,
   return 0;
 }
 
+/* Add a new SFrame function descriptor entry with START_PC_OFFSET, FUNC_SIZE,
+   FUNC_INFO and REP_BLOCK_SIZE to the encoder context ECTX.  Return error
+   code on failure.  */
+
+int
+sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx,
+				int64_t start_pc_offset,
+				uint32_t func_size,
+				unsigned char func_info,
+				uint8_t rep_block_size,
+				uint32_t num_fres ATTRIBUTE_UNUSED)
+{
+  int err = 0;
+  if (ectx == NULL || sframe_encoder_get_version (ectx) != SFRAME_VERSION_3)
+    {
+      sframe_set_errno (&err, SFRAME_ERR_INVAL);
+      return err;
+    }
+
+  err = sframe_encoder_add_funcdesc_internal (ectx, start_pc_offset,
+					      func_size);
+  if (err)
+    return err;
+
+  sf_fde_tbl *fd_info = ectx->sfe_funcdesc;
+  fd_info->entry[fd_info->count-1].func_info = func_info;
+  fd_info->entry[fd_info->count-1].func_rep_size = rep_block_size;
+
+  return 0;
+}
+
 static int
 sframe_sort_funcdesc (sframe_encoder_ctx *ectx)
 {
-- 
2.43.0



More information about the Binutils mailing list