mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 01:53:38 +08:00
sframe: bfd: gas: ld: format bump to SFrame version 2
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.
This commit is contained in:
parent
9f71b60bd4
commit
ce9a87252c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -10,7 +10,7 @@
|
||||
Contents of the SFrame section .sframe:
|
||||
Header :
|
||||
|
||||
Version: SFRAME_VERSION_1
|
||||
Version: SFRAME_VERSION_2
|
||||
Flags: SFRAME_F_FDE_SORTED
|
||||
#...
|
||||
|
||||
|
@ -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
|
||||
#...
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user