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 3e19ff48e9c..b31b9055713 100644 Binary files a/libsframe/testsuite/libsframe.decode/DATA-BE and b/libsframe/testsuite/libsframe.decode/DATA-BE differ diff --git a/libsframe/testsuite/libsframe.decode/DATA1 b/libsframe/testsuite/libsframe.decode/DATA1 index 2b3ef8e4e72..1e675398af5 100644 Binary files a/libsframe/testsuite/libsframe.decode/DATA1 and b/libsframe/testsuite/libsframe.decode/DATA1 differ diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2 index 68fc2d240cd..472f736f872 100644 Binary files a/libsframe/testsuite/libsframe.decode/DATA2 and b/libsframe/testsuite/libsframe.decode/DATA2 differ diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c index f6f4fd73d70..cc6e239b6f1 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;