From: Indu Bhagat Date: Thu, 16 Oct 2025 22:31:05 +0000 (-0700) Subject: libsframe: use sf_fde_tbl data structure internally for the decoder X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fusers%2Fibhagat%2Ftry-sframe-v3-prep1;p=thirdparty%2Fbinutils-gdb.git libsframe: use sf_fde_tbl data structure internally for the decoder 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. --- 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 #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 17f42dbd485..68773b3391d 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 @@ -396,10 +441,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; } @@ -421,7 +467,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; } @@ -442,7 +489,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); @@ -969,7 +1016,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; @@ -1042,17 +1089,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); @@ -1177,7 +1228,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)