sframe: bfd: gas: ld: format bump to SFrame version 2
authorIndu Bhagat <indu.bhagat@oracle.com>
Thu, 29 Jun 2023 23:29:09 +0000 (16:29 -0700)
committerIndu Bhagat <indu.bhagat@oracle.com>
Thu, 29 Jun 2023 23:31:58 +0000 (16:31 -0700)
SFrame version 2 encodes the size of repetitive insn block explicitly
in the format.  Add information in the SFrame FDE to convey the size
of the block of repeating instructions.  This information is used only
for SFrame FDEs of type SFRAME_FDE_TYPE_PCMASK.

Introduce two extra bytes for padding: this ensures that the memory
accesses to the members of the SFrame Frame Descriptor Entry (FDE) are
naturally aligned.

gas generates SFrame section with version SFRAME_VERSION_2 by default.

libsframe provides two new APIs to:
  - get an SFrame FDE data from the decoder context, and
  - add an SFrame FDE to the encoder context.
The additional argument (for rep_block_size) is useful for SFrame FDEs
where FDE type is SFRAME_FDE_TYPE_PCMASK.

The linker will generate the output SFrame sections in the
SFRAME_VERSION_2 format.  If the input sections offered to the linker
are not all in the SFRAME_VERSION_2 format, the linker issues an error
to the user.

objdump/readelf will show the following message to the user if .sframe
section in SFRAME_VERSION_1 format is seen:

 "No further information can be displayed.  SFrame version not
 supported."

In other words, like the rest of the binutils, only the current SFrame
format version, i.e., SFRAME_VERSION_2 is supported by the textual dump
facilities.

bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Generate an
output SFrame section with version SFRAME_VERSION_2.  Also,
error out if the SFrame sections do not all have
SFRAME_VERSION_2.
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Generate SFrame
section for plt entries with version SFRAME_VERSION_2.
gas/
* gen-sframe.c (sframe_set_version): Update to SFRAME_VERSION_2.
(output_sframe): Likewise.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-aarch64-1.d: Use SFRAME_VERSION_2.
* gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-1.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-2.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-3.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-4.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-5.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-6.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-7.d: Likewise.
* gas/cfi-sframe/cfi-sframe-common-8.d: Likewise.
* gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise.
* gas/cfi-sframe/common-empty-1.d: Likewise.
* gas/cfi-sframe/common-empty-2.d: Likewise.
* gas/cfi-sframe/common-empty-3.d: Likewise.
ld/testsuite/
* ld-aarch64/sframe-simple-1.d: Adjust for SFRAME_VERSION_2.
* ld-x86-64/sframe-plt-1.d: Likewise.
* ld-x86-64/sframe-simple-1.d: Likewise.
libsframe/
* libsframe.ver: Add the new APIs.
* sframe.c (sframe_decoder_get_funcdesc_v2): New definition.
(sframe_encoder_add_funcdesc_v2): Likewise.
(sframe_header_sanity_check_p): Include SFRAME_VERSION_2.
(sframe_fre_check_range_p): Get rep_block_size info from SFrame
FDE.
* sframe-dump.c (dump_sframe_header): Add support for
SFRAME_VERSION_2.
(dump_sframe): Inform user if SFrame section in SFRAME_VERSION_1
format is seen.
libsframe/testsuite/
* libsframe.decode/DATA-BE: Regenerated data file.
* libsframe.decode/DATA1: Likewise.
* libsframe.decode/DATA2: Likewise.
* libsframe.find/plt-findfre-1.c: Use new API in the testcase.
include/
* sframe.h: Add member to encode size of the code block of
repeating instructions.  Add 2 bytes of padding.
* sframe-api.h (sframe_decoder_get_funcdesc_v2): New
declaration.
(sframe_encoder_add_funcdesc_v2): Likewise.

