]> 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>
Mon, 10 Nov 2025 22:44:48 +0000 (14:44 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Tue, 9 Dec 2025 08:26:13 +0000 (00:26 -0800)
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.

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 ba4827819ad4dd00a69e0f1d2e0f8c0836490fdc..f6a332cff5746ee30df41125e90169472c387873 100644 (file)
@@ -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);
        }
index ae609903d80ccd44bc9c4f86c9229caa9f098860..7b2b7c218989938862e90da4e3cdc439f0582775 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 5f610ab3fc126c0e466002d5b75a1d87a494d088..0e1185993cab4d5141deb77750634960593188bf 100644 (file)
@@ -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.  */);
 
index 7a124c8196cd9cad240b6c0ca3e3077a34be9525..e2c3d1fafd8a037848e95862b4f9a49a395fc697 100644 (file)
@@ -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
index 0745445635682589dff09e66aef1cae6203979d6..1a3b2c307ba92939028d639e84b00a37037ba8a0 100644 (file)
@@ -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);
 
index 75b89b15903bef8a527173ad54c933070024ac87..dec3c017a5bd795190f2433fdfa2285c96c0f0ee 100644 (file)
@@ -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;
index 56581368aab4bffb313a6ea12e98d5d864121d4b..eda97b70b781664e5460a085eebdfba6d8520fe0 100644 (file)
@@ -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
index 8d8848fc37f90bcb8ea8b4fc17e99f0f84050a6f..dd16d3218b9abc8082a26f91f606579f4e40c024 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;
 } 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);
index 06fd11bd8bf5423db874283e7a73e2464d981083..e297dad35b2402da62d8ed013f548769857ab4ea 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ
index fe2d2543c79f09d20d20a6b7ecb35609f06c8aa2..aa3b89e79f167b2c809586ced303e14726dffc6f 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 848b399f977f5ef48b20d572bcdf1684fd211dd1..58cbbb85e7795c78ca8fcee7d8354098e80f2197 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 27b902ee087bf4d623bf41e7cb70878b444c1d0c..c8d9a0191ed479b8a7572bad8e9157ef3491cc8b 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 eb33b7de5cf14f217da8453042dbd4c380ccb384..5363ac7d1f68ca09fbd2cb838549e82f4eadf4c0 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 9ed98553ecc8680e496c9018dcc0af6861e611e5..4cb04bd14c8eb25cf1bf3e6a0a54dfa4e71a3105 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)