diff options
Diffstat (limited to 'libsframe')
-rw-r--r-- | libsframe/doc/sframe-spec.texi | 32 | ||||
-rw-r--r-- | libsframe/libsframe.ver | 7 | ||||
-rw-r--r-- | libsframe/sframe-dump.c | 73 | ||||
-rw-r--r-- | libsframe/sframe.c | 153 | ||||
-rw-r--r-- | libsframe/testsuite/libsframe.decode/DATA2 | bin | 98 -> 98 bytes | |||
-rw-r--r-- | libsframe/testsuite/libsframe.encode/encode-1.c | 7 | ||||
-rw-r--r-- | libsframe/testsuite/libsframe.find/findfre-1.c | 13 | ||||
-rw-r--r-- | libsframe/testsuite/libsframe.find/findfunc-1.c | 18 | ||||
-rw-r--r-- | libsframe/testsuite/libsframe.find/plt-findfre-1.c | 8 |
9 files changed, 240 insertions, 71 deletions
diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi index 6b8dfa8..69fe873 100644 --- a/libsframe/doc/sframe-spec.texi +++ b/libsframe/doc/sframe-spec.texi @@ -128,6 +128,17 @@ the data structure. @item The above two imply that each SFrame function descriptor entry has a fixed size of 20 bytes instead of its size of 17 bytes in SFrame format version 1. +@item +Add a new flag SFRAME_F_FDE_FUNC_START_PCREL, as an erratum to SFrame +Version 2, to indicate the encoding of the SFrame FDE function start address +field: + @itemize @minus + @item if set, @code{sfde_func_start_address} field contains the offset in +bytes to the start PC of the associated function from the field itself. + @item if unset, @code{sfde_func_start_address} field contains the offset in +bytes to the start PC of the associated function from the start of the SFrame +section. + @end itemize @end itemize SFrame version 1 is now obsolete and should not be used. @@ -234,21 +245,28 @@ describe various section-wide properties. The following flags are currently defined. -@multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries} -@headitem Flag @tab Versions @tab Value @tab Meaning +@multitable {@code{SFRAME_F_FRAME_POINTER}} {Version} {Value} {Function Descriptor Entries are sorted} +@headitem Flag @tab Version @tab Value @tab Meaning @tindex SFRAME_F_FDE_SORTED @item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor Entries are sorted on PC. @tindex SFRAME_F_FRAME_POINTER @item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2 @tab All functions in the object file preserve frame pointer. +@tindex SFRAME_F_FDE_FUNC_START_PCREL +@item @code{SFRAME_F_FDE_FUNC_START_PCREL} @tab 2 @tab 0x4 +@tab The @code{sfde_func_start_address} field in the SFrame FDE is an offset in +bytes to the function's start address, from the field itself. If unset, the +@code{sfde_func_start_address} field in the SFrame FDE is an offset in bytes to +the function's start address, from the start of the SFrame section. @end multitable The purpose of SFRAME_F_FRAME_POINTER flag is to facilitate stack tracers to reliably fallback on the frame pointer based stack tracing method, if SFrame information is not present for some function in the SFrame section. -Further flags may be added in future. +Further flags may be added in future. Bits corresponding to the currently +undefined flags must be set to zero. @node SFrame Header @section SFrame Header @@ -461,9 +479,11 @@ Following table describes each component of the SFrame FDE structure: @tab @code{int32_t} @tab @code{sfde_func_start_address} @tab Signed 32-bit integral field denoting the virtual memory address of the -described function, for which the SFrame FDE applies. The value encoded in -the @code{sfde_func_start_address} field is the offset in bytes of the -function's start address, from the SFrame section. +described function, for which the SFrame FDE applies. If the flag +@code{SFRAME_F_FDE_FUNC_START_PCREL}, @xref{SFrame Flags}, in the SFrame +header is set, the value encoded in the @code{sfde_func_start_address} field is +the offset in bytes to the function's start address, from the SFrame +@code{sfde_func_start_address} field. @item 0x04 @tab @code{uint32_t} diff --git a/libsframe/libsframe.ver b/libsframe/libsframe.ver index 57f5fb6..06324ee 100644 --- a/libsframe/libsframe.ver +++ b/libsframe/libsframe.ver @@ -38,3 +38,10 @@ LIBSFRAME_1.0 { local: *; } LIBSFRAME_0.0; + +LIBSFRAME_1.1 { + sframe_decoder_get_flags; + sframe_decoder_get_offsetof_fde_start_addr; + sframe_encoder_get_flags; + sframe_encoder_get_offsetof_fde_start_addr; +} LIBSFRAME_1.0; diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c index 1fa508d..47ac00e 100644 --- a/libsframe/sframe-dump.c +++ b/libsframe/sframe-dump.c @@ -23,8 +23,6 @@ #include <inttypes.h> #include "sframe-impl.h" -#define SFRAME_HEADER_FLAGS_STR_MAX_LEN 50 - /* Return TRUE if the SFrame section is associated with the aarch64 ABIs. */ static bool @@ -41,11 +39,40 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx) } static void +dump_sframe_header_flags (sframe_decoder_ctx *sfd_ctx) +{ + uint8_t flags; + const char *prefix = "Flags: "; + + flags = sframe_decoder_get_flags (sfd_ctx); + if (!flags) + { + printf ("%11sNONE\n", prefix); + return; + } + +#define PRINT_FLAG(x) \ + if (flags & (x)) \ + { flags = (flags & ~(x)); \ + printf ("%11s%s%s\n", prefix, #x, flags ? "," : ""); \ + prefix = " "; \ + } + + PRINT_FLAG (SFRAME_F_FDE_SORTED); + PRINT_FLAG (SFRAME_F_FRAME_POINTER); + PRINT_FLAG (SFRAME_F_FDE_FUNC_START_PCREL); +#undef PRINT_FLAG + + /* Print any residual flags, should this implementation be out of sync when + new flags are added. */ + if (flags) + printf ("%11s%d\n", prefix, flags); +} + +static void dump_sframe_header (sframe_decoder_ctx *sfd_ctx) { uint8_t ver; - uint8_t flags; - char *flags_str; const char *ver_str = NULL; int8_t cfa_fixed_fp_offset; int8_t cfa_fixed_ra_offset; @@ -57,33 +84,10 @@ dump_sframe_header (sframe_decoder_ctx *sfd_ctx) "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) ver_str = version_names[ver]; - /* Prepare SFrame section flags string. */ - flags = header->sfh_preamble.sfp_flags; - flags_str = (char*) calloc (SFRAME_HEADER_FLAGS_STR_MAX_LEN, sizeof (char)); - if (flags) - { - if (flags & SFRAME_F_FDE_SORTED) - strcpy (flags_str, flag_names[0]); - if (flags & SFRAME_F_FRAME_POINTER) - { - if (strlen (flags_str) > 0) - strcpy (flags_str, ","); - strcpy (flags_str, flag_names[1]); - } - } - else - strcpy (flags_str, "NONE"); - /* CFA fixed FP and RA offsets. */ cfa_fixed_fp_offset = header->sfh_cfa_fixed_fp_offset; cfa_fixed_ra_offset = header->sfh_cfa_fixed_ra_offset; @@ -93,15 +97,15 @@ dump_sframe_header (sframe_decoder_ctx *sfd_ctx) printf (" %s :\n", subsec_name); printf ("\n"); printf (" Version: %s\n", ver_str); - printf (" Flags: %s\n", flags_str); + + dump_sframe_header_flags (sfd_ctx); + if (cfa_fixed_fp_offset != SFRAME_CFA_FIXED_FP_INVALID) printf (" CFA fixed FP offset: %d\n", cfa_fixed_fp_offset); if (cfa_fixed_ra_offset != SFRAME_CFA_FIXED_RA_INVALID) printf (" CFA fixed RA offset: %d\n", cfa_fixed_ra_offset); printf (" Num FDEs: %d\n", sframe_decoder_get_num_fidx (sfd_ctx)); printf (" Num FREs: %d\n", header->sfh_num_fres); - - free (flags_str); } static void @@ -129,8 +133,15 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx, /* Get the SFrame function descriptor. */ sframe_decoder_get_funcdesc (sfd_ctx, funcidx, &num_fres, &func_size, &func_start_address, &func_info); - /* Calculate the virtual memory address for function start pc. */ +/* Calculate the virtual memory address for function start pc. Some older + SFrame V2 sections in ET_DYN or ET_EXEC may still have the + SFRAME_F_FDE_FUNC_START_PCREL flag unset, and hence may be using the + old encoding. Continue to support dumping the sections at least. */ func_start_pc_vma = func_start_address + sec_addr; + if (sframe_decoder_get_flags (sfd_ctx) & SFRAME_F_FDE_FUNC_START_PCREL) + func_start_pc_vma += sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx, + funcidx, + NULL); /* Mark FDEs with [m] where the FRE start address is interpreted as a mask. */ diff --git a/libsframe/sframe.c b/libsframe/sframe.c index d38a61d..ea0e1c7 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> +#include <stddef.h> #include "sframe-impl.h" #include "swap.h" @@ -204,12 +205,11 @@ flip_fde (sframe_func_desc_entry *fdep) static bool 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_1 && hp->sfh_preamble.sfp_version != SFRAME_VERSION_2) - || (hp->sfh_preamble.sfp_flags | all_flags) != all_flags) + || (hp->sfh_preamble.sfp_flags & ~SFRAME_V2_F_ALL_FLAGS)) return false; /* Check offsets are valid. */ @@ -363,25 +363,47 @@ sframe_decoder_get_funcdesc_at_index (sframe_decoder_ctx *ctx, return fdep; } +/* Get the offset of the start PC of the SFrame FDE at FUNC_IDX from the start + of the SFrame section. This section-relative offset is used within + libsframe for sorting the SFrame FDEs, and also information lookup routines + like sframe_find_fre. + + If FUNC_IDX is not a valid index in the given decoder object, returns 0. */ + +static int32_t +sframe_decoder_get_secrel_func_start_addr (sframe_decoder_ctx *dctx, + uint32_t func_idx) +{ + int err = 0; + int32_t offsetof_fde_in_sec + = sframe_decoder_get_offsetof_fde_start_addr (dctx, func_idx, &err); + /* If func_idx is not a valid index, return 0. */ + if (err) + return 0; + + int32_t func_start_addr = dctx->sfd_funcdesc[func_idx].sfde_func_start_address; + + return func_start_addr + offsetof_fde_in_sec; +} + /* Check whether for the given FDEP, the SFrame Frame Row Entry identified via the START_IP_OFFSET and the END_IP_OFFSET, provides the stack trace information for the PC. */ static bool -sframe_fre_check_range_p (sframe_func_desc_entry *fdep, +sframe_fre_check_range_p (sframe_decoder_ctx *dctx, uint32_t func_idx, uint32_t start_ip_offset, uint32_t end_ip_offset, int32_t pc) { + sframe_func_desc_entry *fdep; int32_t func_start_addr; uint8_t rep_block_size; uint32_t fde_type; uint32_t pc_offset; bool mask_p; - if (!fdep) - return false; - - func_start_addr = fdep->sfde_func_start_address; + fdep = &dctx->sfd_funcdesc[func_idx]; + func_start_addr = sframe_decoder_get_secrel_func_start_addr (dctx, func_idx); fde_type = sframe_get_fde_type (fdep); mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK); rep_block_size = fdep->sfde_func_rep_size; @@ -913,7 +935,7 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp) sfheaderp = &dctx->sfd_header; if (!sframe_header_sanity_check_p (sfheaderp)) { - sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM); + sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL); goto decode_fail_free; } hdrsz = sframe_get_hdr_size (sfheaderp); @@ -988,6 +1010,15 @@ sframe_decoder_get_version (sframe_decoder_ctx *dctx) return dhp->sfh_preamble.sfp_version; } +/* Get the section flags from the SFrame decoder context DCTX. */ + +uint8_t +sframe_decoder_get_flags (sframe_decoder_ctx *dctx) +{ + const sframe_header *dhp = sframe_decoder_get_header (dctx); + return dhp->sfh_preamble.sfp_flags; +} + /* Get the SFrame's fixed FP offset given the decoder context CTX. */ int8_t sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *ctx) @@ -1006,6 +1037,29 @@ sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *ctx) return dhp->sfh_cfa_fixed_ra_offset; } +/* Get the offset of the sfde_func_start_address field (from the start of the + on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the decoder + context DCTX. + + If FUNC_IDX is more than the number of SFrame FDEs in the section, sets + error code in ERRP, but returns the (hypothetical) offset. This is useful + for the linker when arranging input FDEs into the output section to be + emitted. */ + +uint32_t +sframe_decoder_get_offsetof_fde_start_addr (sframe_decoder_ctx *dctx, + uint32_t func_idx, int *errp) +{ + if (func_idx >= sframe_decoder_get_num_fidx (dctx)) + sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTFOUND); + else if (errp) + *errp = 0; + + return (sframe_decoder_get_hdr_size (dctx) + + func_idx * sizeof (sframe_func_desc_entry) + + offsetof (sframe_func_desc_entry, sfde_func_start_address)); +} + /* Find the function descriptor entry which contains the specified address ADDR. This function is deprecated and will be removed from libsframe.so.2. */ @@ -1023,7 +1077,7 @@ sframe_get_funcdesc_with_addr (sframe_decoder_ctx *ctx __attribute__ ((unused)), static sframe_func_desc_entry * sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr, - int *errp) + int *errp, uint32_t *func_idx) { sframe_header *dhp; sframe_func_desc_entry *fdp; @@ -1038,7 +1092,7 @@ sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr, return sframe_ret_set_errno (errp, SFRAME_ERR_DCTX_INVAL); /* If the FDE sub-section is not sorted on PCs, skip the lookup because binary search cannot be used. */ - if ((dhp->sfh_preamble.sfp_flags & SFRAME_F_FDE_SORTED) == 0) + if ((sframe_decoder_get_flags (ctx) & SFRAME_F_FDE_SORTED) == 0) return sframe_ret_set_errno (errp, SFRAME_ERR_FDE_NOTSORTED); /* Do the binary search. */ @@ -1051,12 +1105,16 @@ sframe_get_funcdesc_with_addr_internal (sframe_decoder_ctx *ctx, int32_t addr, /* Given sfde_func_start_address <= addr, addr - sfde_func_start_address must be positive. */ - if (fdp[mid].sfde_func_start_address <= addr - && ((uint32_t)(addr - fdp[mid].sfde_func_start_address) + if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) <= addr + && ((uint32_t)(addr - sframe_decoder_get_secrel_func_start_addr (ctx, + mid)) < fdp[mid].sfde_func_size)) - return fdp + mid; + { + *func_idx = mid; + return fdp + mid; + } - if (fdp[mid].sfde_func_start_address < addr) + if (sframe_decoder_get_secrel_func_start_addr (ctx, mid) < addr) low = mid + 1; else high = mid - 1; @@ -1100,6 +1158,7 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, { sframe_frame_row_entry cur_fre; sframe_func_desc_entry *fdep; + uint32_t func_idx; uint32_t fre_type, i; int32_t func_start_addr; uint32_t start_ip_offset, end_ip_offset; @@ -1111,14 +1170,14 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, return sframe_set_errno (&err, SFRAME_ERR_INVAL); /* Find the FDE which contains the PC, then scan its fre entries. */ - fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err); + fdep = sframe_get_funcdesc_with_addr_internal (ctx, pc, &err, &func_idx); if (fdep == NULL || ctx->sfd_fres == NULL) return sframe_set_errno (&err, SFRAME_ERR_DCTX_INVAL); fre_type = sframe_get_fre_type (fdep); fres = ctx->sfd_fres + fdep->sfde_func_start_fre_off; - func_start_addr = fdep->sfde_func_start_address; + func_start_addr = sframe_decoder_get_secrel_func_start_addr (ctx, func_idx); for (i = 0; i < fdep->sfde_func_num_fres; i++) { @@ -1134,7 +1193,8 @@ sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, if (start_ip_offset > (uint32_t)(pc - func_start_addr)) return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL); - if (sframe_fre_check_range_p (fdep, start_ip_offset, end_ip_offset, pc)) + if (sframe_fre_check_range_p (ctx, func_idx, start_ip_offset, + end_ip_offset, pc)) { sframe_frame_row_entry_copy (frep, &cur_fre); return 0; @@ -1330,6 +1390,12 @@ sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, hp->sfh_preamble.sfp_magic = SFRAME_MAGIC; hp->sfh_preamble.sfp_flags = flags; + /* Implementation in the SFrame encoder APIs, e.g., + sframe_encoder_write_sframe assume flag SFRAME_F_FDE_FUNC_START_PCREL + set. */ + if (!(flags & SFRAME_F_FDE_FUNC_START_PCREL)) + return sframe_ret_set_errno (errp, SFRAME_ERR_ECTX_INVAL); + hp->sfh_abi_arch = abi_arch; hp->sfh_cfa_fixed_fp_offset = fixed_fp_offset; hp->sfh_cfa_fixed_ra_offset = fixed_ra_offset; @@ -1402,6 +1468,15 @@ sframe_encoder_get_version (sframe_encoder_ctx *encoder) return ehp->sfh_preamble.sfp_version; } +/* Get the section flags from the SFrame encoder context ENCODER. */ + +uint8_t +sframe_encoder_get_flags (sframe_encoder_ctx *encoder) +{ + const sframe_header *ehp = sframe_encoder_get_header (encoder); + return ehp->sfh_preamble.sfp_flags; +} + /* Return the number of function descriptor entries in the SFrame encoder ENCODER. */ @@ -1416,6 +1491,29 @@ sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder) return num_fdes; } +/* Get the offset of the sfde_func_start_address field (from the start of the + on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the encoder + context ENCODER. + + If FUNC_IDX is more than the number of SFrame FDEs in the section, sets + error code in ERRP, but returns the (hypothetical) offset. This is useful + for the linker when arranging input FDEs into the output section to be + emitted. */ + +uint32_t +sframe_encoder_get_offsetof_fde_start_addr (sframe_encoder_ctx *encoder, + uint32_t func_idx, int *errp) +{ + if (func_idx >= sframe_encoder_get_num_fidx (encoder)) + sframe_ret_set_errno (errp, SFRAME_ERR_FDE_INVAL); + else if (errp) + *errp = 0; + + return (sframe_encoder_get_hdr_size (encoder) + + func_idx * sizeof (sframe_func_desc_entry) + + offsetof (sframe_func_desc_entry, sfde_func_start_address)); +} + /* Add an FRE to function at FUNC_IDX'th function descriptor entry in the encoder context. */ @@ -1627,15 +1725,28 @@ sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder, static int sframe_sort_funcdesc (sframe_encoder_ctx *encoder) { - sframe_header *ehp; + sframe_header *ehp = sframe_encoder_get_header (encoder); - ehp = sframe_encoder_get_header (encoder); /* Sort and write out the FDE table. */ sf_fde_tbl *fd_info = encoder->sfe_funcdesc; if (fd_info) { + /* The new encoding of sfde_func_start_address means the distances are + not from the same anchor, so cannot be sorted directly. At the moment + we adress this by manual value adjustments before and after sorting. + FIXME - qsort_r may be more optimal. */ + + for (unsigned int i = 0; i < fd_info->count; i++) + fd_info->entry[i].sfde_func_start_address + += sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL); + qsort (fd_info->entry, fd_info->count, sizeof (sframe_func_desc_entry), fde_func); + + for (unsigned int i = 0; i < fd_info->count; i++) + fd_info->entry[i].sfde_func_start_address + -= sframe_encoder_get_offsetof_fde_start_addr (encoder, i, NULL); + /* Update preamble's flags. */ ehp->sfh_preamble.sfp_flags |= SFRAME_F_FDE_SORTED; } @@ -1736,7 +1847,6 @@ sframe_encoder_write_sframe (sframe_encoder_ctx *encoder) size_t fre_size; size_t esz = 0; sframe_header *ehp; - unsigned char flags; sf_fde_tbl *fd_info; sf_fre_tbl *fr_info; uint32_t i, num_fdes; @@ -1806,8 +1916,7 @@ sframe_encoder_write_sframe (sframe_encoder_ctx *encoder) /* Sanity checks: - the FDE section must have been sorted by now on the start address of each function. */ - flags = ehp->sfh_preamble.sfp_flags; - if (!(flags & SFRAME_F_FDE_SORTED) + if (!(sframe_encoder_get_flags (encoder) & SFRAME_F_FDE_SORTED) || (fd_info == NULL)) return sframe_set_errno (&err, SFRAME_ERR_FDE_INVAL); diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2 Binary files differindex 472f736..90649e2 100644 --- a/libsframe/testsuite/libsframe.decode/DATA2 +++ b/libsframe/testsuite/libsframe.decode/DATA2 diff --git a/libsframe/testsuite/libsframe.encode/encode-1.c b/libsframe/testsuite/libsframe.encode/encode-1.c index 3c2df76..1ba75d7 100644 --- a/libsframe/testsuite/libsframe.encode/encode-1.c +++ b/libsframe/testsuite/libsframe.encode/encode-1.c @@ -41,7 +41,7 @@ add_fde1 (sframe_encoder_ctx *encode, int idx) unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); - err = sframe_encoder_add_funcdesc (encode, 0xfffff03e, 0x1b, finfo, 4); + err = sframe_encoder_add_funcdesc (encode, 0xfffff022, 0x1b, finfo, 4); if (err == -1) return err; @@ -66,7 +66,7 @@ add_fde2 (sframe_encoder_ctx *encode, int idx) unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); - err = sframe_encoder_add_funcdesc (encode, 0xfffff059, 0x10, finfo, 4); + err = sframe_encoder_add_funcdesc (encode, 0xfffff029, 0x10, finfo, 4); if (err == -1) return err; @@ -145,7 +145,8 @@ int main (void) } \ while (0) - encode = sframe_encode (SFRAME_VERSION, 0, + encode = sframe_encode (SFRAME_VERSION, + SFRAME_F_FDE_FUNC_START_PCREL, SFRAME_ABI_AMD64_ENDIAN_LITTLE, SFRAME_CFA_FIXED_FP_INVALID, -8, /* Fixed RA offset for AMD64. */ diff --git a/libsframe/testsuite/libsframe.find/findfre-1.c b/libsframe/testsuite/libsframe.find/findfre-1.c index 94fe2e9..7c7c947 100644 --- a/libsframe/testsuite/libsframe.find/findfre-1.c +++ b/libsframe/testsuite/libsframe.find/findfre-1.c @@ -43,7 +43,10 @@ add_fde1 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr, fre_start_addr of the last FRE above (0x38). */ *func_size = 0x40; - int32_t func1_start_addr = start_pc_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL); + int32_t func1_start_addr = (start_pc_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc (encode, func1_start_addr, *func_size, @@ -74,7 +77,10 @@ add_fde2 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr, fre_start_addr of the last FRE above (0x20). */ *func_size = 0x60; - int32_t func2_start_addr = start_pc_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL); + int32_t func2_start_addr = (start_pc_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc (encode, func2_start_addr, *func_size, @@ -115,7 +121,8 @@ void test_text_findfre (uint32_t text_vaddr, uint32_t sframe_vaddr) } \ while (0) - encode = sframe_encode (SFRAME_VERSION, 0, + encode = sframe_encode (SFRAME_VERSION, + SFRAME_F_FDE_FUNC_START_PCREL, SFRAME_ABI_AMD64_ENDIAN_LITTLE, SFRAME_CFA_FIXED_FP_INVALID, -8, /* Fixed RA offset for AMD64. */ diff --git a/libsframe/testsuite/libsframe.find/findfunc-1.c b/libsframe/testsuite/libsframe.find/findfunc-1.c index 3cdcdb6..00b9e8d 100644 --- a/libsframe/testsuite/libsframe.find/findfunc-1.c +++ b/libsframe/testsuite/libsframe.find/findfunc-1.c @@ -50,7 +50,10 @@ add_fde1 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr, fre_start_addr of the last FRE above (0x38). */ *func_size = 0x40; - int32_t func1_start_addr = start_pc_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL); + int32_t func1_start_addr = (start_pc_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc (encode, func1_start_addr, *func_size, @@ -81,7 +84,10 @@ add_fde2 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr, fre_start_addr of the last FRE above (0x20). */ *func_size = 0x60; - int32_t func2_start_addr = start_pc_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL); + int32_t func2_start_addr = (start_pc_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc (encode, func2_start_addr, *func_size, @@ -112,7 +118,10 @@ add_fde3 (sframe_encoder_ctx *encode, uint32_t start_pc_vaddr, fre_start_addr of the last FRE above (0x38). */ *func_size = 0x40; - int32_t func3_start_addr = start_pc_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (encode, idx, NULL); + int32_t func3_start_addr = (start_pc_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCINC); int err = sframe_encoder_add_funcdesc (encode, func3_start_addr, *func_size, @@ -155,7 +164,8 @@ void test_text_findfre (uint32_t text_vaddr, uint32_t sframe_vaddr) } \ while (0) - encode = sframe_encode (SFRAME_VERSION, 0, + encode = sframe_encode (SFRAME_VERSION, + SFRAME_F_FDE_FUNC_START_PCREL, SFRAME_ABI_AMD64_ENDIAN_LITTLE, SFRAME_CFA_FIXED_FP_INVALID, -8, /* Fixed RA offset for AMD64. */ diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c index 89ca466..91da4bc 100644 --- a/libsframe/testsuite/libsframe.find/plt-findfre-1.c +++ b/libsframe/testsuite/libsframe.find/plt-findfre-1.c @@ -42,7 +42,10 @@ add_plt_fde1 (sframe_encoder_ctx *ectx, uint32_t plt_vaddr, unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCMASK); - int32_t func_start_addr = plt_vaddr - sframe_vaddr; + uint32_t offsetof_fde_in_sec + = sframe_encoder_get_offsetof_fde_start_addr (ectx, idx, NULL); + int32_t func_start_addr = (plt_vaddr + - (sframe_vaddr + offsetof_fde_in_sec)); /* 5 pltN entries of 16 bytes each. */ int err = sframe_encoder_add_funcdesc_v2 (ectx, func_start_addr, @@ -81,7 +84,8 @@ void test_plt_findfre (uint32_t plt_vaddr, uint32_t sframe_vaddr) } \ while (0) - ectx = sframe_encode (SFRAME_VERSION, 0, SFRAME_ABI_AMD64_ENDIAN_LITTLE, + ectx = sframe_encode (SFRAME_VERSION, SFRAME_F_FDE_FUNC_START_PCREL, + SFRAME_ABI_AMD64_ENDIAN_LITTLE, SFRAME_CFA_FIXED_FP_INVALID, -8, /* Fixed RA offset for AMD64. */ &err); |