include: sframe: doc: define new flag SFRAME_F_FDE_FUNC_START_PCREL

Add a new flag SFRAME_F_FDE_FUNC_START_PCREL to SFrame stack trace
format.  If set, this flag indicates that the function start address
field (sfde_func_start_address) is the offset to the function start
address from the SFrame FDE function start address field itself.

Such an encoding is friendlier to the exisitng PC-REL relocations
available in the ABIs supported in SFrame: AMD64 (R_X86_64_PC32) and
AArch64 (R_AARCH64_PREL32).  In subsequent patches, we will make the
implementation in gas and ld to both:
  - emit the values in the same (above-mentioned) encoding uniformly.
  - set the flag SFRAME_F_FDE_FUNC_START_PCREL in the SFrame header
    for consumers to be able to distinguish.

Define SFRAME_V2_F_ALL_FLAGS in sframe.h to help keep the implementation
less error-prone by keeping a set of all defined flags at a central
place.  Adjust the check in sframe_header_sanity_check_p () to use the
SFRAME_V2_F_ALL_FLAGS instead.

Add documentation for SFRAME_F_FDE_FUNC_START_PCREL.  Update the
documentation about the encoding of the sfde_func_start_address field.

Also, update the section "Changes from Version 1 to Version 2" to
include the specification of the new flag SFRAME_F_FDE_FUNC_START_PCREL
as an erratum to the SFrame Version 2 specification.

include/
        * sframe.h (SFRAME_F_FDE_FUNC_START_PCREL): New definition.
        (SFRAME_V2_F_ALL_FLAGS): Likewise.
libsframe/
	* sframe-dump.c (dump_sframe_header_flags): Update to include
	the new flag SFRAME_F_FDE_FUNC_START_PCREL.
	* sframe.c (sframe_header_sanity_check_p): Use
	SFRAME_V2_F_ALL_FLAGS.
libsframe/doc/
	* sframe-spec.texi: Add details about the new flag.  Also update
	the defails about the sfde_func_start_address encoding.
This commit is contained in:
Indu Bhagat
2025-07-06 12:46:43 -07:00
parent 72dac98050
commit dcb0cf7bb2
4 changed files with 41 additions and 10 deletions

View File

@@ -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}

View File

@@ -60,6 +60,7 @@ dump_sframe_header_flags (sframe_decoder_ctx *sfd_ctx)
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

View File

@@ -205,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. */