aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIndu Bhagat <indu.bhagat@oracle.com>2025-07-06 12:47:05 -0700
committerIndu Bhagat <indu.bhagat@oracle.com>2025-07-06 12:53:03 -0700
commit0b1bf2fc98e2f657a5f259f369446caf39cda786 (patch)
tree016ebf8199b399524adf8a484913cf3e3989ee37
parentc915c2c95a3b38749d5a2f455ad5c91a20cb4794 (diff)
downloadbinutils-0b1bf2fc98e2f657a5f259f369446caf39cda786.zip
binutils-0b1bf2fc98e2f657a5f259f369446caf39cda786.tar.gz
binutils-0b1bf2fc98e2f657a5f259f369446caf39cda786.tar.bz2
bfd: gas: ld: libsframe: adopt new encoding for FDE func start addr field
This patch convenes a set of changes in bfd, gas, ld, libsframe towards moving to the new encoding for the 'sfde_func_start_address' field in SFrame FDE. First, gas must now mark all SFrame sections with the new flag SFRAME_F_FDE_FUNC_START_PCREL. gas was already emitting the field in the said encoding. * gas/gen-sframe.c (output_sframe_internal): Emit the flag SFRAME_F_FDE_FUNC_START_PCREL. Similarly for ld, adopt the new semantics of sfde_func_start_address consistently. This means: - When merging SFrame sections, check that all input SFrame sections have the SFRAME_F_FDE_FUNC_START_PCREL flag set. If the check fails, ld errors out. - When merging SFrame sections, keep even the in-memory contents of the FDE function start address (buffer passed to libsframe sframe_encoder_write () for writing out) encoded in the new semantics. While it is, in theory, possible that instead of doing this change here, we adjust the value of sfde_func_start_address at the final write (sframe_encoder_write) time. But latter is not favorable for maintenanance and may be generally confusing for developers. - When creating SFrame for PLT entries, emit flag SFRAME_F_FDE_FUNC_START_PCREL. include/ * sframe-api.h (SFRAME_F_LD_MUSTHAVE_FLAGS): New definition. bfd/ * elf-sframe.c (_bfd_elf_merge_section_sframe): Check for flag combinatation SFRAME_F_LD_MUSTHAVE_FLAGS set for all input and output SFrame sections. If not, error out. Also, adopt the new semantics of function start address encoding. * bfd/elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Emit flag SFRAME_F_FDE_FUNC_START_PCREL. Next, for dumping SFrame sections, now that we are emitting the same encoding in GAS, non-relocatable and relocatable SFrame links, it is the time to set relocate to TRUE in debug_displays[]. binutils/ * dwarf.c (struct dwarf_section_display): Allow sframe sections to now be relocated. gas/testsuite/ * gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Update the test. Relocatable SFrame sections now display non-zero value (appropriate function start address). Now, as the SFrame sections on-disk and in-memory use the new semantics of sfde_func_start_address encoding (i.e., function start address is the offset from the sfde_func_start_address field to the start PC), the calculation to make it human readable (i.e., relatable to the addresses in .text sections) needs adjustment. libsframe/ * sframe-dump.c (dump_sframe_func_with_fres): Adjust the function start address for dumping. Now that both the emission of the new encoding, and the relocation of sections before dumping them is in place, it is time to adjust the testcases. gas/testsuite/ * gas/cfi-sframe/cfi-sframe-aarch64-1.d: Update expected output to include SFRAME_F_FDE_FUNC_START_PCREL instead of NONE. * gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-aarch64-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-aarch64-4.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-10.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-11.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-common-9.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-4.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. * gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise. * gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise. ld/testsuite/ * ld-aarch64/sframe-simple-1.d: Update expected output to include SFRAME_F_FDE_FUNC_START_PCREL. * ld-x86-64/sframe-ibt-plt-1.d: Likewise. * ld-x86-64/sframe-plt-1.d: Likewise. * ld-x86-64/sframe-pltgot-1.d: Likewise. * ld-x86-64/sframe-pltgot-2.d: Likewise. * ld-x86-64/sframe-simple-1.d: Likewise. Naturally, the change of semantics for 'SFrame FDE function start address' has consequences on the implementation in libsframe. As per the new semantics: - Function start address in the SFrame FDE (sfde_func_start_address) is an offset from the FDE function start address field to the start PC of the associated function. Note that, the libsframe library brings the SFrame section contents into its own memory to create a sframe_decoder_ctx object via sframe_decode (). Many internal and user-interfacing APIs then may use sframe_decoder_ctx object to interact and fulfill the work. In context of changing semantics for sfde_func_start_address, following relevant examples may help understand the impact: - sframe_find_fre () finds a the SFrame stack trace data (SFrame FRE) given a lookup offset (offset of lookup_pc from the start of SFrame section). Now that the sfde_func_start_address includes the distance from the sfde_func_start_address field to the start of SFrame section itself, the comparison checks of sfde_func_start_address with the incoming lookup offset need adjustment. - Some internal functions (sframe_get_funcdesc_with_addr_internal () finds SFrame FDE by using binary seach comparing sfde_func_start_address fields, etc.) need adjustments. - sframe_encoder_write () sorts the SFrame FDEs before writing out the SFrame data. Sorting of SFrame FDE via the internal function sframe_sort_funcdesc() needs adjustments: the new encoding of sfde_func_start_address means the distances are not from the same anchor, so cannot be sorted directly. This patch takes the approach of adding a new internal function: - sframe_decoder_get_secrel_func_start_addr (): This function returns the offset of the start PC of the function from the start of SFrame section, i.e., it gives a section-relative offset. As the sframe_decoder_get_secrel_func_start_addr () API needs the value of the function index in the FDE list, another internal API needs sframe_fre_check_range_p () adjustments too. Sorting the FDEs (via sframe_sort_funcdesc ()) is done by first bringing all offsets in sfde_func_start_address relative to start of SFrame section, followed by sorting, and then readjusting the offsets accroding to the new position in the FDE list. libsframe/ * sframe.c (sframe_decoder_get_secrel_func_start_addr): New static function. (sframe_fre_check_range_p): Adjust the interface a bit. (sframe_get_funcdesc_with_addr_internal): Use sframe_decoder_get_secrel_func_start_addr () when comparing sfde_func_start_address with user input offset. (sframe_find_fre): Adopt the new semantics. (sframe_sort_funcdesc): Likewise. For the libsframe testsuite, use the new encoding for FDE func start addr: distance between the FDE sfde_func_start_address field and the start PC of the function itself. Use SFRAME_F_FDE_FUNC_START_PCREL flag, though the sframe_encode () interface in libsframe applies no sanity checks for the encoding itself. libsframe/testsuite/ * libsframe.find/findfre-1.c: Adjust to use the new SFRAME_F_FDE_FUNC_START_PCREL specific encoding. * libsframe.find/findfunc-1.c: Likewise. * libsframe.find/plt-findfre-1.c: Likewise. * libsframe/testsuite/libsframe.decode/DATA2: Update data file due to usage of new SFRAME_F_FDE_FUNC_START_PCREL flag. * libsframe/testsuite/libsframe.encode/encode-1.c: Use flag SFRAME_F_FDE_FUNC_START_PCREL.
-rw-r--r--bfd/elf-sframe.c37
-rw-r--r--bfd/elfxx-x86.c2
-rw-r--r--binutils/dwarf.c2
-rw-r--r--gas/gen-sframe.c13
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d10
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-1.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-2.d2
-rw-r--r--gas/testsuite/gas/cfi-sframe/common-empty-3.d2
-rw-r--r--gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d2
-rw-r--r--gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d2
-rw-r--r--include/sframe-api.h5
-rw-r--r--ld/testsuite/ld-aarch64/sframe-simple-1.d3
-rw-r--r--ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d3
-rw-r--r--ld/testsuite/ld-x86-64/sframe-plt-1.d3
-rw-r--r--ld/testsuite/ld-x86-64/sframe-pltgot-1.d3
-rw-r--r--ld/testsuite/ld-x86-64/sframe-pltgot-2.d3
-rw-r--r--ld/testsuite/ld-x86-64/sframe-simple-1.d3
-rw-r--r--libsframe/sframe-dump.c9
-rw-r--r--libsframe/sframe.c77
-rw-r--r--libsframe/testsuite/libsframe.decode/DATA2bin98 -> 98 bytes
-rw-r--r--libsframe/testsuite/libsframe.encode/encode-1.c7
-rw-r--r--libsframe/testsuite/libsframe.find/findfre-1.c13
-rw-r--r--libsframe/testsuite/libsframe.find/findfunc-1.c18
-rw-r--r--libsframe/testsuite/libsframe.find/plt-findfre-1.c8
45 files changed, 200 insertions, 71 deletions
diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index 97e0073..89c5322 100644
--- a/bfd/elf-sframe.c
+++ b/bfd/elf-sframe.c
@@ -328,6 +328,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
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;
@@ -351,6 +353,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
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);
@@ -361,8 +365,18 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
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_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_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,
@@ -411,6 +425,18 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
return false;
}
+ /* Check that all SFrame sections being linked have the 'data encoding'
+ related flags set. The implementation does not support updating these
+ data encodings on the fly; confirm by checking the ectx_flags. */
+ ectx_flags = sframe_encoder_get_flags (sfe_ctx);
+ if ((dctx_flags & ectx_flags & SFRAME_F_LD_MUSTHAVE_FLAGS)
+ != SFRAME_F_LD_MUSTHAVE_FLAGS)
+ {
+ _bfd_error_handler
+ (_("SFrame sections with unexpected data 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
@@ -481,6 +507,15 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
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. */
+ uint32_t 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);
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index bc9bb70..663f40a 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -1891,7 +1891,7 @@ _bfd_x86_elf_create_sframe_plt (bfd *output_bfd,
}
*ectx = sframe_encode (SFRAME_VERSION_2,
- 0,
+ SFRAME_F_FDE_FUNC_START_PCREL,
SFRAME_ABI_AMD64_ENDIAN_LITTLE,
SFRAME_CFA_FIXED_FP_INVALID,
-8, /* Fixed RA offset. */
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 51590cc..e0e202f 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -12863,7 +12863,7 @@ struct dwarf_section_display debug_displays[] =
{ { ".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 },
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 2d1c196..85d3553 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -21,6 +21,7 @@
#include "as.h"
#include "subsegs.h"
#include "sframe.h"
+#include "sframe-api.h"
#include "gen-sframe.h"
#include "dw2gencfi.h"
@@ -598,7 +599,8 @@ output_sframe_funcdesc (symbolS *start_of_fre_section,
dw_fde_start_addrS = get_dw_fde_start_addrS (sframe_fde->dw_fde);
dw_fde_end_addrS = get_dw_fde_end_addrS (sframe_fde->dw_fde);
- /* Start address of the function. */
+ /* Start address of the function. gas always emits this value with encoding
+ SFRAME_F_FDE_FUNC_START_PCREL. See PR ld/32666. */
exp.X_op = O_subtract;
exp.X_add_symbol = dw_fde_start_addrS; /* to location. */
exp.X_op_symbol = symbol_temp_new_now (); /* from location. */
@@ -663,8 +665,9 @@ output_sframe_internal (void)
int fixed_ra_offset = SFRAME_CFA_FIXED_RA_INVALID;
/* The function descriptor entries as dumped by the assembler are not
- sorted on PCs. */
- unsigned char sframe_flags = 0;
+ sorted on PCs. Fix for PR ld/32666 requires setting of an additional
+ flag in SFrame Version 2. */
+ unsigned char sframe_flags = SFRAME_F_FDE_FUNC_START_PCREL;
unsigned int num_fdes = get_num_sframe_fdes ();
unsigned int num_fres = get_num_sframe_fres ();
@@ -680,6 +683,10 @@ output_sframe_internal (void)
/* Output the preamble of SFrame section. */
out_two (SFRAME_MAGIC);
out_one (SFRAME_VERSION);
+ /* gas must ensure emitted SFrame sections have at least the required flags
+ set. */
+ gas_assert ((sframe_flags & SFRAME_F_LD_MUSTHAVE_FLAGS)
+ == SFRAME_F_LD_MUSTHAVE_FLAGS);
out_one (sframe_flags);
/* abi/arch. */
#ifdef sframe_get_abi_arch
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 8ae4621..830a652 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-1.d
@@ -6,7 +6,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
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 b7834d5..a6ee2ae 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-2.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
Num FDEs: 1
Num FREs: 2
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d
index f72b70a..c8ace34 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-3.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
Num FDEs: 1
Num FREs: 2
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d
index 51fad9c..fc75379 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-aarch64-4.d
@@ -16,7 +16,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
Num FDEs: 0
Num FREs: 0
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 599d4c4..4f14e39 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
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
Num FDEs: 2
Num FREs: 6
@@ -18,10 +18,10 @@ Contents of the SFrame section .sframe:
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
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 5f4ae00..8c74680 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-1.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
index 106e05d..a91b1fe 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-10.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d
index 2584815..2173ddb 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-11.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 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 ded8c450..146b789 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-2.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 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 d23fd97..8c065f8 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-3.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 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 8632613..0aed15c 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-4.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
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 dd2c32d..d7cedb3 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-5.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
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 34390c4..41074c7 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-6.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
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 61efb9c..e68a9a3 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-7.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
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 d776456..11a15bf 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-8.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
index 80c9235..ef588ea 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-common-9.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
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 88b4cc6..7850db2 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
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 4
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d
index d779b6d..c3841aa 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-2.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 1
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
index 0bae4b9..a63231e 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
index f1ba044..c3b4c4c 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d
index c8fc7a4..29a6d0c 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
index 43f09e0..1a718af 100644
--- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
+++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-1.d b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
index 736aea8..c64dd92 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-1.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-1.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-2.d b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
index 163b504..8174b32 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-2.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-2.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/cfi-sframe/common-empty-3.d b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
index 39caad5..c014988 100644
--- a/gas/testsuite/gas/cfi-sframe/common-empty-3.d
+++ b/gas/testsuite/gas/cfi-sframe/common-empty-3.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
#? CFA fixed FP offset: \-?\d+
#? CFA fixed RA offset: \-?\d+
Num FDEs: 0
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d
index 7c247e3..52ff74c9 100644
--- a/gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-sections-1.d
@@ -7,7 +7,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 5
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
index c6a9b53..d405420 100644
--- a/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
@@ -8,7 +8,7 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: NONE
+ Flags: SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
Num FDEs: 1
Num FREs: 4
diff --git a/include/sframe-api.h b/include/sframe-api.h
index 3dc18b6..753a91f 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -36,6 +36,11 @@ typedef struct sframe_encoder_ctx sframe_encoder_ctx;
#define MAX_OFFSET_BYTES \
((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS))
+/* 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_PCREL)
+
/* User interfacing SFrame Row Entry.
An abstraction provided by libsframe so the consumer is decoupled from
the binary format representation of the same.
diff --git a/ld/testsuite/ld-aarch64/sframe-simple-1.d b/ld/testsuite/ld-aarch64/sframe-simple-1.d
index 6ab8c2a..1ae73de 100644
--- a/ld/testsuite/ld-aarch64/sframe-simple-1.d
+++ b/ld/testsuite/ld-aarch64/sframe-simple-1.d
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
Num FDEs: 2
Num FREs: 2
diff --git a/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d b/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d
index f868242..45bf99a 100644
--- a/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-ibt-plt-1.d
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
#...
diff --git a/ld/testsuite/ld-x86-64/sframe-plt-1.d b/ld/testsuite/ld-x86-64/sframe-plt-1.d
index 2918ccb..d23540e 100644
--- a/ld/testsuite/ld-x86-64/sframe-plt-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-plt-1.d
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
#...
diff --git a/ld/testsuite/ld-x86-64/sframe-pltgot-1.d b/ld/testsuite/ld-x86-64/sframe-pltgot-1.d
index 6c47770..e2255b0 100644
--- a/ld/testsuite/ld-x86-64/sframe-pltgot-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-pltgot-1.d
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
#...
diff --git a/ld/testsuite/ld-x86-64/sframe-pltgot-2.d b/ld/testsuite/ld-x86-64/sframe-pltgot-2.d
index 141be29..52e712b 100644
--- a/ld/testsuite/ld-x86-64/sframe-pltgot-2.d
+++ b/ld/testsuite/ld-x86-64/sframe-pltgot-2.d
@@ -10,7 +10,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
#...
diff --git a/ld/testsuite/ld-x86-64/sframe-simple-1.d b/ld/testsuite/ld-x86-64/sframe-simple-1.d
index 3effdbf..bb4142f 100644
--- a/ld/testsuite/ld-x86-64/sframe-simple-1.d
+++ b/ld/testsuite/ld-x86-64/sframe-simple-1.d
@@ -11,7 +11,8 @@ Contents of the SFrame section .sframe:
Header :
Version: SFRAME_VERSION_2
- Flags: SFRAME_F_FDE_SORTED
+ Flags: SFRAME_F_FDE_SORTED,
+ SFRAME_F_FDE_FUNC_START_PCREL
CFA fixed RA offset: \-8
#...
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
index fbaa832..47ac00e 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -133,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 3e5b60a..ea0e1c7 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -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;
@@ -1055,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;
@@ -1083,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;
@@ -1132,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;
@@ -1143,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++)
{
@@ -1166,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;
@@ -1362,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;
@@ -1691,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;
}
diff --git a/libsframe/testsuite/libsframe.decode/DATA2 b/libsframe/testsuite/libsframe.decode/DATA2
index 472f736..90649e2 100644
--- a/libsframe/testsuite/libsframe.decode/DATA2
+++ b/libsframe/testsuite/libsframe.decode/DATA2
Binary files differ
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);