aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elf-sframe.c32
-rw-r--r--bfd/elfxx-x86.c24
-rw-r--r--gas/gen-sframe.c9
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-3.d2
-rw-r--r--include/sframe-api.h23
-rw-r--r--include/sframe.h7
-rw-r--r--ld/testsuite/ld-aarch64/sframe-simple-1.d4
-rw-r--r--ld/testsuite/ld-x86-64/sframe-plt-1.d2
-rw-r--r--ld/testsuite/ld-x86-64/sframe-simple-1.d4
-rw-r--r--libsframe/libsframe.ver2
-rw-r--r--libsframe/sframe-dump.c42
-rw-r--r--libsframe/sframe.c74
-rw-r--r--libsframe/testsuite/libsframe.decode/DATA-BEbin64 -> 67 bytes
-rw-r--r--libsframe/testsuite/libsframe.decode/DATA1bin60 -> 63 bytes
-rw-r--r--libsframe/testsuite/libsframe.decode/DATA2bin92 -> 98 bytes
-rw-r--r--libsframe/testsuite/libsframe.find/plt-findfre-1.c2
30 files changed, 191 insertions, 64 deletions
diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index 013a892..1b38768 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 ffd02f1..f224e8f 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 b0bf514..7fca83b 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 aeefbc9..8ae4621 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 985f51f..b7834d5 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 666a941..599d4c4 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 7d97383..32577f3 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 fc7d5c4..3e3f74d 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 9595450..6430d46 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 b835980..319ff96 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 d2bef75..82d3497 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 f915ac5..fe6917c 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 cab19d5..39724d9 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 c0a4a8de..c0a0e62 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 bba3b59..ae36c21 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 0b09799..1419225 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 e566c07..ab8de0b 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 f7a6062..df0b19e 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 7883b66..961ff7e 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 cdf275f..bef580f 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 6f61715..6ab8c2a 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 06bb16b..5e73461 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 afc0006..7f4db31 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 3e2a569..57f5fb6 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 4799652..bb83528 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 cb73a0c..95da010 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 3e19ff4..b31b905 100644
--- a/libsframe/testsuite/libsframe.decode/DATA-BE
+++ b/libsframe/testsuite/libsframe.decode/DATA-BE
Binary files differ
diff --git a/libsframe/testsuite/libsframe.decode/DATA1 b/libsframe/testsuite/libsframe.decode/DATA1
index 2b3ef8e..1e67539 100644
--- a/libsframe/testsuite/libsframe.decode/DATA1
+++ b/libsframe/testsuite/libsframe.decode/DATA1
Binary files differ
diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2
index 68fc2d2..472f736 100644
--- a/libsframe/testsuite/libsframe.decode/DATA2
+++ b/libsframe/testsuite/libsframe.decode/DATA2
Binary files differ
diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c
index f6f4fd7..cc6e239 100644
--- 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;