mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-08 00:23:09 +00:00
libsframe: make flip_fde version aware
Future versions of the format may have a different representation of an
SFrame FDE. As the format evolves, endian flipping will need to be version
aware.
Refactor flip_fde a bit by carving out an internal sframe_decode_fde API
which can read information from an on-disk SFrame FDE.
libsframe/
* sframe.c (flip_fde): Make version aware.
(sframe_decode_fde): New internal definition.
(flip_sframe): Use the new definitions.
This commit is contained in:
@@ -198,13 +198,34 @@ flip_header (sframe_header *sfheader)
|
|||||||
swap_thing (sfheader->sfh_freoff);
|
swap_thing (sfheader->sfh_freoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Endian flip the SFrame FDE at BUF (buffer size provided in BUF_SIZE), given
|
||||||
flip_fde (sframe_func_desc_entry *fdep)
|
the SFrame version VER. Update the FDE_SIZE to the size of the SFrame FDE
|
||||||
|
flipped.
|
||||||
|
|
||||||
|
Return SFRAME_ERR if any error. If error code is returned, the flipped FDEP
|
||||||
|
should not be used. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
flip_fde (char *buf, size_t buf_size, uint8_t ver, size_t *fde_size)
|
||||||
{
|
{
|
||||||
swap_thing (fdep->sfde_func_start_address);
|
|
||||||
swap_thing (fdep->sfde_func_size);
|
if (ver == SFRAME_VERSION_2)
|
||||||
swap_thing (fdep->sfde_func_start_fre_off);
|
{
|
||||||
swap_thing (fdep->sfde_func_num_fres);
|
if (buf_size < sizeof (sframe_func_desc_entry_v2))
|
||||||
|
return SFRAME_ERR;
|
||||||
|
|
||||||
|
sframe_func_desc_entry_v2 *fdep = (sframe_func_desc_entry_v2 *) buf;
|
||||||
|
swap_thing (fdep->sfde_func_start_address);
|
||||||
|
swap_thing (fdep->sfde_func_size);
|
||||||
|
swap_thing (fdep->sfde_func_start_fre_off);
|
||||||
|
swap_thing (fdep->sfde_func_num_fres);
|
||||||
|
|
||||||
|
*fde_size = sizeof (sframe_func_desc_entry_v2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SFRAME_ERR; /* No other versions are possible ATM. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if SFrame header has valid data. */
|
/* Check if SFrame header has valid data. */
|
||||||
@@ -428,6 +449,35 @@ sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx,
|
|||||||
return (start_ip_offset <= pc_offset) && (end_ip_offset >= pc_offset);
|
return (start_ip_offset <= pc_offset) && (end_ip_offset >= pc_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read the on-disk SFrame FDE of SFrame version VER from location BUF of size
|
||||||
|
in bytes equal to BUF_SIZE.
|
||||||
|
|
||||||
|
Return SFRAME_ERR if any error. If error code is returned, the read values
|
||||||
|
should not be used. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
sframe_decode_fde (const char *buf, size_t buf_size, uint8_t ver,
|
||||||
|
uint32_t *num_fres, uint32_t *fre_type,
|
||||||
|
uint32_t *fre_offset, size_t *fde_size)
|
||||||
|
{
|
||||||
|
if (ver == SFRAME_VERSION_2)
|
||||||
|
{
|
||||||
|
if (buf_size < sizeof (sframe_func_desc_entry_v2))
|
||||||
|
return SFRAME_ERR;
|
||||||
|
|
||||||
|
sframe_func_desc_entry_v2 *fdep = (sframe_func_desc_entry_v2 *) buf;
|
||||||
|
*num_fres = fdep->sfde_func_num_fres;
|
||||||
|
*fre_type = sframe_get_fre_type (fdep);
|
||||||
|
*fre_offset = fdep->sfde_func_start_fre_off;
|
||||||
|
|
||||||
|
*fde_size = sizeof (sframe_func_desc_entry_v2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return SFRAME_ERR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
flip_fre (char *fp, uint32_t fre_type, size_t *fre_size)
|
flip_fre (char *fp, uint32_t fre_type, size_t *fre_size)
|
||||||
{
|
{
|
||||||
@@ -477,14 +527,16 @@ flip_sframe (char *frame_buf, size_t buf_size, uint32_t to_foreign)
|
|||||||
{
|
{
|
||||||
unsigned int i, j, prev_frep_index;
|
unsigned int i, j, prev_frep_index;
|
||||||
const sframe_header *ihp;
|
const sframe_header *ihp;
|
||||||
|
uint8_t ver;
|
||||||
char *fdes;
|
char *fdes;
|
||||||
|
char *fres;
|
||||||
|
const char *buf_end;
|
||||||
char *fp = NULL;
|
char *fp = NULL;
|
||||||
sframe_func_desc_entry *fdep;
|
|
||||||
unsigned int num_fdes = 0;
|
unsigned int num_fdes = 0;
|
||||||
unsigned int num_fres = 0;
|
uint32_t num_fres = 0;
|
||||||
uint32_t fre_type = 0;
|
uint32_t fre_type = 0;
|
||||||
uint32_t fre_offset = 0;
|
uint32_t fre_offset = 0;
|
||||||
size_t esz = 0;
|
size_t esz = 0, fsz = 0;
|
||||||
size_t hdrsz = 0;
|
size_t hdrsz = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
/* For error checking. */
|
/* For error checking. */
|
||||||
@@ -500,35 +552,34 @@ flip_sframe (char *frame_buf, size_t buf_size, uint32_t to_foreign)
|
|||||||
FDEs and the first FDE in the buffer. */
|
FDEs and the first FDE in the buffer. */
|
||||||
hdrsz = sframe_get_hdr_size (ihp);
|
hdrsz = sframe_get_hdr_size (ihp);
|
||||||
num_fdes = ihp->sfh_num_fdes;
|
num_fdes = ihp->sfh_num_fdes;
|
||||||
|
ver = ihp->sfh_preamble.sfp_version;
|
||||||
fdes = frame_buf + hdrsz + ihp->sfh_fdeoff;
|
fdes = frame_buf + hdrsz + ihp->sfh_fdeoff;
|
||||||
fdep = (sframe_func_desc_entry *)fdes;
|
fres = frame_buf + hdrsz + ihp->sfh_freoff;
|
||||||
|
buf_end = frame_buf + buf_size;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
prev_frep_index = 0;
|
prev_frep_index = 0;
|
||||||
for (i = 0; i < num_fdes; fdep++, i++)
|
for (i = 0; i < num_fdes; fdes += fsz, i++)
|
||||||
{
|
{
|
||||||
if ((char*)fdep >= (frame_buf + buf_size))
|
if (fdes >= buf_end)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (to_foreign)
|
if (to_foreign && sframe_decode_fde (fdes, fdes - buf_end, ver,
|
||||||
{
|
&num_fres, &fre_type, &fre_offset,
|
||||||
num_fres = fdep->sfde_func_num_fres;
|
&fsz))
|
||||||
fre_type = sframe_get_fre_type (fdep);
|
goto bad;
|
||||||
fre_offset = fdep->sfde_func_start_fre_off;
|
|
||||||
}
|
|
||||||
|
|
||||||
flip_fde (fdep);
|
if (flip_fde (fdes, buf_end - fdes, ver, &fsz))
|
||||||
bytes_flipped += sizeof (sframe_func_desc_entry);
|
goto bad;
|
||||||
|
|
||||||
if (!to_foreign)
|
bytes_flipped += fsz;
|
||||||
{
|
|
||||||
num_fres = fdep->sfde_func_num_fres;
|
|
||||||
fre_type = sframe_get_fre_type (fdep);
|
|
||||||
fre_offset = fdep->sfde_func_start_fre_off;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp = frame_buf + hdrsz + ihp->sfh_freoff;
|
if (!to_foreign && sframe_decode_fde (fdes, fdes - buf_end, ver,
|
||||||
fp += fre_offset;
|
&num_fres, &fre_type, &fre_offset,
|
||||||
|
&fsz))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
fp = fres + fre_offset;
|
||||||
for (; j < prev_frep_index + num_fres; j++)
|
for (; j < prev_frep_index + num_fres; j++)
|
||||||
{
|
{
|
||||||
if (flip_fre (fp, fre_type, &esz))
|
if (flip_fre (fp, fre_type, &esz))
|
||||||
|
|||||||
Reference in New Issue
Block a user