]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libsframe: use sf_fde_tbl data structure internally for the decoder
authorIndu Bhagat <indu.bhagat@oracle.com>
Sat, 1 Nov 2025 08:46:42 +0000 (01:46 -0700)
committerIndu Bhagat <indu.bhagat@oracle.com>
Sat, 1 Nov 2025 08:47:29 +0000 (01:47 -0700)
Instead of the current sframe_func_desc_entry (on-disk format
representation) data structure.

The decoder context in libsframe, so far, has been internally directly
tied to the sframe_func_desc_entry (on-disk format representation) data
structure.  While this allows libsframe to avoid some operations, this
is not desirable anymore as the format evolves: we will need to support
reading in of older version(s) of SFrame FDE, as well as a newer on-disk
representations for SFrame FDE.

Use sf_fde_tbl internally in the decoder context.  Note that libsframe
already does _not_ use sframe_func_desc_entry in any external-facing,
user-visible APIs.

Note that this commit is simply preparatory in nature.  At the moment,
the 'sf_fde_tbl' internally uses the sframe_func_desc_entry (on-disk
format representation).  When need arises (as SFrame FDE evolves), we
may change sf_fde_tbl to use an alternative (but still libsframe
internal) definition of SFrame FDE.

lisbframe/
        * sframe-impl.h (sf_fde_tbl, sf_fre_tbl): Move definition before use.
Use sf_fde_tbl instead of sframe_func_desc_entry in struct
        sframe_decoder_ctx.
        * sframe.c (sframe_fde_tbl_alloc): New internal definition.
        (sframe_fde_tbl_init): Likewise.
        (sframe_decoder_get_funcdesc_at_index): Adjust for sf_fde_tbl
usage.
        (sframe_decoder_get_secrel_func_start_addr): Likewise.
        (sframe_fre_check_range_p): Likewise.
        (sframe_decode): Likewise.
        (sframe_get_funcdesc_with_addr_internal): Likewise.

libsframe/sframe-impl.h
libsframe/sframe.c

index 1cada54ae9ee38a7f6b6098a0c04966823d664ae..65acb9758629991b177b7691322b18751e3906da 100644 (file)
@@ -30,12 +30,15 @@ extern "C"
 #include <assert.h>
 #define sframe_assert(expr) (assert (expr))
 
+typedef struct sf_fde_tbl sf_fde_tbl;
+typedef struct sf_fre_tbl sf_fre_tbl;
+
 struct sframe_decoder_ctx
 {
   /* SFrame header.  */
   sframe_header sfd_header;
   /* SFrame function desc entries table.  */
-  sframe_func_desc_entry *sfd_funcdesc;
+  sf_fde_tbl *sfd_funcdesc;
   /* SFrame FRE table.  */
   char *sfd_fres;
   /* Number of bytes needed for SFrame FREs.  */
@@ -45,9 +48,6 @@ struct sframe_decoder_ctx
   void *sfd_buf;
 };
 
-typedef struct sf_fde_tbl sf_fde_tbl;
-typedef struct sf_fre_tbl sf_fre_tbl;
-
 struct sframe_encoder_ctx
 {
   /* SFrame header.  */
index 260e1047b4da60f7b0bd28dcc6c7b102d02d7df1..dfff1b3490aa13a2901a06ef4b90367069fe3b9b 100644 (file)
@@ -103,6 +103,51 @@ sframe_ret_set_errno (int *errp, int error)
   return NULL;
 }
 
+/* Allocate space for NUM_FDES number of SFrame FDEs of type
+   sframe_func_desc_entry.  This is version-unaware because this pertains to
+   libsframe's internal in-memory representation of SFrame FDE.  */
+
+static int
+sframe_fde_tbl_alloc (sf_fde_tbl **fde_tbl, unsigned int num_fdes)
+{
+  size_t fidx_size = num_fdes * sizeof (sframe_func_desc_entry);
+  size_t fd_tbl_sz = (sizeof (sf_fde_tbl) + fidx_size);
+
+  *fde_tbl = malloc (fd_tbl_sz);
+  if (*fde_tbl == NULL)
+    return SFRAME_ERR;
+
+  (*fde_tbl)->alloced = num_fdes;
+
+  return 0;
+}
+
+/* Initialize libsframe's internal representation of SFrame FDEs.  */
+
+static int
+sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf,
+                    size_t *fidx_size, unsigned int num_fdes, uint8_t ver)
+{
+  /* sframe_func_desc_entry is the same type as the latest SFrame FDE V2
+     definition (currently sframe_func_desc_entry_v2).  */
+  if (ver == SFRAME_VERSION_2 && SFRAME_VERSION == SFRAME_VERSION_2)
+    {
+      *fidx_size = num_fdes * sizeof (sframe_func_desc_entry_v2);
+      memcpy (fde_tbl->entry, fde_buf, *fidx_size);
+      fde_tbl->count = num_fdes;
+    }
+  /* If ver is not the latest, read buffer manually and upgrade from
+     sframe_func_desc_entry_v2 to populate the sf_fde_tbl entries.  */
+  else
+    {
+      /* Not possible ATM.  */
+      *fidx_size = 0;
+      return SFRAME_ERR;
+    }
+
+  return 0;
+}
+
 /* Get the SFrame header size.  */
 
 static uint32_t