30 files changed:
bfd/elf-sframe.c
bfd/elfxx-x86.c
gas/gen-sframe.c
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d
gas/testsuite/gas/cfi-sframe/common-empty-1.d
gas/testsuite/gas/cfi-sframe/common-empty-2.d
gas/testsuite/gas/cfi-sframe/common-empty-3.d
include/sframe-api.h
include/sframe.h
ld/testsuite/ld-aarch64/sframe-simple-1.d
ld/testsuite/ld-x86-64/sframe-plt-1.d
ld/testsuite/ld-x86-64/sframe-simple-1.d
libsframe/libsframe.ver
libsframe/sframe-dump.c
libsframe/sframe.c
libsframe/testsuite/libsframe.decode/DATA-BE
libsframe/testsuite/libsframe.decode/DATA1
libsframe/testsuite/libsframe.decode/DATA2
libsframe/testsuite/libsframe.find/plt-findfre-1.c

index 013a892e08a40b1c1face56aa15f6fdb2e342df6..1b38768ec719b7984f0452b3374d8c8961ce8838 100644 (file)
@@ -328,6 +328,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
   uint8_t sfd_ctx_abi_arch;
   int8_t sfd_ctx_fixed_fp_offset;
   int8_t sfd_ctx_fixed_ra_offset;
+  uint8_t dctx_version;
+  uint8_t ectx_version;
   int encerr = 0;
 
   struct elf_link_hash_table *htab;
@@ -361,7 +363,7 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
       if (!sfd_ctx_abi_arch)
        return false;
 
-      htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_1,
+      htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
                                              0, /* SFrame flags.  */
                                              sfd_ctx_abi_arch,
                                              sfd_ctx_fixed_fp_offset,
@@ -400,6 +402,18 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
       return false;
     }
 
+  /* Check that all .sframe sections being linked have the same version.  */
+  dctx_version = sframe_decoder_get_version (sfd_ctx);
+  ectx_version = sframe_encoder_get_version (sfe_ctx);
+  if (dctx_version != SFRAME_VERSION_2 || dctx_version != ectx_version)
+    {
+      _bfd_error_handler
+       (_("input SFrame sections with different format versions prevent"
+         " .sframe generation"));
+      return false;
+    }
+
+
   /* Iterate over the function descriptor entries and the FREs of the
      function from the decoder context.  Add each of them to the encoder
      context, if suitable.  */
@@ -411,16 +425,18 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
   for (i = 0; i < num_fidx; i++)
     {
       unsigned int num_fres = 0;
-      int32_t func_start_address;
+      int32_t func_start_addr;
       bfd_vma address;
       uint32_t func_size = 0;
       unsigned char func_info = 0;
       unsigned int r_offset = 0;
       bool pltn_reloc_by_hand = false;
       unsigned int pltn_r_offset = 0;
+      uint8_t rep_block_size = 0;
 
-      if (!sframe_decoder_get_funcdesc (sfd_ctx, i, &num_fres, &func_size,
-                                       &func_start_address, &func_info))
+      if (!sframe_decoder_get_funcdesc_v2 (sfd_ctx, i, &num_fres, &func_size,
+                                          &func_start_addr, &func_info,
+                                          &rep_block_size))
        {
          /* If function belongs to a deleted section, skip editing the
             function descriptor entry.  */
@@ -471,13 +487,13 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
              /* FIXME For testing only. Cleanup later.  */
              // address += (sec->output_section->vma);
 
-             func_start_address = address;
+             func_start_addr = address;
            }
 
          /* Update the encoder context with updated content.  */
-         int err = sframe_encoder_add_funcdesc (sfe_ctx, func_start_address,
-                                                func_size, func_info,
-                                                num_fres);
+         int err = sframe_encoder_add_funcdesc_v2 (sfe_ctx, func_start_addr,
+                                                   func_size, func_info,
+                                                   rep_block_size, num_fres);
          cur_fidx++;
          BFD_ASSERT (!err);
        }
