From: Indu Bhagat Date: Mon, 10 Nov 2025 22:44:48 +0000 (-0800) Subject: [SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for extensibility in FDE X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d48ac48f9798412f0fa67b49dbe37708c4d8cfe;p=thirdparty%2Fbinutils-gdb.git [SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for extensibility in FDE FDE's func_info field is a key member which is used to convey important information around the encoding and interpretation of the SFrame FDE and the function's SFrame FRE information. Currently there is 1 bit left for AArch64, and 2 bits for AMD64,s390x (and other future ABIs to be supported). Provision some additional space now (specifically an additional 8-bits) for future needs for V3 and beyond. Compared to V2, this now increases the size of SFrame FDE by 1 byte in V3. In this patch, the additional byte is not used functionally in the patch. Hence, rather mechanical changes in libsframe, bfd and libsframe/testsuite accompany. With the addition of a new byte for additional func info (func_info2), add a new arg to allow usecases like textual dumper to get all data members in one API: sframe_decoder_get_funcdesc_v3. To keep the APIs symmetric looking, add new arg to sframe_encoder_add_funcdesc_v3 too. Since bfd uses these APIs too, carry out the mechanical change in the respective APIs too. And of course, the testsuite which exercises these APIs. bfd/ * elf-sframe.c (_bfd_elf_merge_section_sframe): Get and set func_info2. * elf64-s390.c (_bfd_s390_elf_create_sframe_plt): Pass 0 for func_info2 for SFrame FDE for PLT. * elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Likewise. gas/ * gen-sframe.c (output_sframe_funcdesc): Emit the uint8_t for func_info2. libsframe/ * sframe-dump.c (dump_sframe_func_with_fres): * sframe.c (sframe_fde_tbl_init): Handle the new additional member. (sframe_encoder_write_fde): Likewise. * sframe.c (sframe_decoder_get_funcdesc_v3): Update func_info2. libsframe/testsuite/ * libsframe.decode/DATA2: Update data file with SFrame section data. * libsframe.encode/encode-1.c: Pass 0 for func_info2 arg. * libsframe.find/findfre-1.c: Likewise. * libsframe.find/findfunc-1.c: Likewise. * libsframe.find/plt-findfre-1.c: Likewise. * libsframe.find/plt-findfre-2.c: Likewise. include/ * sframe.h: Add new uint8_t sfde_func_info2 to sframe_func_desc_entry_v3. * sframe-api.h (sframe_decoder_get_funcdesc_v3): New arg. (sframe_encoder_add_funcdesc_v3): Likewise. --- diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c index ba4827819ad..f6a332cff57 100644 --- a/bfd/elf-sframe.c +++ b/bfd/elf-sframe.c @@ -477,6 +477,7 @@ _bfd_elf_merge_section_sframe (bfd *abfd, bfd_vma address; uint32_t func_size = 0; unsigned char func_info = 0; + unsigned char func_info2 = 0; unsigned int r_offset = 0; bool pltn_reloc_by_hand = false; unsigned int pltn_r_offset = 0; @@ -484,7 +485,7 @@ _bfd_elf_merge_section_sframe (bfd *abfd, if (!sframe_decoder_get_funcdesc_v3 (sfd_ctx, i, &num_fres, &func_size, &func_start_addr, &func_info, - &rep_block_size)) + &func_info2, &rep_block_size)) { /* If function belongs to a deleted section, skip editing the function descriptor entry. */ @@ -551,7 +552,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd, /* Update the encoder context with updated content. */ int err = sframe_encoder_add_funcdesc_v3 (sfe_ctx, func_start_addr, func_size, func_info, - rep_block_size, num_fres); + func_info2, rep_block_size, + num_fres); cur_fidx++; BFD_ASSERT (!err); } diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index ae609903d80..7b2b7c21898 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1616,6 +1616,7 @@ _bfd_s390_elf_create_sframe_plt (struct bfd_link_info *info) 0, /* func start addr. */ plt0_entry_size, func_info, + 0, /* func_info2. */ 0, /* Rep block size. */ 0 /* Num FREs. */); sframe_frame_row_entry plt0_fre; @@ -1644,6 +1645,7 @@ _bfd_s390_elf_create_sframe_plt (struct bfd_link_info *info) plt0_entry_size, /* func start addr. */ dpltsec->size - plt0_entry_size, func_info, + 0, /* func_info2. */ plt_entry_size, 0 /* Num FREs. */); diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 5f610ab3fc1..0e1185993ca 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -1927,6 +1927,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, 0, /* func start addr. */ plt0_entry_size, func_info, + 0, /* func_info2. */ 0, 0 /* Num FREs. */); sframe_frame_row_entry plt0_fre; @@ -1956,6 +1957,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd, plt0_entry_size, /* func start addr. */ dpltsec->size - plt0_entry_size, func_info, + 0, /* func_info2. */ plt_entry_size, 0 /* Num FREs. */); diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 7a124c8196c..e2c3d1fafd8 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -764,6 +764,7 @@ output_sframe_funcdesc (symbolS *start_of_fre_section, else out_one (func_info); out_one (0); + out_one (0); } static void diff --git a/include/sframe-api.h b/include/sframe-api.h index 07454456356..1a3b2c307ba 100644 --- a/include/sframe-api.h +++ b/include/sframe-api.h @@ -183,8 +183,8 @@ sframe_decoder_get_funcdesc_v2 (const sframe_decoder_ctx *ctx, uint8_t *rep_block_size); /* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO, - REP_BLOCK_SIZE) from the SFrame function descriptor entry at the I'th index - in the decoder object DCTX. If failed, return SFRAME_ERR. */ + FUNC_INFO2, REP_BLOCK_SIZE) from the SFrame function descriptor entry at the + I'th index in the decoder object DCTX. If failed, return SFRAME_ERR. */ extern int sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx, unsigned int i, @@ -192,6 +192,7 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx, uint32_t *func_size, int64_t *func_start_address, unsigned char *func_info, + unsigned char *func_info2, uint8_t *rep_block_size); /* SFrame textual dump. */ @@ -308,12 +309,13 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *ectx, uint32_t num_fres); /* Add a new SFrame function descriptor entry with START_ADDR, FUNC_SIZE, - FUNC_INFO and REP_BLOCK_SIZE to the encoder context ECTX. */ + FUNC_INFO, FUNC_INFO2 and REP_BLOCK_SIZE to the encoder context ECTX. */ extern int sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx, int64_t start_addr, uint32_t func_size, unsigned char func_info, + unsigned char func_info2, uint8_t rep_block_size, uint32_t num_fres); diff --git a/include/sframe.h b/include/sframe.h index 75b89b15903..dec3c017a5b 100644 --- a/include/sframe.h +++ b/include/sframe.h @@ -264,6 +264,13 @@ typedef struct sframe_func_desc_entry_v3 --------------------------------------------------------------------------------- 8 7 6 5 4 0 */ uint8_t sfde_func_info; + /* Additional information for stack tracing from the function: + - 8-bits: Unused. + ------------------------------------------------------------------------- + | Unused | + ------------------------------------------------------------------------- + 8 7 6 5 4 0 */ + uint8_t sfde_func_info2; /* Size of the block of repeating insns. Used for SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK. */ uint8_t sfde_func_rep_size; diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c index 56581368aab..eda97b70b78 100644 --- a/libsframe/sframe-dump.c +++ b/libsframe/sframe-dump.c @@ -172,7 +172,8 @@ dump_sframe_func_with_fres (const sframe_decoder_ctx *sfd_ctx, int64_t func_start_addr = 0; sframe_decoder_get_funcdesc_v3 (sfd_ctx, funcidx, &num_fres, &func_size, &func_start_addr, - &func_info, &rep_block_size); + &func_info, NULL, + &rep_block_size); func_start_pc_vma = func_start_addr + sec_addr; } else diff --git a/libsframe/sframe.c b/libsframe/sframe.c index 8d8848fc37f..dd16d3218b9 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -34,6 +34,7 @@ typedef struct sframe_func_desc_entry_int uint32_t func_start_fre_off; uint32_t func_num_fres; uint8_t func_info; + uint8_t func_info2; uint8_t func_rep_size; } ATTRIBUTE_PACKED sframe_func_desc_entry_int; @@ -153,6 +154,7 @@ sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf, fde_tbl->entry[i].func_start_fre_off = fdep->sfde_func_start_fre_off; fde_tbl->entry[i].func_num_fres = (uint16_t)fdep->sfde_func_num_fres; fde_tbl->entry[i].func_info = fdep->sfde_func_info; + fde_tbl->entry[i].func_info2 = fdep->sfde_func_info2; fde_tbl->entry[i].func_rep_size = fdep->sfde_func_rep_size; } fde_tbl->count = num_fdes; @@ -171,6 +173,7 @@ sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf, fde_tbl->entry[i].func_start_fre_off = fdep->sfde_func_start_fre_off; fde_tbl->entry[i].func_num_fres = fdep->sfde_func_num_fres; fde_tbl->entry[i].func_info = fdep->sfde_func_info; + fde_tbl->entry[i].func_info2 = 0; fde_tbl->entry[i].func_rep_size = fdep->sfde_func_rep_size; } fde_tbl->count = num_fdes; @@ -1533,6 +1536,7 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx, uint32_t *func_size, int64_t *func_start_address, unsigned char *func_info, + unsigned char *func_info2, uint8_t *rep_block_size) { int err = 0; @@ -1552,6 +1556,8 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx, *func_size = fdp->func_size; if (func_info) *func_info = fdp->func_info; + if (func_info2) + *func_info2 = fdp->func_info2; if (rep_block_size) *rep_block_size = fdp->func_rep_size; @@ -1991,6 +1997,7 @@ sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx, int64_t start_addr, uint32_t func_size, unsigned char func_info, + unsigned char func_info2, uint8_t rep_block_size, uint32_t num_fres ATTRIBUTE_UNUSED) { @@ -2004,6 +2011,7 @@ sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx, 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_info2 = func_info2; fd_info->entry[fd_info->count-1].func_rep_size = rep_block_size; return 0; @@ -2133,6 +2141,7 @@ sframe_encoder_write_fde (const sframe_header *sfhp ATTRIBUTE_UNUSED, fdep->sfde_func_start_fre_off = fde->func_start_fre_off; fdep->sfde_func_num_fres = (uint16_t)fde->func_num_fres; fdep->sfde_func_info = fde->func_info; + fdep->sfde_func_info2 = fde->func_info2; fdep->sfde_func_rep_size = fde->func_rep_size; *fde_write_size = sizeof (sframe_func_desc_entry_v3); diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2 index 06fd11bd8bf..e297dad35b2 100644 Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ diff --git a/libsframe/testsuite/libsframe.encode/encode-1.c b/libsframe/testsuite/libsframe.encode/encode-1.c index fe2d2543c79..aa3b89e79f1 100644 --- a/libsframe/testsuite/libsframe.encode/encode-1.c +++ b/libsframe/testsuite/libsframe.encode/encode-1.c @@ -40,7 +40,7 @@ add_fde1 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func1_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE1_NUM_FRES); if (err == -1) return err; @@ -76,7 +76,7 @@ add_fde2 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func1_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE1_NUM_FRES); if (err == -1) return err; diff --git a/libsframe/testsuite/libsframe.find/findfre-1.c b/libsframe/testsuite/libsframe.find/findfre-1.c index 848b399f977..58cbbb85e77 100644 --- a/libsframe/testsuite/libsframe.find/findfre-1.c +++ b/libsframe/testsuite/libsframe.find/findfre-1.c @@ -40,7 +40,7 @@ add_fde1 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func1_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE1_NUM_FRES); if (err == -1) return err; @@ -75,7 +75,7 @@ add_fde2 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func2_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE2_NUM_FRES); if (err == -1) return err; diff --git a/libsframe/testsuite/libsframe.find/findfunc-1.c b/libsframe/testsuite/libsframe.find/findfunc-1.c index 27b902ee087..c8d9a0191ed 100644 --- a/libsframe/testsuite/libsframe.find/findfunc-1.c +++ b/libsframe/testsuite/libsframe.find/findfunc-1.c @@ -47,7 +47,7 @@ add_fde1 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func1_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE1_NUM_FRES); if (err == -1) return err; @@ -82,7 +82,7 @@ add_fde2 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func2_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE2_NUM_FRES); if (err == -1) return err; @@ -117,7 +117,7 @@ add_fde3 (sframe_encoder_ctx *encode, int64_t start_pc_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc_v3 (encode, func3_start_addr, - *func_size, finfo, 0, + *func_size, finfo, 0, 0, FDE3_NUM_FRES); if (err == -1) return err; diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c index eb33b7de5cf..5363ac7d1f6 100644 --- a/libsframe/testsuite/libsframe.find/plt-findfre-1.c +++ b/libsframe/testsuite/libsframe.find/plt-findfre-1.c @@ -41,6 +41,7 @@ add_plt_fde1 (sframe_encoder_ctx *ectx, int64_t plt_vaddr, int err = sframe_encoder_add_funcdesc_v3 (ectx, func_start_addr, 16 * 5 /* func size in bytes. */, finfo, + 0, /* func_info2. */ 16 /* rep block size in bytes. */, PLT1_NUM_FRES); if (err == -1) diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-2.c b/libsframe/testsuite/libsframe.find/plt-findfre-2.c index 9ed98553ecc..4cb04bd14c8 100644 --- a/libsframe/testsuite/libsframe.find/plt-findfre-2.c +++ b/libsframe/testsuite/libsframe.find/plt-findfre-2.c @@ -48,6 +48,7 @@ add_plt0_fde (sframe_encoder_ctx *ectx, int64_t plt_vaddr, int err = sframe_encoder_add_funcdesc_v3 (ectx, func_start_addr, PLT_SIZE /* func size. */, finfo, + 0, /* func_info2. */ 0 /* rep block size. */, 1 /* num FREs. */); if (err == -1) @@ -81,6 +82,7 @@ add_pltn_fde (sframe_encoder_ctx *ectx, int64_t plt_vaddr, int err = sframe_encoder_add_funcdesc_v3 (ectx, func_start_addr, 5 * PLT_SIZE /* func size. */, finfo, + 0, /* func_info2. */ PLT_SIZE /* rep block size. */, 1 /* num FREs. */); if (err == -1)