@@ -400,10 +445,11 @@ sframe_decoder_get_funcdesc_at_index (sframe_decoder_ctx *ctx,
   num_fdes = sframe_decoder_get_num_fidx (ctx);
   if (num_fdes == 0
       || func_idx >= num_fdes
-      || ctx->sfd_funcdesc == NULL)
+      || ctx->sfd_funcdesc == NULL
+      || ctx->sfd_funcdesc->count <= func_idx)
     return sframe_ret_set_errno (&err, SFRAME_ERR_DCTX_INVAL);
 
-  fdep = &ctx->sfd_funcdesc[func_idx];
+  fdep = &ctx->sfd_funcdesc->entry[func_idx];
   return fdep;
 }
 
@@ -425,7 +471,8 @@ sframe_decoder_get_secrel_func_start_addr (sframe_decoder_ctx *dctx,
   if (err)
     return 0;
 
-  int32_t func_start_addr = dctx->sfd_funcdesc[func_idx].sfde_func_start_address;
+  const sframe_func_desc_entry *fdep = &dctx->sfd_funcdesc->entry[func_idx];
+  int32_t func_start_addr = fdep->sfde_func_start_address;
 
   return func_start_addr + offsetof_fde_in_sec;
 }
@@ -446,7 +493,7 @@ sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx,
   uint32_t pc_offset;
   bool mask_p;
 
-  fdep = &dctx->sfd_funcdesc[func_idx];
+  fdep = &dctx->sfd_funcdesc->entry[func_idx];
   func_start_addr = sframe_decoder_get_secrel_func_start_addr (dctx, func_idx);
   fde_type = sframe_get_fde_type (fdep);
   mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK);
@@ -982,7 +1029,7 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
   char *frame_buf;
   char *tempbuf = NULL;
 
-  int fidx_size;
+  size_t fidx_size;
   uint32_t fre_bytes;
   int foreign_endian = 0;
 
@@ -1055,17 +1102,21 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
   frame_buf += hdrsz;
 
   /* Handle the SFrame Function Descriptor Entry section.  */
-  fidx_size = dhp->sfh_num_fdes * sizeof (sframe_func_desc_entry);
-  dctx->sfd_funcdesc = malloc (fidx_size);
-  if (dctx->sfd_funcdesc == NULL)
+  if (sframe_fde_tbl_alloc (&dctx->sfd_funcdesc, dhp->sfh_num_fdes))
     {
       sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
       goto decode_fail_free;
     }
+
   /* SFrame FDEs are at an offset of sfh_fdeoff from SFrame header end.  */
-  memcpy (dctx->sfd_funcdesc, frame_buf + dhp->sfh_fdeoff, fidx_size);
+  if (sframe_fde_tbl_init (dctx->sfd_funcdesc, frame_buf + dhp->sfh_fdeoff,
+                          &fidx_size, dhp->sfh_num_fdes, sfp->sfp_version))
+    {
+      sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
+      goto decode_fail_free;
+    }
 
-  debug_printf ("%u total fidx size\n", fidx_size);
+  debug_printf ("%lu total fidx size\n", fidx_size);
 
   /* Handle the SFrame Frame Row Entry section.  */
   dctx->sfd_fres = (char *) malloc (dhp->sfh_fre_len);
@@ -1190,7 +1241,7 @@ sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr,
     return sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTSORTED);
 
   /* Do the binary search.  */
-  fdp = (sframe_func_desc_entry *) ctx->sfd_funcdesc;
+  fdp = (sframe_func_desc_entry *) ctx->sfd_funcdesc->entry;
   low = 0;
   high = dhp->sfh_num_fdes - 1;
   while (low <= high)