index ffd02f137d1d07b7b70c5034c3cfe890db5c8360..f224e8f1354dfa76e1a0b3d6bd3944930f9ae597 100644 (file)
@@ -1883,7 +1883,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
       break;
     }
 
-  *ectx = sframe_encode (SFRAME_VERSION_1,
+  *ectx = sframe_encode (SFRAME_VERSION_2,
                         0,
                         SFRAME_ABI_AMD64_ENDIAN_LITTLE,
                         SFRAME_CFA_FIXED_FP_INVALID,
@@ -1900,11 +1900,12 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
     {
       /* Add SFrame FDE for plt0, the function start address is updated later
         at _bfd_elf_merge_section_sframe time.  */
-      sframe_encoder_add_funcdesc (*ectx,
-                                  0, /* func start addr.  */
-                                  plt0_entry_size,
-                                  func_info,
-                                  0 /* Num FREs.  */);
+      sframe_encoder_add_funcdesc_v2 (*ectx,
+                                     0, /* func start addr.  */
+                                     plt0_entry_size,
+                                     func_info,
+                                     16,
+                                     0 /* Num FREs.  */);
       sframe_frame_row_entry plt0_fre;
       unsigned int num_plt0_fres = htab->sframe_plt->plt0_num_fres;
       for (unsigned int j = 0; j < num_plt0_fres; j++)
@@ -1928,11 +1929,12 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
         function start address = plt0_entry_size.  As usual, this will be
         updated later at _bfd_elf_merge_section_sframe, by when the
         sections are relocated.  */
-      sframe_encoder_add_funcdesc (*ectx,
-                                  plt0_entry_size, /* func start addr.  */
-                                  dpltsec->size - plt0_entry_size,
-                                  func_info,
-                                  0 /* Num FREs.  */);
+      sframe_encoder_add_funcdesc_v2 (*ectx,
+                                     plt0_entry_size, /* func start addr.  */
+                                     dpltsec->size - plt0_entry_size,
+                                     func_info,
+                                     16,
+                                     0 /* Num FREs.  */);
 
       sframe_frame_row_entry pltn_fre;
       /* Now add the FREs for pltn.  Simply adding the two FREs suffices due
index b0bf514be75171ffbbb3c47f24d1536632ee4797..7fca83bd610ba6f8d06bcf048e050a64c1f1615b 100644 (file)
@@ -278,7 +278,10 @@ sframe_v1_set_func_info (unsigned int fde_type, unsigned int fre_type,
 static void
 sframe_set_version (uint32_t sframe_version ATTRIBUTE_UNUSED)
 {
-  sframe_ver_ops.format_version = SFRAME_VERSION_1;
+  sframe_ver_ops.format_version = SFRAME_VERSION_2;
+
+  /* These operations remain the same for SFRAME_VERSION_2 as fre_info and
+     func_info have not changed from SFRAME_VERSION_1.  */
 
   sframe_ver_ops.set_fre_info = sframe_v1_set_fre_info;
 
@@ -605,6 +608,8 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
 #else
   out_one (func_info);
 #endif
+  out_one (0);
+  out_two (0);
 }
 
 static void
@@ -1355,7 +1360,7 @@ output_sframe (segT sframe_seg)
   (void) sframe_seg;
 
   /* Setup the version specific access functions.  */
-  sframe_set_version (SFRAME_VERSION_1);
+  sframe_set_version (SFRAME_VERSION_2);
 
   /* Process all fdes and create SFrame stack trace information.  */
   create_sframe_all ();
index aeefbc9cdef3efb1fb404688f3999aa80e7ccbb0..8ae46217117c6bd0bca905f8be19987cafd34041 100644 (file)
@@ -5,7 +5,7 @@
 Contents of the SFrame section .sframe:
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 3
index 985f51fcda9abd3d6d805be00453d9a797fa9698..b7834d53b075c138dc90213cabc0c78ec1146ba7 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 2
index 666a94101ab8547fc856617893d4d858c0477259..599d4c4e795c8af50018bd03cf0653175379f433 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 2
     Num FREs: 6
index 7d97383bb902ee33c383c333a427e044e83ec402..32577f31860eef52eb8f5f63c91a85332755eb8f 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 1
index fc7d5c440dbcb0aac0dc4873896ab08d1a2ec1e0..3e3f74dbe4240b30fec372c2e40975622845b352 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 1
index 95954508e3d83c53554f465e528dba0de82e36fd..6430d463a891bf841b27a221b897c29df7e99882 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 1
index b835980ecbd241fa4ba29b49634753629b404954..319ff96cce2a67aac0859891f8c2a3878a530216 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 3
index d2bef7507c2b63618c1b2ddbb9b250f8712e5705..82d34973dddecb42892deea9ee0b8a6b5b62c2de 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 3
index f915ac5f234534584033a66ff3b0568875e0bfcb..fe6917c70800a89a7f7ccbfb4edb18e250a43d32 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 3
index cab19d5bc256a478f1f1172ed7579c0d5161ab0d..39724d9cdf198f94a6d74a48e101e93fbbc05661 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 3
index c0a4a8de250a3fa78ab4d083aa3a456a66be6c4a..c0a0e627fad931e2ec35afc719f9d41cf388d7ff 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 2
index bba3b5920f177056ea4db1629aeaed45f119dadb..ae36c21b3b7c12b8680deabcef94b2fba6559151 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 1
     Num FREs: 4
index 0b09799826c034c1b64dd27c5af9298895b2ce6f..141922517f0d9580f7d2a8bdf0ea743982887729 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 0
     Num FREs: 0
index e566c078249c4b709a05a859e512349fae9b8787..ab8de0b8afa333f927db232d9a0bebc04520efb8 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 0
     Num FREs: 0
index f7a6062d3926f7d13e0458ce3c919bd5dd70ada5..df0b19ee1bd13aad299f92b46d3098c65987b003 100644 (file)
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
 
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: NONE
     Num FDEs: 0
     Num FREs: 0
index 7883b668e3183d69524683e9d165cb5a4fb27613..961ff7eb05ff1edf88451418339a5489d40fd74d 100644 (file)
@@ -172,6 +172,19 @@ sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx,
                             int32_t *func_start_address,
                             unsigned char *func_info);
 
+/* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO,
+   REP_BLOCK_SIZE) from the function descriptor entry at index I'th
+   in the decoder CTX.  If failed, return error code.
+   This API is only available from SFRAME_VERSION_2.  */
+extern int
+sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx,
+                               unsigned int i,
+                               uint32_t *num_fres,
+                               uint32_t *func_size,
+                               int32_t *func_start_address,
+                               unsigned char *func_info,
+                               uint8_t *rep_block_size);
+
 /* SFrame textual dump.  */
 extern void
 dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr);
