]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[SFrame-V3] include: gas: libsframe: add 8-bits of func_info2 for extensibility in FDE
authorIndu Bhagat <indu.bhagat@oracle.com>
Fri, 16 Jan 2026 00:42:17 +0000 (16:42 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Fri, 16 Jan 2026 01:02:25 +0000 (17:02 -0800)
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.

14 files changed:
bfd/elf-sframe.c
bfd/elf64-s390.c
bfd/elfxx-x86.c
gas/gen-sframe.c
include/sframe-api.h
include/sframe.h
libsframe/sframe-dump.c
libsframe/sframe.c
libsframe/testsuite/libsframe.decode/DATA2
libsframe/testsuite/libsframe.encode/encode-1.c
libsframe/testsuite/libsframe.find/findfre-1.c
libsframe/testsuite/libsframe.find/findfunc-1.c
libsframe/testsuite/libsframe.find/plt-findfre-1.c
libsframe/testsuite/libsframe.find/plt-findfre-2.c

index 8842efe6fe672dae7e678861364b996737d92c58..1ef53120543019768bea53a8ee9da526c4ceb358 100644 (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);
        }
index dbeee7f66e44100778097b83e1d3aea0e665f9e0..c172b9b52875def8f844653c9e6b9628616496bf 100644 (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.  */);
 
index ae6c96d77df46134acd5757aa1b2fd4dab538bc5..58b12e2b372060bba18c516f8e28e025bc00b672 100644 (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.  */);
 
index 6818407683acd039661133dd5a34e0fc05bd68a6..132cb2ff33e7369ea59d960e880ec12c19a4f17b 100644 (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
index 71130eb12f1d0956ea4dabfa562d9d8b97de0b8d..07de850017a1c8098b8ec47363ca312e8c28b55f 100644 (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);
 
index 8e3510fdd8643744e8b90716618e95ae99dc04ca..3b656663ce2da0e6e91a28ae7c473a7f04c39f31 100644 (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;
index 394dbdc91582a24dce35b8deacfafa7ad476c519..d36731728fa0ac32a10f6b425d514987edc5d21e 100644 (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
index 292058f7c1773d5a39444fe5b28153aee5e72648..e8f499bd7f364fb738200d32ea3c34f75b758643 100644 (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);
index 06fd11bd8bf5423db874283e7a73e2464d981083..e297dad35b2402da62d8ed013f548769857ab4ea 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ
index 284177df8050ec0152f6770f20883c063dc8bbe2..53f15e68bac6cc54971d4ad026484713e0fd979c 100644 (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;
index 996a943e6798ab24c240a047ff39e4a1e333fbbd..b63c3651a87585b5a6e55cdfcd2742a913fb245a 100644 (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;
index 364c9673ba47cbe94f1452aa49f1f0c4ad94a661..7d2c46b8b51ea2754975a419581ac0915215ef92 100644 (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;
index c2a5e2f8de92a805e1d68f076c3a70c90d847e56..7368cc61fcbf5946b03178af03ab18000f1cc8d4 100644 (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)
index c1ad7f085057e90ed7077a1e5db032f726c95df7..e6f317a757df6372dabcc830a2c3c0fc80b0843f 100644 (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)