diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index 013a892e08a..1b38768ec71 100644
--- a/bfd/elf-sframe.c
+++ b/bfd/elf-sframe.c
@@ -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);
 	}
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index ffd02f137d1..f224e8f1354 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -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
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index b0bf514be75..7fca83bd610 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -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 ();
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
index aeefbc9cdef..8ae46217117 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
index 985f51fcda9..b7834d53b07 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d
index 666a94101ab..599d4c4e795 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
index 7d97383bb90..32577f31860 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
index fc7d5c440db..3e3f74dbe42 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
index 95954508e3d..6430d463a89 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
index b835980ecbd..319ff96cce2 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
index d2bef7507c2..82d34973ddd 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
index f915ac5f234..fe6917c7080 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
index cab19d5bc25..39724d9cdf1 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
index c0a4a8de250..c0a0e627fad 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d
index bba3b5920f1..ae36c21b3b7 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-1.d b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
index 0b09799826c..141922517f0 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-1.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-2.d b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
index e566c078249..ab8de0b8afa 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-2.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
@@ -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
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-3.d b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
index f7a6062d392..df0b19ee1bd 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-3.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
@@ -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
diff --git a/include/sframe-api.h b/include/sframe-api.h
index 7883b668e31..961ff7eb05f 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -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  *
diff --git a/include/sframe.h b/include/sframe.h
index cdf275f69e4..bef580fd5cb 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -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.  */
diff --git a/ld/testsuite/ld-aarch64/sframe-simple-1.d b/ld/testsuite/ld-aarch64/sframe-simple-1.d
index 6f617153a35..6ab8c2ab46a 100644
--- a/ld/testsuite/ld-aarch64/sframe-simple-1.d
+++ b/ld/testsuite/ld-aarch64/sframe-simple-1.d
@@ -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
diff --git a/ld/testsuite/ld-x86-64/sframe-plt-1.d b/ld/testsuite/ld-x86-64/sframe-plt-1.d
index 06bb16bd482..5e734610b97 100644
--- a/ld/testsuite/ld-x86-64/sframe-plt-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-plt-1.d
@@ -10,7 +10,7 @@
 Contents of the SFrame section .sframe:
   Header :
 
-    Version: SFRAME_VERSION_1
+    Version: SFRAME_VERSION_2
     Flags: SFRAME_F_FDE_SORTED
 #...
 
diff --git a/ld/testsuite/ld-x86-64/sframe-simple-1.d b/ld/testsuite/ld-x86-64/sframe-simple-1.d
index afc0006112e..7f4db31fe1b 100644
--- a/ld/testsuite/ld-x86-64/sframe-simple-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-simple-1.d
@@ -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
 #...
 
diff --git a/libsframe/libsframe.ver b/libsframe/libsframe.ver
index 3e2a5695e93..57f5fb6c378 100644
--- a/libsframe/libsframe.ver
+++ b/libsframe/libsframe.ver
@@ -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;
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
index 4799652f727..bb83528bc79 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -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");
 }
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index cb73a0ca87f..95da010f823 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -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)
 {
diff --git a/libsframe/testsuite/libsframe.decode/DATA-BE b/libsframe/testsuite/libsframe.decode/DATA-BE
index 3e19ff48e9c67f30645a9d8bdca0af834dd345f4..b31b905571313aabe3ac84c334ce0a9e0788225f 100644
GIT binary patch
diff --git a/libsframe/testsuite/libsframe.decode/DATA1 b/libsframe/testsuite/libsframe.decode/DATA1
diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2
index 68fc2d240cd34878747f552d1b12bbc0e59a5217..472f736f872a0bb23b8f075a2b6da8d3aeaabbcd 100644
GIT binary patch
diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c
--- a/libsframe/testsuite/libsframe.find/plt-findfre-1.c
+++ b/libsframe/testsuite/libsframe.find/plt-findfre-1.c
@@ -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;
 