@@ -246,6 +259,16 @@ sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder,
                             unsigned char func_info,
                             uint32_t num_fres);
 
+/* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO
+   and REP_BLOCK_SIZE to the encoder.  */
+extern int
+sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder,
+                               int32_t start_addr,
+                               uint32_t func_size,
+                               unsigned char func_info,
+                               uint8_t rep_block_size,
+                               uint32_t num_fres);
+
 /* Serialize the contents of the encoder and return the buffer.  ENCODED_SIZE
    is updated to the size of the buffer.  Sets ERRP if failure.  */
 extern char  *
index cdf275f69e494e75373559d8b95e8d9176fbe873..bef580fd5cb1297d30ee201398bbfa026dc1825b 100644 (file)
@@ -73,10 +73,11 @@ extern "C"
 
 /* SFrame format versions.  */
 #define SFRAME_VERSION_1       1
+#define SFRAME_VERSION_2       2
 /* SFrame magic number.  */
 #define SFRAME_MAGIC           0xdee2
 /* Current version of SFrame format.  */
-#define SFRAME_VERSION SFRAME_VERSION_1
+#define SFRAME_VERSION SFRAME_VERSION_2
 
 /* Various flags for SFrame.  */
 
@@ -193,6 +194,10 @@ typedef struct sframe_func_desc_entry
      ------------------------------------------------------------------------
      8               6                             5           4              0     */
   uint8_t sfde_func_info;
