[PATCH, V2 3/3] libsframe: use sf_fde_tbl data structure internally for the decoder
Indu Bhagat
indu.bhagat@oracle.com
Tue Oct 21 06:11:53 GMT 2025
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 of SFrame FDE, as well as a newer on-disk
representation 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 (and still libsframe
internal) definition for 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.
---
[No Changes in V2]
---
libsframe/sframe-impl.h | 8 ++---
libsframe/sframe.c | 73 ++++++++++++++++++++++++++++++++++-------
2 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/libsframe/sframe-impl.h b/libsframe/sframe-impl.h
index 1cada54ae9e..65acb975862 100644
--- a/libsframe/sframe-impl.h
+++ b/libsframe/sframe-impl.h
@@ -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. */
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 260e1047b4d..dfff1b3490a 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -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)
--
2.43.0
More information about the Binutils
mailing list