From: Indu Bhagat Date: Tue, 4 Feb 2025 19:57:24 +0000 (-0800) Subject: libsframe: add new dump_sframe_reloc X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=078d38682291b06c44a3e091ad87c302d9385eb4;p=thirdparty%2Fbinutils-gdb.git libsframe: add new dump_sframe_reloc PR libsframe/32589 - function start address is zero in SFrame section dump This new function dumps the contents of a relocated SFrame section in human readable text. Even after the section contents are relocated, there is need to fixup the function start address, which is what sframe_fde_tbl_reloc_fixup () is about. This function is libsframe internal only and is not exposed. Some caution is necessary though in making sure this is done in a version aware manner, when future versions of the SFrame format are implemented. libsframe/ * libtool.version: Bump revision and age. Use 1:1:1. * libsframe.ver: Add new API dump_sframe_reloc. * sframe-dump.c (dump_sframe): (dump_sframe_reloc): New definition. * sframe-impl.h (sframe_fde_tbl_reloc_fixup): New declaration. * sframe.c (sframe_fde_tbl_reloc_fixup): New definition. include/ * sframe-api.h (dump_sframe_reloc): New declaration. --- diff --git a/include/sframe-api.h b/include/sframe-api.h index 77ba32b0f4b..a2527ec4a3e 100644 --- a/include/sframe-api.h +++ b/include/sframe-api.h @@ -189,6 +189,10 @@ sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx, extern void dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr); +/* SFrame textual dump - with relocation. */ +extern void +dump_sframe_reloc (sframe_decoder_ctx *dctx, uint64_t sec_addr, bool relocate); + /* Get the base reg id from the FRE info. Sets errp if fails. */ extern uint8_t sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp); diff --git a/libsframe/libsframe.ver b/libsframe/libsframe.ver index 57f5fb6c378..1f794134679 100644 --- a/libsframe/libsframe.ver +++ b/libsframe/libsframe.ver @@ -33,6 +33,7 @@ LIBSFRAME_1.0 { sframe_encoder_add_funcdesc_v2; sframe_encoder_write; dump_sframe; + dump_sframe_reloc; sframe_errmsg; local: diff --git a/libsframe/libtool-version b/libsframe/libtool-version index 9dcbe48e47d..6fe45c485c5 100644 --- a/libsframe/libtool-version +++ b/libsframe/libtool-version @@ -27,4 +27,4 @@ # then set age to 0. # # CURRENT:REVISION:AGE -1:0:0 +1:1:1 diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c index 1fa508d9bad..95c4d44414e 100644 --- a/libsframe/sframe-dump.c +++ b/libsframe/sframe-dump.c @@ -219,13 +219,20 @@ dump_sframe_functions (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr) } void -dump_sframe (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr) +dump_sframe_reloc (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr, bool relocate) { - uint8_t ver; + if (relocate) + sframe_fde_tbl_reloc_fixup (sfd_ctx); + + dump_sframe (sfd_ctx, sec_addr); +} +void +dump_sframe (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr) +{ dump_sframe_header (sfd_ctx); - ver = sframe_decoder_get_version (sfd_ctx); + uint8_t ver = sframe_decoder_get_version (sfd_ctx); if (ver == SFRAME_VERSION) dump_sframe_functions (sfd_ctx, sec_addr); else diff --git a/libsframe/sframe-impl.h b/libsframe/sframe-impl.h index 1cada54ae9e..9887039c3c5 100644 --- a/libsframe/sframe-impl.h +++ b/libsframe/sframe-impl.h @@ -64,6 +64,8 @@ struct sframe_encoder_ctx size_t sfe_data_size; }; +int sframe_fde_tbl_reloc_fixup (sframe_decoder_ctx *dctx); + #ifdef __cplusplus } #endif diff --git a/libsframe/sframe.c b/libsframe/sframe.c index c2693b978ec..ebf8019b78b 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -102,6 +102,37 @@ sframe_ret_set_errno (int *errp, int error) return NULL; } +/* If the input buffer containing the SFrame section has been relocated, there + will be a need to do fixups too. The fixup merely accounts for the offset + of the byte from the start of the section. + + Currently used by dump_sframe. The caller must have decoded (and hence, + endian flipped) the input buffer before calling this function. */ + +int +sframe_fde_tbl_reloc_fixup (sframe_decoder_ctx *dctx) +{ + uint8_t sframe_ver = sframe_decoder_get_version (dctx); + uint32_t num_fdes = sframe_decoder_get_num_fidx (dctx); + unsigned int buf_offset = 0; + sframe_func_desc_entry *fde; + uint32_t i = 0; + + if (sframe_ver != SFRAME_VERSION_2 || !dctx->sfd_funcdesc) + return SFRAME_ERR; + + buf_offset += sframe_decoder_get_hdr_size (dctx); + while (i < num_fdes) + { + fde = &dctx->sfd_funcdesc[i]; + fde->sfde_func_start_address += buf_offset; + buf_offset += sizeof (sframe_func_desc_entry); + i++; + } + + return 0; +} + /* Get the SFrame header size. */ static uint32_t