+  /* Size of the block of repeating insns.  Used for SFrame FDEs of type
+     SFRAME_FDE_TYPE_PCMASK.  */
+  uint8_t sfde_func_rep_size;
+  uint16_t sfde_func_padding2;
 } ATTRIBUTE_PACKED sframe_func_desc_entry;
 
 /* Macros to compose and decompose function info in FDE.  */
index 6f617153a359e152d74b32299d1178f7c9c1c4a7..6ab8c2ab46ac47c1f7eb87e50d59632dca496028 100644 (file)
@@ -3,14 +3,14 @@
 #source: sframe-bar.s
 #objdump: --sframe=.sframe
 #ld: -shared
-#name: SFrame Simple link
+#name: SFrame simple link
 
 .*:     file format .*
 
 Contents of the SFrame section .sframe:
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: SFRAME_F_FDE_SORTED
     Num FDEs: 2
     Num FREs: 2
index 06bb16bd482f4d7ad43e0e3466d543cbd6e91abb..5e734610b97097f929fd136a23e14a97869b3d74 100644 (file)
@@ -10,7 +10,7 @@
 Contents of the SFrame section .sframe:
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: SFRAME_F_FDE_SORTED
 #...
 
index afc0006112e3d2bb35eceba0b61324b08dc90d39..7f4db31fe1b71e422bf0f51ae0461be9a5454c2a 100644 (file)
@@ -3,14 +3,14 @@
 #source: sframe-bar.s
 #objdump: --sframe=.sframe
 #ld: -shared
-#name: SFrame Simple link
+#name: SFrame simple link
 
 .*: +file format .*
 
 Contents of the SFrame section .sframe:
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: SFRAME_F_FDE_SORTED
 #...
 
