[SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for extensibility in FDE

The existing field func_info (in the SFrame FDE) is used to convey important
information around the encoding and interpretation of the rest of the
stack trace data for the respective SFrame FDE: the SFrame FRE type,
SFrame FDE PC type, etc.

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 func_info2 byte is not used
functionally yet.  Hence, rather mechanical changes in libsframe, bfd
and libsframe/testsuite accompany.  We will put func_info2 into use in a
later patch by reserving 5 of these bits for SFrame FDE types.

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, 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.
This commit is contained in:
Indu Bhagat
2026-01-15 16:42:17 -08:00
parent 5ed153a90a
commit c953fe86fa
14 changed files with 44 additions and 15 deletions

View File

@@ -488,6 +488,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;
@@ -495,7 +496,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. */
@@ -562,7 +563,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);
}

View File

@@ -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. */);

View File

@@ -1917,6 +1917,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;
@@ -1946,6 +1947,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. */);

View File

@@ -755,6 +755,7 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
else
out_one (func_info);
out_one (0);
out_one (0);
}
static void

View File

@@ -182,7 +182,7 @@ sframe_decoder_get_funcdesc_v2 (const sframe_decoder_ctx *ctx,
unsigned char *func_info,
uint8_t *rep_block_size);
/* Get the data (NUM_FRES, FUNC_SIZE, START_PC_OFFSET, FUNC_INFO,
/* Get the data (NUM_FRES, FUNC_SIZE, START_PC_OFFSET, FUNC_INFO, FUNC_INFO2,
REP_BLOCK_SIZE) from the SFrame function descriptor entry at the I'th index
in the decoder object DCTX. Return SFRAME_ERR on failure. */
extern int
@@ -192,6 +192,7 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx,
uint32_t *func_size,
int64_t *start_pc_offset,
unsigned char *func_info,
unsigned char *func_info2,
uint8_t *rep_block_size);
/* SFrame textual dump. */
@@ -308,13 +309,14 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *ectx,
uint32_t num_fres);
/* Add a new SFrame function descriptor entry with START_PC_OFFSET, FUNC_SIZE,
FUNC_INFO and REP_BLOCK_SIZE to the encoder context ECTX. Return error
code on failure. */
FUNC_INFO, FUNC_INFO2 and REP_BLOCK_SIZE to the encoder context ECTX.
Return error code on failure. */
extern int
sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx,
int64_t start_pc_offset,
uint32_t func_size,
unsigned char func_info,
unsigned char func_info2,
uint8_t rep_block_size,
uint32_t num_fres);

View File

@@ -269,6 +269,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 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;

View File

@@ -148,7 +148,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

View File

@@ -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;
} 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 = 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;
@@ -172,6 +174,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;
@@ -1537,6 +1540,7 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx,
uint32_t *func_size,
int64_t *start_pc_offset,
unsigned char *func_info,
unsigned char *func_info2,
uint8_t *rep_block_size)
{
int err = 0;
@@ -1556,6 +1560,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;
@@ -1988,14 +1994,15 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *ectx,
}
/* Add a new SFrame function descriptor entry with START_PC_OFFSET, FUNC_SIZE,
FUNC_INFO and REP_BLOCK_SIZE to the encoder context ECTX. Return error
code on failure. */
FUNC_INFO, FUNC_INFO2 and REP_BLOCK_SIZE to the encoder context ECTX.
Return error code on failure. */
int
sframe_encoder_add_funcdesc_v3 (sframe_encoder_ctx *ectx,
int64_t start_pc_offset,
uint32_t func_size,
unsigned char func_info,
unsigned char func_info2,
uint8_t rep_block_size,
uint32_t num_fres ATTRIBUTE_UNUSED)
{
@@ -2013,6 +2020,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;
@@ -2142,6 +2150,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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)