[PATCH, V2 4/9] include: sframe: doc: define new flag SFRAME_F_FDE_FUNC_START_ADDR_PCREL

Indu Bhagat indu.bhagat@oracle.com
Wed Jun 4 07:08:09 GMT 2025


Add a new flag SFRAME_F_FDE_FUNC_START_ADDR_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_ADDR_PCREL in the SFrame header
    for consumers to be able to distinguish.

Add documentation for SFRAME_F_FDE_FUNC_START_ADDR_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_ADDR_PCREL as an errata release to the SFrame
Version 2 specification.

include/
        * sframe.h (SFRAME_F_FDE_FUNC_START_ADDR_PCREL): New definition.
libsframe/
	* sframe-dump.c (dump_sframe_header_flags): Update to include
	the new flag.
	* sframe.c (sframe_header_sanity_check_p): Use uint8_t.
libsframe/doc/
	* sframe-spec.texi: Add details about the new flag.  Also update
	the defails about the sfde_func_start_address encoding.

---
[Changes in V2]
  - Switch back to the old style of flag values.
  - Merge three patches from V1 into a single patch
    include: libsframe: add APIs for offsetof FDE func start addr field
    doc: sframe: add documentation for SFRAME_F_FDE_FUNC_START_ADDR_PCREL
    doc: sframe: update documentation for sfde_func_start_address
[End of changes in V2]
---
 include/sframe.h               | 10 ++++++++--
 libsframe/doc/sframe-spec.texi | 29 ++++++++++++++++++++++++-----
 libsframe/sframe-dump.c        |  2 ++
 libsframe/sframe.c             |  3 ++-
 4 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/sframe.h b/include/sframe.h
index a965e23bdd1..11cbc9b5b0f 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -82,9 +82,15 @@ extern "C"
 /* Various flags for SFrame.  */
 
 /* Function Descriptor Entries are sorted on PC.  */
-#define SFRAME_F_FDE_SORTED	0x1
+#define SFRAME_F_FDE_SORTED		    0x1
 /* Functions preserve frame pointer.  */
-#define SFRAME_F_FRAME_POINTER 0x2
+#define SFRAME_F_FRAME_POINTER		    0x2
+/* Function start address in SFrame FDE is encoded as the distance from the
+   location of the sfde_func_start_address to the start PC of the function.
+   If absent, the function start address in SFrame FDE is encoded as the
+   distance from the start of the SFrame FDE section to the start PC of the
+   function.  */
+#define SFRAME_F_FDE_FUNC_START_ADDR_PCREL  0x4
 
 #define SFRAME_CFA_FIXED_FP_INVALID 0
 #define SFRAME_CFA_FIXED_RA_INVALID 0
diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
index 6b8dfa80650..e4cfe01204c 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
+A new flag SFRAME_F_FDE_FUNC_START_ADDR_PCREL, released as an errata 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,14 +245,20 @@ 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_ADDR_PCREL
+@item @code{SFRAME_F_FDE_FUNC_START_ADDR_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
@@ -461,9 +478,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_ADDR_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/sframe-dump.c b/libsframe/sframe-dump.c
index 43b6cc26056..230c7b75f69 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -60,6 +60,8 @@ dump_sframe_header_flags (sframe_decoder_ctx *sfd_ctx)
 
   PRINT_FLAG (SFRAME_F_FDE_SORTED, "SFRAME_F_FDE_SORTED");
   PRINT_FLAG (SFRAME_F_FRAME_POINTER, "SFRAME_F_FRAME_POINTER");
+  PRINT_FLAG (SFRAME_F_FDE_FUNC_START_ADDR_PCREL,
+	      "SFRAME_F_FDE_FUNC_START_ADDR_PCREL");
 #undef PRINT_FLAG
 }
 
diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index f554ae28127..68760fad368 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -205,7 +205,8 @@ 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;
+  uint8_t all_flags = (SFRAME_F_FDE_SORTED | SFRAME_F_FRAME_POINTER
+		       | SFRAME_F_FDE_FUNC_START_ADDR_PCREL);
   /* Check preamble is valid.  */
   if (hp->sfh_preamble.sfp_magic != SFRAME_MAGIC
       || (hp->sfh_preamble.sfp_version != SFRAME_VERSION_1
-- 
2.43.0



More information about the Binutils mailing list