index 3e2a5695e93226d7638ca28b6dc0a795600c1418..57f5fb6c3786ec6cc6496871efcd4210048e0e37 100644 (file)
@@ -20,6 +20,7 @@ LIBSFRAME_1.0 {
     sframe_find_fre;
     sframe_decoder_get_num_fidx;
     sframe_decoder_get_funcdesc;
+    sframe_decoder_get_funcdesc_v2;
     sframe_decoder_get_fre;
     sframe_encode;
     sframe_encoder_free;
@@ -29,6 +30,7 @@ LIBSFRAME_1.0 {
     sframe_encoder_get_num_fidx;
     sframe_encoder_add_fre;
     sframe_encoder_add_funcdesc;
+    sframe_encoder_add_funcdesc_v2;
     sframe_encoder_write;
     dump_sframe;
     sframe_errmsg;
index 4799652f727eb6935c6a4ead6ee5f7d3a1d4c076..bb83528bc7991fdc2290d49c8abb771151fbe343 100644 (file)
@@ -43,27 +43,33 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx)
 static void
 dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
 {
-  const char *verstr = NULL;
+  uint8_t ver;
+  uint8_t flags;
+  char *flags_str;
+  const char *ver_str = NULL;
   const sframe_header *header = &(sfd_ctx->sfd_header);
 
   /* Prepare SFrame section version string.  */
   const char *version_names[]
     = { "NULL",
-       "SFRAME_VERSION_1" };
-  unsigned char ver = header->sfh_preamble.sfp_version;
+       "SFRAME_VERSION_1",
+       "SFRAME_VERSION_2" };
+
+  /* PS: Keep SFRAME_HEADER_FLAGS_STR_MAX_LEN in sync if adding more members to
+     this array.  */
+  const char *flag_names[]
+    = { "SFRAME_F_FDE_SORTED",
+       "SFRAME_F_FRAME_POINTER" };
+
+  ver = sframe_decoder_get_version (sfd_ctx);
   if (ver <= SFRAME_VERSION)
-    verstr = version_names[ver];
+    ver_str = version_names[ver];
 
   /* Prepare SFrame section flags string.  */
-  unsigned char flags = header->sfh_preamble.sfp_flags;
-  char *flags_str
-    = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN);
+  flags = header->sfh_preamble.sfp_flags;
+  flags_str = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN);
   if (flags)
     {
-      const char *flag_names[]
-       = { "SFRAME_F_FDE_SORTED",
-           "SFRAME_F_FRAME_POINTER" };
-      unsigned char flags = header->sfh_preamble.sfp_flags;
       if (flags & SFRAME_F_FDE_SORTED)
        strcpy (flags_str, flag_names[0]);
       if (flags & SFRAME_F_FRAME_POINTER)
@@ -80,9 +86,9 @@ dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
   printf ("\n");
   printf ("  %s :\n", subsec_name);
   printf ("\n");
-  printf ("    Version: %s\n", verstr);
+  printf ("    Version: %s\n", ver_str);
   printf ("    Flags: %s\n", flags_str);
-  printf ("    Num FDEs: %d\n", header->sfh_num_fdes);
+  printf ("    Num FDEs: %d\n", sframe_decoder_get_num_fidx (sfd_ctx));
   printf ("    Num FREs: %d\n", header->sfh_num_fres);
 
   free (flags_str);
@@ -203,6 +209,14 @@ dump_sframe_functions (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr)
 void
 dump_sframe (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr)
 {
+  uint8_t ver;
+
   dump_sframe_header (sfd_ctx);
-  dump_sframe_functions (sfd_ctx, sec_addr);
+
+  ver = sframe_decoder_get_version (sfd_ctx);
+  if (ver == SFRAME_VERSION)
+    dump_sframe_functions (sfd_ctx, sec_addr);
+  else
+    printf ("\n No further information can be displayed.  %s",
+           "SFrame version not supported\n");
 }
index cb73a0ca87f1cddf4eb3845c66bb311e8a58df56..95da010f823b5ac76341ec1cafe2462b2b7afa34 100644 (file)
@@ -206,9 +206,10 @@ sframe_header_sanity_check_p (sframe_header *hp)
 {
   unsigned char all_flags = SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER;
   /* Check preamble is valid.  */
-  if ((hp->sfh_preamble.sfp_magic != SFRAME_MAGIC)
-      || (hp->sfh_preamble.sfp_version != SFRAME_VERSION)
-      || ((hp->sfh_preamble.sfp_flags | all_flags) != all_flags))
+  if (hp->sfh_preamble.sfp_magic != SFRAME_MAGIC
+      || (hp->sfh_preamble.sfp_version != SFRAME_VERSION_1
+         && hp->sfh_preamble.sfp_version != SFRAME_VERSION_2)
+      || (hp->sfh_preamble.sfp_flags | all_flags) != all_flags)
     return false;
 
   /* Check offsets are valid.  */
@@ -373,16 +374,13 @@ sframe_fre_check_range_p (sframe_func_desc_entry *fdep,
 {
   int32_t start_ip, end_ip;
   int32_t func_start_addr;
-  uint32_t rep_block_size;
+  uint8_t rep_block_size;
   uint32_t fde_type;
   int32_t masked_pc;
   bool mask_p;
   bool ret;
 
   ret = false;
-  /* FIXME - the rep_block_size should be encoded in the format somehow.  For
-     AMD64, each pltN entry stub in .plt is 16 bytes.  */
-  rep_block_size = 16;
 
   if (!fdep)
     return ret;
@@ -390,6 +388,7 @@ sframe_fre_check_range_p (sframe_func_desc_entry *fdep,
   func_start_addr = fdep->sfde_func_start_address;
   fde_type = sframe_get_fde_type (fdep);
   mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK);
+  rep_block_size = fdep->sfde_func_rep_size;
 
   if (!mask_p)
     {
@@ -1208,6 +1207,36 @@ sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx,
   return 0;
 }
 
+int
+sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *dctx,
+                               unsigned int i,
+                               uint32_t *num_fres,
+                               uint32_t *func_size,
+                               int32_t *func_start_address,
+                               unsigned char *func_info,
+                               uint8_t *rep_block_size)
+{
+  sframe_func_desc_entry *fdp;
+  int err = 0;
+
+  if (dctx == NULL || func_start_address == NULL
+      || num_fres == NULL || func_size == NULL
+      || sframe_decoder_get_version (dctx) == SFRAME_VERSION_1)
+    return sframe_set_errno (&err, SFRAME_ERR_INVAL);
+
+  fdp = sframe_decoder_get_funcdesc_at_index (dctx, i);
+
+  if (fdp == NULL)
+    return sframe_set_errno (&err, SFRAME_ERR_FDE_NOTFOUND);
+
+  *num_fres = fdp->sfde_func_num_fres;
+  *func_start_address = fdp->sfde_func_start_address;
+  *func_size = fdp->sfde_func_size;
+  *func_info = fdp->sfde_func_info;
+  *rep_block_size = fdp->sfde_func_rep_size;
+
+  return 0;
+}
 /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function
    descriptor entry in the SFrame decoder CTX.  Returns error code as
    applicable.  */
@@ -1579,6 +1608,37 @@ bad:
   return -1;
 }
 
+/* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO
+   and REP_BLOCK_SIZE to the encoder.
+
+   This API is valid only for SFrame format version 2.  */
+
+int
+sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder,
+                               int32_t start_addr,
+                               uint32_t func_size,
+                               unsigned char func_info,
+                               uint8_t rep_block_size,
+                               uint32_t num_fres __attribute__ ((unused)))
+{
+  sf_fde_tbl *fd_info;
+  int err;
+
+  if (encoder == NULL
+      || sframe_encoder_get_version (encoder) == SFRAME_VERSION_1)
+    return sframe_set_errno (&err, SFRAME_ERR_INVAL);
+
+  err = sframe_encoder_add_funcdesc (encoder, start_addr, func_size, func_info,
+                                    num_fres);
+  if (err)
+    return SFRAME_ERR;
+
+  fd_info = encoder->sfe_funcdesc;
+  fd_info->entry[fd_info->count-1].sfde_func_rep_size = rep_block_size;
+
+  return 0;
+}
+
 static int
 sframe_sort_funcdesc (sframe_encoder_ctx *encoder)
 {
index 3e19ff48e9c67f30645a9d8bdca0af834dd345f4..b31b905571313aabe3ac84c334ce0a9e0788225f 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA-BE and b/libsframe/testsuite/libsframe.decode/DATA-BE differ
index 2b3ef8e4e727ac30c993903a320698bbd6e098b9..1e675398af503ffea686f989b283b07329ee9dea 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA1 and b/libsframe/testsuite/libsframe.decode/DATA1 differ
index 68fc2d240cd34878747f552d1b12bbc0e59a5217..472f736f872a0bb23b8f075a2b6da8d3aeaabbcd 100644 (file)
Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ
index f6f4fd73d70f92e24a5f653053f4726aaae5dd3f..cc6e239b6f1a3f7a7db96831fe4bfeab927fdb1d 100644 (file)
@@ -42,7 +42,7 @@ add_plt_fde1 (sframe_encoder_ctx *ectx, int idx)
   unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
                                                     SFRAME_FDE_TYPE_PCMASK);
   /* 5 pltN entries of 16 bytes each.  */
-  err = sframe_encoder_add_funcdesc (ectx, 0x1000, 16*5, finfo, 3);
+  err = sframe_encoder_add_funcdesc_v2 (ectx, 0x1000, 16*5, finfo, 16, 3);
   if (err == -1)
     return err;