int8_t sfd_ctx_fixed_ra_offset;
uint8_t dctx_version;
uint8_t ectx_version;
+ uint8_t dctx_flags;
+ uint8_t ectx_flags;
int encerr = 0;
struct elf_link_hash_table *htab;
if (sfd_ctx == NULL || sfe_info == NULL)
return false;
+ dctx_flags = sframe_decoder_get_flags (sfd_ctx);
+
if (htab->sfe_info.sfe_ctx == NULL)
{
sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
if (!sfd_ctx_abi_arch)
return false;
+ /* In-memory FDEs in the encoder object are unsorted during linking and
+ will be sorted before emission. Reset SFRAME_F_FDE_SORTED to aptly
+ reflect that (doing so has no other functional value at this time
+ though). */
+ uint8_t tflags = dctx_flags & ~SFRAME_F_FDE_SORTED;
+ /* ld always generates an output section with
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL flag set. Later using
+ SFRAME_F_LD_MUSTHAVE_FLAGS, it is enforced that the provided input
+ sections also have this flag set. */
+ tflags |= SFRAME_F_FDE_FUNC_START_ADDR_PCREL;
htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
- 0, /* SFrame flags. */
+ tflags, /* SFrame flags. */
sfd_ctx_abi_arch,
sfd_ctx_fixed_fp_offset,
sfd_ctx_fixed_ra_offset,
" .sframe generation"));
return false;
}
-
+ /* Check that all SFrame sections being linked have harmonious flags. */
+ ectx_flags = sframe_encoder_get_flags (sfe_ctx);
+ if ((dctx_flags ^ ectx_flags) & SFRAME_F_LD_MUSTHAVE_FLAGS)
+ {
+ _bfd_error_handler
+ (_("input SFrame sections with different FDE encoding 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
bool pltn_reloc_by_hand = false;
unsigned int pltn_r_offset = 0;
uint8_t rep_block_size = 0;
+ uint32_t offsetof_fde_in_sec = 0;
if (!sframe_decoder_get_funcdesc_v2 (sfd_ctx, i, &num_fres, &func_size,
&func_start_addr, &func_info,
address += sframe_read_value (abfd, contents,
pltn_r_offset, 4);
address += (sec->output_offset + r_offset);
+ /* SFrame FDE function start address is an offset from the
+ sfde_func_start_address field to the start PC. The
+ calculation below is the distance of sfde_func_start_address
+ field from the start of the output SFrame section. */
+ offsetof_fde_in_sec
+ = sframe_encoder_get_offsetof_fde_start_addr (sfe_ctx,
+ cur_fidx + num_enc_fidx,
+ NULL);
+ address -= offsetof_fde_in_sec;
/* FIXME For testing only. Cleanup later. */
// address += (sec->output_section->vma);
}
*ectx = sframe_encode (SFRAME_VERSION_2,
- 0,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset. */
{ { ".debug_weaknames", ".zdebug_weaknames", "", NO_ABBREVS }, display_debug_not_supported, NULL, false },
{ { ".gdb_index", "", "", NO_ABBREVS }, display_gdb_index, &do_gdb_index, false },
{ { ".debug_names", "", "", NO_ABBREVS }, display_debug_names, &do_gdb_index, false },
- { { ".sframe", "", "", NO_ABBREVS }, display_sframe, &do_sframe, false },
+ { { ".sframe", "", "", NO_ABBREVS }, display_sframe, &do_sframe, true },
{ { ".trace_info", "", "", ABBREV (trace_abbrev) }, display_trace_info, &do_trace_info, true },
{ { ".trace_abbrev", "", "", NO_ABBREVS }, display_debug_abbrev, &do_trace_abbrevs, false },
{ { ".trace_aranges", "", "", NO_ABBREVS }, display_debug_aranges, &do_trace_aranges, false },
/* The function descriptor entries as dumped by the assembler are not
sorted on PCs. */
unsigned char sframe_flags = 0;
+ /* Fix PR ld/32666 - Incorrect .rela.sframe when using ld -r.
+ With the fix now in place, we indicate the new encoding with an additional
+ flag in SFrame Version 2. */
+ sframe_flags |= SFRAME_F_FDE_FUNC_START_ADDR_PCREL;
unsigned int num_fdes = get_num_sframe_fdes ();
unsigned int num_fres = get_num_sframe_fres ();
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 1
Num FREs: 3
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 1
Num FREs: 2
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 1
Num FREs: 2
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 0
Num FREs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 2
Num FREs: 6
0+0004 +sp\+0 +u +u\[s\] +
0+0008 +sp\+16 +c-16 +c-8\[s\] +
- func idx \[1\]: pc = 0x0, size = 20 bytes, pauth = B key
+ func idx \[1\]: pc = 0xc, size = 20 bytes, pauth = B key
STARTPC + CFA + FP + RA +
- 0+0000 +sp\+0 +u +u +
- 0+0004 +sp\+0 +u +u\[s\] +
- 0+0008 +sp\+16 +c-16 +c-8\[s\] +
+ 0+000c +sp\+0 +u +u +
+ 0+0010 +sp\+0 +u +u\[s\] +
+ 0+0014 +sp\+16 +c-16 +c-8\[s\] +
#pass
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 4
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 5
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 4
(SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER \
| SFRAME_F_FDE_FUNC_START_ADDR_PCREL)
+/* Set of flags that are required to be harmonious between all decoder and
+ encoder objects participating in a link. */
+#define SFRAME_F_LD_MUSTHAVE_FLAGS \
+ (SFRAME_F_FDE_FUNC_START_ADDR_PCREL)
+
/* User interfacing SFrame Row Entry.
An abstraction provided by libsframe so the consumer is decoupled from
the binary format representation of the same.
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
Num FDEs: 2
Num FREs: 2
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
#...
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
#...
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
#...
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
#...
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL
CFA fixed RA offset: \-8
#...
/* 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_ADDR_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_ADDR_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. */
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;
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;
/* 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;
{
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;
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++)
{
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;
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_ADDR_PCREL
+ set. */
+ if (!(flags & SFRAME_F_FDE_FUNC_START_ADDR_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;
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)
{
+ 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;
}
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;
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;
} \
while (0)
- encode = sframe_encode (SFRAME_VERSION, 0,
+ encode = sframe_encode (SFRAME_VERSION,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset for AMD64. */
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,
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,
} \
while (0)
- encode = sframe_encode (SFRAME_VERSION, 0,
+ encode = sframe_encode (SFRAME_VERSION,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset for AMD64. */
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,
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,
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,
} \
while (0)
- encode = sframe_encode (SFRAME_VERSION, 0,
+ encode = sframe_encode (SFRAME_VERSION,
+ SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset for AMD64. */
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,
} \
while (0)
- ectx = sframe_encode (SFRAME_VERSION, 0, SFRAME_ABI_AMD64_ENDIAN_LITTLE,
+ ectx = sframe_encode (SFRAME_VERSION, SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
+ SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset for AMD64. */
&err);