RISC-V: Don't report warnings when linking different privileged spec objects.
[binutils-gdb.git] / libsframe / doc / sframe-spec.texi
blobc1730adfc55a3f99f477aabcc97dce41c3973c5a
1 \input texinfo       @c                    -*- Texinfo -*-
2 @setfilename sframe-spec.info
3 @settitle The SFrame Format
5 @copying
6 Copyright @copyright{} 2021-2024 Free Software Foundation, Inc.
8 Permission is granted to copy, distribute and/or modify this document
9 under the terms of the GNU General Public License, Version 3 or any
10 later version published by the Free Software Foundation.  A copy of the
11 license is included in the section entitled ``GNU General Public
12 License''.
14 @end copying
16 @dircategory Software development
17 @direntry
18 * SFrame: (sframe-spec).         The Simple Frame format.
19 @end direntry
21 @titlepage
22 @title The SFrame Format
23 @subtitle Version 2
24 @author Indu Bhagat
26 @page
27 @vskip 0pt plus 1filll
28 @insertcopying
29 @end titlepage
30 @contents
32 @ifnottex
33 @node Top
34 @top The SFrame format
36 This manual describes version 2 of the SFrame file format.  SFrame stands for
37 Simple Frame.  The SFrame format keeps track of the minimal necessary
38 information needed for generating stack traces:
40 @itemize @minus
41 @item
42 Canonical Frame Address (CFA).
43 @item
44 Frame Pointer (FP).
45 @item
46 Return Address (RA).
47 @end itemize
49 The reason for existence of the SFrame format is to provide a simple, fast and
50 low-overhead mechanism to generate stack traces.
52 @menu
53 * Introduction::
54 * SFrame Section::
55 * ABI/arch-specific Definition::
57 Appendices
58 * Generating Stack Traces using SFrame::
60 * Index::
61 @end menu
63 @end ifnottex
65 @node Introduction
66 @chapter Introduction
67 @cindex Introduction
69 @menu
70 * Overview::
71 * Changes from Version 1 to Version 2::
72 @end menu
74 @node Overview
75 @section Overview
76 @cindex Overview
78 The SFrame stack trace information is provided in a loaded section, known as the
79 @code{.sframe} section.  When available, the @code{.sframe} section appears in
80 a new segment of its own, PT_GNU_SFRAME.
82 The SFrame format is currently supported only for select ABIs, namely, AMD64
83 and AAPCS64.
85 A portion of the SFrame format follows an unaligned on-disk representation.
86 Some data structures, however, (namely the SFrame header and the SFrame
87 function descriptor entry) have elements at their natural boundaries.  All data
88 structures are packed, unless otherwise stated.
90 The contents of the SFrame section are stored in the target endianness, i.e.,
91 in the endianness of the system on which the section is targeted to be used.
92 An SFrame section reader may use the magic number in the SFrame header to
93 identify the endianness of the SFrame section.
95 Addresses in this specification are expressed in bytes.
97 The rest of this specification describes the current version of the format,
98 @code{SFRAME_VERSION_2}, in detail.  Additional sections outline the major
99 changes made to each previously published version of the SFrame stack trace
100 format.
102 The associated API to decode, probe and encode the SFrame section, provided via
103 @code{libsframe}, is not accompanied here at this time.  This will be added
104 later.
106 This document is intended to be in sync with the C code in @file{sframe.h}.
107 Please report discrepancies between the two, if any.
109 @node Changes from Version 1 to Version 2
110 @section Changes from Version 1 to Version 2
111 @cindex Changes from Version 1 to Version 2
113 The following is a list of the changes made to the SFrame stack trace format
114 since Version 1 was published.
116 @itemize @bullet
117 @item
118 Add an unsigned 8-bit integral field to the SFrame function descriptor entry to
119 encode the size of the repetitive code blocks.  Such code blocks, e.g, pltN
120 entries, use an SFrame function descriptor entry of type
121 SFRAME_FDE_TYPE_PCMASK.
122 @item
123 Add an unsigned 16-bit integral field to the SFrame function descriptor entry
124 to serve as padding.  This helps ensure natural alignment for the members of
125 the data structure.
126 @item
127 The above two imply that each SFrame function descriptor entry has a fixed size
128 of 20 bytes instead of its size of 17 bytes in SFrame format version 1.
129 @end itemize
131 SFrame version 1 is now obsolete and should not be used.
133 @node SFrame Section
134 @chapter SFrame Section
135 @cindex SFrame Section
137 The SFrame section consists of an SFrame header, starting with a preamble, and
138 two other sub-sections, namely the SFrame function descriptor entry (SFrame
139 FDE) sub-section, and the SFrame frame row entry (SFrame FRE) sub-section.
141 @menu
142 * SFrame Preamble::
143 * SFrame Header::
144 * SFrame Function Descriptor Entries::
145 * SFrame Frame Row Entries::
146 @end menu
148 @node SFrame Preamble
149 @section SFrame Preamble
150 @cindex SFrame preamble
152 The preamble is a 32-bit packed structure; the only part of the SFrame section
153 whose format cannot vary between versions.
155 @example
156 typedef struct sframe_preamble
158   uint16_t sfp_magic;
159   uint8_t sfp_version;
160   uint8_t sfp_flags;
161 @} ATTRIBUTE_PACKED sframe_preamble;
162 @end example
164 Every element of the SFrame preamble is naturally aligned.
166 All values are stored in the endianness of the target system for which the
167 SFrame section is intended.  Further details:
169 @multitable {Offset} {@code{uint16_t}} {@code{sfp_version}} {The magic number for SFrame section: 0xdee2.}
170 @headitem Offset @tab Type @tab Name @tab Description
171 @item 0x00
172 @tab @code{uint16_t}
173 @tab @code{sfp_magic}
174 @tab The magic number for SFrame section: 0xdee2.  Defined as a macro @code{SFRAME_MAGIC}.
175 @tindex SFRAME_MAGIC
177 @item 0x02
178 @tab @code{uint8_t}
179 @tab @code{sfp_version}
180 @tab The version number of this SFrame section.  @xref{SFrame Version}, for the
181 set of valid values.  Current version is
182 @code{SFRAME_VERSION_2}.
184 @item 0x03
185 @tab @code{uint8_t}
186 @tab @code{sfp_flags}
187 @tab Flags (section-wide) for this SFrame section.  @xref{SFrame Flags}, for the
188 set of valid values.
189 @end multitable
191 @menu
192 * SFrame Magic Number and Endianness::
193 * SFrame Version::
194 * SFrame Flags::
195 @end menu
197 @node SFrame Magic Number and Endianness
198 @subsection SFrame Magic Number and Endianness
200 @cindex endianness
201 @cindex SFrame magic number
202 SFrame sections are stored in the target endianness of the system that consumes
203 them.  A consumer library reading or writing SFrame sections should detect
204 foreign-endianness by inspecting the SFrame magic number in the
205 @code{sfp_magic} field in the SFrame header.  It may then provide means to
206 endian-flip the SFrame section as necessary.
208 @node SFrame Version
209 @subsection SFrame Version
211 The version of the SFrame format can be determined by inspecting
212 @code{sfp_version}.  The following versions are currently valid:
214 @tindex SFRAME_VERSION_1
215 @cindex SFrame versions
216 @multitable {SFRAME_VERSION_2} {Number} {Current version, under development.}
217 @headitem Version Name @tab Number @tab Description
218 @item @code{SFRAME_VERSION_1}
219 @tab 1 @tab First version, obsolete.
220 @item @code{SFRAME_VERSION_2}
221 @tab 2 @tab Current version, under development.
222 @end multitable
224 This document describes @code{SFRAME_VERSION_2}.
226 @node SFrame Flags
227 @subsection SFrame Flags
228 @cindex SFrame Flags
230 The preamble contains bitflags in its @code{sfp_flags} field that
231 describe various section-wide properties.
233 The following flags are currently defined.
235 @multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries}
236 @headitem Flag @tab Versions @tab Value @tab Meaning
237 @tindex SFRAME_F_FDE_SORTED
238 @item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor
239 Entries are sorted on PC.
240 @tindex SFRAME_F_FRAME_POINTER
241 @item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2
242 @tab All functions in the object file preserve frame pointer.
243 @end multitable
245 The purpose of SFRAME_F_FRAME_POINTER flag is to facilitate stack tracers to
246 reliably fallback on the frame pointer based stack tracing method, if SFrame
247 information is not present for some function in the SFrame section.
249 Further flags may be added in future.
251 @node SFrame Header
252 @section SFrame Header
253 @cindex SFrame header
255 The SFrame header is the first part of an SFrame section.  It begins with the
256 SFrame preamble.  All parts of it other than the preamble
257 (@pxref{SFrame Preamble}) can vary between SFrame file versions.  It contains
258 things that apply to the section as a whole, and offsets to the various other
259 sub-sections defined in the format.  As with the rest of the SFrame section,
260 all values are stored in the endianness of the target system.
262 The two sub-sections tile the SFrame section: each section runs from the offset
263 given until the start of the next section.  An explicit length is given for the
264 last sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section.
266 @example
267 typedef struct sframe_header
269   sframe_preamble sfh_preamble;
270   uint8_t sfh_abi_arch;
271   int8_t sfh_cfa_fixed_fp_offset;
272   int8_t sfh_cfa_fixed_ra_offset;
273   uint8_t sfh_auxhdr_len;
274   uint32_t sfh_num_fdes;
275   uint32_t sfh_num_fres;
276   uint32_t sfh_fre_len;
277   uint32_t sfh_fdeoff;
278   uint32_t sfh_freoff;
279 @} ATTRIBUTE_PACKED sframe_header;
280 @end example
282 Every element of the SFrame header is naturally aligned.
284 The sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the
285 SFrame header are relative to the @emph{end} of the SFrame header; they are
286 each an offset in bytes into the SFrame section where the SFrame FDE
287 sub-section and the SFrame FRE sub-section respectively start.
289 The SFrame section contains @code{sfh_num_fdes} number of fixed-length array
290 elements in the SFrame FDE sub-section.  Each array element is of type SFrame
291 function descriptor entry; each providing a high-level function description for
292 the purpose of stack tracing.  More details in a subsequent section.
293 @xref{SFrame Function Descriptor Entries}.
295 Next, the SFrame FRE sub-section, starting at offset @code{sfh_fre_off},
296 describes the stack trace information for each function, using a total of
297 @code{sfh_num_fres} number of variable-length array elements.  Each array
298 element is of type SFrame frame row entry.
299 @xref{SFrame Frame Row Entries}.
301 SFrame header allows specifying explicitly the fixed offsets from CFA, if any,
302 from which FP or RA may be recovered.  For example, in AMD64, the stack offset
303 of the return address is @code{CFA - 8}.  Since these offsets are expected to
304 be in close vicinity to the CFA in most ABIs, @code{sfh_cfa_fixed_fp_offset}
305 and @code{sfh_cfa_fixed_ra_offset} are limited to signed 8-bit integers.
307 @cindex Provisions for future ABIs
308 The SFrame format has made some provisions for supporting more
309 ABIs/architectures in the future.  One of them is the concept of the auxiliary
310 SFrame header.  Bytes in the auxiliary SFrame header may be used to convey
311 further ABI-specific information.  The @code{sframe_header} structure provides
312 an unsigned 8-bit integral field to denote the size (in bytes) of an auxiliary
313 SFrame header.  The auxiliary SFrame header follows right after the
314 @code{sframe_header} structure.  As for the calculation of the sub-section
315 offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, the @emph{end} of
316 SFrame header must be the end of the auxiliary SFrame header, if the latter is
317 present.
319 Putting it all together:
321 @multitable {Offset} {@code{uint32_t}} {@code{sfh_cfa_fixed_fp_offset}} {The number of SFrame FREs in the}
322 @headitem Offset @tab Type @tab Name @tab Description
323 @item 0x00
324 @tab @code{sframe_ @* preamble}
325 @tab @code{sfh_preamble}
326 @tab The SFrame preamble. @xref{SFrame Preamble}.
328 @item 0x04
329 @tab @code{uint8_t}
330 @tab @code{sfh_abi_arch}
331 @tab The ABI/arch identifier.  @xref{SFrame ABI/arch Identifier}.
333 @item 0x05
334 @tab @code{int8_t}
335 @tab @code{sfh_cfa_fixed_fp_offset}
336 @tab The CFA fixed FP offset, if any.
338 @item 0x06
339 @tab @code{int8_t}
340 @tab @code{sfh_cfa_fixed_ra_offset}
341 @tab The CFA fixed RA offset, if any.
343 @item 0x07
344 @tab @code{uint8_t}
345 @tab @code{sfh_auxhdr_len}
346 @tab Size in bytes of the auxiliary header that follows the
347 @code{sframe_header} structure.
349 @item 0x08
350 @tab @code{uint32_t}
351 @tab @code{sfh_num_fdes}
352 @tab The number of SFrame FDEs in the section.
354 @item 0x0c
355 @tab @code{uint32_t}
356 @tab @code{sfh_num_fres}
357 @tab The number of SFrame FREs in the section.
359 @item 0x10
360 @tab @code{uint32_t}
361 @tab @code{sfh_fre_len}
362 @tab The length in bytes of the SFrame FRE sub-section.
364 @item 0x14
365 @tab @code{uint32_t}
366 @tab @code{sfh_fdeoff}
367 @tab The offset in bytes to the SFrame FDE sub-section.
369 @item 0x18
370 @tab @code{uint32_t}
371 @tab @code{sfh_freoff}
372 @tab The offset in bytes to the SFrame FRE sub-section.
374 @end multitable
376 @menu
377 * SFrame ABI/arch Identifier::
378 @end menu
380 @node SFrame ABI/arch Identifier
381 @subsection SFrame ABI/arch Identifier
382 @cindex SFrame ABI/arch Identifier
384 SFrame header identifies the ABI/arch of the target system for which the
385 executable and hence, the stack trace information contained in the SFrame
386 section, is intended.  There are currently three identifiable ABI/arch values
387 in the format.
389 @multitable {SFRAME_ABI_AARCH64_ENDIAN_LITTLE} {Value} {@code{AARCH64 little-endian}}
390 @headitem ABI/arch Identifier @tab Value @tab Description
392 @tindex SFRAME_ABI_AARCH64_ENDIAN_BIG
393 @item @code{SFRAME_ABI_AARCH64_ENDIAN_BIG}
394 @tab 1 @tab AARCH64 big-endian
396 @tindex SFRAME_ABI_AARCH64_ENDIAN_LITTLE
397 @item @code{SFRAME_ABI_AARCH64_ENDIAN_LITTLE}
398 @tab 2 @tab AARCH64 little-endian
400 @tindex SFRAME_ABI_AMD64_ENDIAN_LITTLE
401 @item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE}
402 @tab 3 @tab AMD64 little-endian
404 @end multitable
406 The presence of an explicit identification of ABI/arch in SFrame may allow
407 stack trace generators to make certain ABI/arch-specific decisions.
409 @node SFrame Function Descriptor Entries
410 @section SFrame FDE
411 @cindex SFrame FDE
413 The SFrame function descriptor entry sub-section is an array of the
414 fixed-length SFrame function descriptor entries (SFrame FDEs).  Each SFrame FDE
415 is a packed structure which contains information to describe a function's stack
416 trace information at a high-level.
418 The array of SFrame FDEs is sorted on the @code{sfde_func_start_address} if
419 the SFrame section header flag @code{sfp_flags} has @code{SFRAME_F_FDE_SORTED}
420 set.  Typically (as is the case with GNU ld) a linked object or executable
421 will have the @code{SFRAME_F_FDE_SORTED} set.  This makes the job of a stack
422 tracer easier as it may then employ binary search schemes to look for the
423 pertinent SFrame FDE.
425 @example
426 typedef struct sframe_func_desc_entry
428   int32_t sfde_func_start_address;
429   uint32_t sfde_func_size;
430   uint32_t sfde_func_start_fre_off;
431   uint32_t sfde_func_num_fres;
432   uint8_t sfde_func_info;
433   uint8_t sfde_func_rep_size;
434   uint16_t sfde_func_padding2;
435 @} ATTRIBUTE_PACKED sframe_func_desc_entry;
436 @end example
438 Every element of the SFrame function descriptor entry is naturally aligned.
440 @code{sfde_func_start_fre_off} is the offset to the first SFrame FRE for the
441 function.  This offset is relative to the @emph{end of the SFrame FDE}
442 sub-section (unlike the sub-section offsets in the SFrame header, which are
443 relative to the @emph{end} of the SFrame header).
445 @code{sfde_func_info} is the SFrame FDE "info word", containing information on
446 the FRE type and the FDE type for the function @xref{The SFrame FDE Info Word}.
448 @cindex Provisions for future ABIs
449 Apart from the @code{sfde_func_padding2}, the SFrame FDE has some currently
450 unused bits in the SFrame FDE info word, @xref{The SFrame FDE Info Word}, that
451 may be used for the purpose of extending the SFrame file format specification
452 for future ABIs.
454 Following table describes each component of the SFrame FDE structure:
456 @multitable {Offset} {@code{uint32_t}} {@code{sfde_func_start_fre_off}} {Signed 32-bit integral field denoting the}
457 @headitem Offset @tab Type @tab Name @tab Description
458 @item 0x00
459 @tab @code{int32_t}
460 @tab @code{sfde_func_start_address}
461 @tab Signed 32-bit integral field denoting the virtual memory address of the
462 described function.
464 @item 0x04
465 @tab @code{uint32_t}
466 @tab @code{sfde_func_size}
467 @tab Unsigned 32-bit integral field specifying the size of the function in
468 bytes.
470 @item 0x08
471 @tab @code{uint32_t}
472 @tab @code{sfde_func_start_fre_off}
473 @tab Unsigned 32-bit integral field specifying the offset in bytes of the
474 function's first SFrame FRE in the SFrame section.
476 @item 0x0c
477 @tab @code{uint32_t}
478 @tab @code{sfde_func_num_fres}
479 @tab Unsigned 32-bit integral field specifying the total number of SFrame FREs
480 used for the function.
482 @item 0x10
483 @tab @code{uint8_t}
484 @tab @code{sfde_func_info}
485 @tab Unsigned 8-bit integral field specifying the SFrame FDE info word.
486 @xref{The SFrame FDE Info Word}.
488 @item 0x11
489 @tab @code{uint8_t}
490 @tab @code{sfde_func_rep_size}
491 @tab Unsigned 8-bit integral field specifying the size of the repetitive code
492 block for which an SFrame FDE of type SFRAME_FDE_TYPE_PCMASK is used.  For
493 example, in AMD64, the size of a pltN entry is 16 bytes.
495 @item 0x12
496 @tab @code{uint16_t}
497 @tab @code{sfde_func_padding2}
498 @tab Padding of 2 bytes.  Currently unused bytes.
500 @end multitable
502 @menu
503 * The SFrame FDE Info Word::
504 * The SFrame FDE Types::
505 * The SFrame FRE Types::
506 @end menu
508 @cindex The SFrame FDE Info Word
509 @node The SFrame FDE Info Word
510 @subsection The SFrame FDE Info Word
512 The info word is a bitfield split into three parts.  From MSB to LSB:
514 @multitable {Bit offset} {@code{pauth_key}} {Specify which key is used for signing the return addresses}
515 @headitem Bit offset @tab Name @tab Description
516 @item 7--6
517 @tab @code{unused}
518 @tab Unused bits.
520 @item 5
521 @tab @code{pauth_key}
522 @tab (For AARCH64) Specify which key is used for signing the return addresses
523 in the SFrame FDE.  Two possible values: @*
524 SFRAME_AARCH64_PAUTH_KEY_A (0), or @*
525 SFRAME_AARCH64_PAUTH_KEY_B (1). @*
526 Ununsed in AMD64.
528 @item 4
529 @tab @code{fdetype}
530 @tab Specify the SFrame FDE type.  Two possible values: @*
531 SFRAME_FDE_TYPE_PCMASK (1), or @*
532 SFRAME_FDE_TYPE_PCINC (0). @*
533 @xref{The SFrame FDE Types}.
535 @item 0--3
536 @tab @code{fretype}
537 @tab Choice of three SFrame FRE types. @xref{The SFrame FRE Types}.
538 @end multitable
540 @node The SFrame FDE Types
541 @subsection The SFrame FDE Types
542 @tindex SFRAME_FDE_TYPE_PCMASK
543 @tindex SFRAME_FDE_TYPE_PCINC
545 The SFrame format defines two types of FDE entries.  The choice of which SFrame
546 FDE type to use is made based on the instruction patterns in the relevant
547 program stub.
549 An SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the
550 FREs should be treated as increments in bytes.  This is used fo the the bulk of
551 the executable code of a program, which contains instructions with no specific
552 pattern.
554 In contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an
555 indication that the PCs in the FREs should be treated as masks.  This type is
556 useful for the cases where a small pattern of instructions in a program stub is
557 used repeatedly for a specific functionality.  Typical usecases are pltN
558 entries and trampolines.
560 @multitable {SFRAME_FDE_TYPE_PCMASK} {Value} {Unwinders perform a Unwinders perform a}
561 @headitem Name of SFrame FDE type @tab Value @tab Description
563 @item SFRAME_FDE_TYPE_PCINC
564 @tab 0 @tab Stacktracers perform a @*
565 (PC >= FRE_START_ADDR) to look up a matching FRE.
567 @item SFRAME_FDE_TYPE_PCMASK
568 @tab 1 @tab  Stacktracers perform a @*
569 (PC % REP_BLOCK_SIZE @*
570  >= FRE_START_ADDR)
571 to look up a matching FRE.  REP_BLOCK_SIZE is the size in bytes of the
572 repeating block of program instructions and is encoded via
573 @code{sfde_func_rep_size} in the SFrame FDE.
575 @end multitable
577 @node The SFrame FRE Types
578 @subsection The SFrame FRE Types
580 A real world application can have functions of size big and small.  SFrame
581 format defines three types of SFrame FRE entries to effeciently encode the
582 stack trace information for such a variety of function sizes.  These
583 representations vary in the number of bits needed to encode the start address
584 offset in the SFrame FRE.
586 The following constants are defined and used to identify the SFrame FRE types:
588 @multitable {SFRAME_FRE_TYPE_ADDR1} {@code{Value}} {The start address offset (in bytes) of the}
589 @headitem Name @tab Value @tab Description
591 @tindex SFRAME_FRE_TYPE_ADDR1
592 @item @code{SFRAME_FRE_TYPE_ADDR1}
593 @tab 0
594 @tab The start address offset (in bytes) of the SFrame FRE is an unsigned
595 8-bit value.
597 @tindex SFRAME_FRE_TYPE_ADDR2
598 @item @code{SFRAME_FRE_TYPE_ADDR2}
599 @tab 1
600 @tab The start address offset (in bytes) of the SFrame FRE is an unsigned
601 16-bit value.
603 @tindex SFRAME_FRE_TYPE_ADDR4
604 @item @code{SFRAME_FRE_TYPE_ADDR4}
605 @tab 2
606 @tab The start address offset (in bytes) of the SFrame FRE is an unsigned
607 32-bit value.
608 @end multitable
610 A single function must use the same type of SFrame FRE throughout.  The
611 identifier to reflect the chosen SFrame FRE type is stored in the
612 @code{fretype} bits in the SFrame FDE info word,
613 @xref{The SFrame FDE Info Word}.
615 @node SFrame Frame Row Entries
616 @section SFrame FRE
617 @cindex SFrame FRE
619 The SFrame frame row entry sub-section contains the core of the stack trace
620 information.  An SFrame frame row entry (FRE) is a self-sufficient record
621 containing SFrame stack trace information for a range of contiguous
622 (instruction) addresses, starting at the specified offset from the start of the
623 function.
625 Each SFrame FRE encodes the stack offsets to recover the CFA, FP and RA (where
626 applicable) for the respective instruction addresses.  To encode this
627 information, each SFrame FRE is followed by S*N bytes, where:
629 @itemize @minus
630 @item
631 @code{S} is the size of a stack offset for the FRE, and
632 @item
633 @code{N} is the number of stack offsets in the FRE
634 @end itemize
636 The entities @code{S}, @code{N} are encoded in the SFrame FRE info word, via
637 the @code{fre_offset_size} and the @code{fre_offset_count} respectively.  More
638 information about the precise encoding and range of values for @code{S} and
639 @code{N} is provided later in the @xref{The SFrame FRE Info Word}.
641 @cindex Provisions for future ABIs
642 It is important to underline here that although the canonical interpretation
643 of these bytes is as stack offsets (to recover CFA, FP and RA), these bytes
644 @emph{may} be used by future ABIs/architectures to convey other information on
645 a per SFrame FRE basis.
647 In summary, SFrame file format, by design, supports a variable number of stack
648 offsets at the tail end of each SFrame FRE.  To keep the SFrame file
649 format specification flexible yet extensible, the interpretation of the stack
650 offsets is ABI/arch-specific.  The precise interpretation of the FRE stack
651 offsets in the currently supported ABIs/architectures is covered in the
652 ABI/arch-specific definition of the SFrame file format,
653 @xref{ABI/arch-specific Definition}.
655 Next, the definitions of the three SFrame FRE types are as follows:
657 @example
658 typedef struct sframe_frame_row_entry_addr1
660   uint8_t sfre_start_address;
661   sframe_fre_info sfre_info;
662 @} ATTRIBUTE_PACKED sframe_frame_row_entry_addr1;
663 @end example
665 @example
666 typedef struct sframe_frame_row_entry_addr2
668   uint16_t sfre_start_address;
669   sframe_fre_info sfre_info;
670 @} ATTRIBUTE_PACKED sframe_frame_row_entry_addr2;
671 @end example
673 @example
674 typedef struct sframe_frame_row_entry_addr4
676   uint32_t sfre_start_address;
677   sframe_fre_info sfre_info;
678 @} ATTRIBUTE_PACKED sframe_frame_row_entry_addr4;
679 @end example
681 For ensuring compactness, SFrame frame row entries are stored unaligned on
682 disk.  Appropriate mechanisms need to be employed, as necessary, by the
683 serializing and deserializing entities, if unaligned accesses need to be
684 avoided.
686 @code{sfre_start_address} is an unsigned 8-bit/16-bit/32-bit integral field
687 identifies the start address of the range of program counters, for which the
688 SFrame FRE applies.  The value encoded in the @code{sfre_start_address} field
689 is the offset in bytes of the start address of the SFrame FRE, from the start
690 address of the function.
692 Further SFrame FRE types may be added in future.
694 @menu
695 * The SFrame FRE Info Word::
696 @end menu
698 @cindex The SFrame FRE Info Word
699 @node The SFrame FRE Info Word
700 @subsection The SFrame FRE Info Word
702 The SFrame FRE info word is a bitfield split into four parts.  From MSB to LSB:
704 @multitable {Bit offset} {@code{fre_cfa_base_reg_id}} {Size of stack offsets in bytes.  Valid values}
705 @headitem Bit offset @tab Name @tab Description
706 @item 7
707 @tab @code{fre_mangled_ra_p}
708 @tab Indicate whether the return address is mangled with any authorization bits (signed RA).
710 @item 5-6
711 @tab @code{fre_offset_size}
712 @tab Size of stack offsets in bytes.  Valid values are: @*
713 SFRAME_FRE_OFFSET_1B, @*
714 SFRAME_FRE_OFFSET_2B, and @*
715 SFRAME_FRE_OFFSET_4B.
717 @item 1-4
718 @tab @code{fre_offset_count}
719 @tab A max value of 15 is allowed.  Typically, a value of upto 3 is sufficient
720 for most ABIs to track all three of CFA, FP and RA.
722 @item 0
723 @tab @code{fre_cfa_base_reg_id}
724 @tab Distinguish between SP or FP based CFA recovery.
726 @end multitable
728 @multitable {SFRAME_FRE_OFFSET_4B} {@code{Value}} {All stack offsets following the fixed-length}
729 @headitem Name @tab Value @tab Description
731 @tindex SFRAME_FRE_OFFSET_1B
732 @item @code{SFRAME_FRE_OFFSET_1B}
733 @tab 0
734 @tab All stack offsets following the fixed-length FRE structure are 1 byte
735 long.
737 @tindex SFRAME_FRE_OFFSET_2B
738 @item @code{SFRAME_FRE_OFFSET_2B}
739 @tab 1
740 @tab All stack offsets following the fixed-length FRE structure are 2 bytes
741 long.
743 @tindex SFRAME_FRE_OFFSET_4B
744 @item @code{SFRAME_FRE_OFFSET_4B}
745 @tab 2
746 @tab All stack offsets following the fixed-length FRE structure are 4 bytes
747 long.
749 @end multitable
751 @node ABI/arch-specific Definition
752 @chapter ABI/arch-specific Definition
753 @cindex ABI/arch-specific Definition
755 This section covers the ABI/arch-specific definition of the SFrame file format.
757 Currently, the only part of the SFrame file format definition that is
758 ABI/arch-specific is the interpretation of the variable number of bytes at the
759 tail end of each SFrame FRE.  Currently, these bytes are only used for
760 representing stack offsets (for all the currently supported ABIs).  It is
761 recommended to peruse this section along with @xref{SFrame Frame Row Entries}
762 for clarity of context.
764 Future ABIs must specify the algorithm for identifying the appropriate SFrame
765 FRE stack offsets in this chapter.  This should inevitably include the
766 blueprint for interpreting the variable number of bytes at the tail end of the
767 SFrame FRE for the specific ABI/arch. Any further provisions, e.g., using the
768 auxiliary SFrame header, etc., if used, must also be outlined here.
770 @menu
771 * AMD64::
772 * AArch64::
773 @end menu
775 @node AMD64
776 @section AMD64
778 Irrespective of the ABI, the first stack offset is always used to locate the
779 CFA, by interpreting it as: CFA = @code{BASE_REG} + offset1.  The
780 identification of the @code{BASE_REG} is done by using the
781 @code{fre_cfa_base_reg_id} field in the SFrame FRE info word.
783 In AMD64, the return address (RA) is always saved on stack when a function
784 call is executed.  Further, AMD64 ABI mandates that the RA be saved at a
785 @code{fixed offset} from the CFA when entering a new function.  This means
786 that the RA does not need to be tracked per SFrame FRE.  The fixed offset is
787 encoded in the SFrame file format in the field @code{sfh_cfa_fixed_ra_offset}
788 in the SFrame header.  @xref{SFrame Header}.
790 Hence, the second stack offset (in the SFrame FRE), when present, will be used
791 to locate the FP, by interpreting it as: FP = CFA + offset2.
793 Hence, in summary:
795 @multitable {Offset ID} {Interpretation in AMD64 in AMD64}
796 @headitem Offset ID @tab Interpretation in AMD64
797 @item 1 @tab CFA = @code{BASE_REG} + offset1
798 @item 2 @tab FP = CFA + offset2
799 @end multitable
801 @node AArch64
802 @section AArch64
804 Irrespective of the ABI, the first stack offset is always used to locate the
805 CFA, by interpreting it as: CFA = @code{BASE_REG} + offset1.  The
806 identification of the @code{BASE_REG} is done by using the
807 @code{fre_cfa_base_reg_id} field in the SFrame FRE info word.
809 In AARCH64, the AAPCS64 standard specifies that the Frame Record saves both FP
810 and LR (a.k.a the RA).  However, the standard does not mandate the precise
811 location in the function where the frame record is created, if at all.  Hence
812 the need to track RA in the SFrame stack trace format.  As RA is being tracked
813 in this ABI, the second stack offset is always used to locate the RA, by
814 interpreting it as: RA = CFA + offset2. The third stack offset will be used to
815 locate the FP, by interpreting it as: FP = CFA + offset3.
817 Given the nature of things, the number of stack offsets seen on AARCH64 per
818 SFrame FRE is either 1 or 3.
820 Hence, in summary:
822 @multitable {Offset ID} {Interpretation in AArch64 in X}
823 @headitem Offset ID @tab Interpretation in AArch64
824 @item 1 @tab CFA = @code{BASE_REG} + offset1
825 @item 2 @tab RA = CFA + offset2
826 @item 3 @tab FP = CFA + offset3
827 @end multitable
829 @node Generating Stack Traces using SFrame
830 @appendix Generating Stack Traces using SFrame
832 Using some C-like pseudocode, this section highlights how SFrame provides a
833 simple, fast and low-overhead mechanism to generate stack traces.  Needless to
834 say that for generating accurate and useful stack traces, several other aspects
835 will need attention: finding and decoding bits of SFrame section(s) in the
836 program binary, symbolization of addresses, to name a few.
838 In the current context, a @code{frame} is the abstract construct that
839 encapsulates the following information:
840 @itemize @minus
841 @item
842 program counter (PC),
843 @item
844 stack pointer (SP), and
845 @item
846 frame pointer (FP)
847 @end itemize
849 With that said, establishing the first @code{frame} should be trivial:
851 @example
852     // frame 0
853     frame->pc = current_IP;
854     frame->sp = get_reg_value (REG_SP);
855     frame->fp = get_reg_value (REG_FP);
856 @end example
858 where @code{REG_SP} and @code{REG_FP} are are ABI-designated stack pointer and
859 frame pointer registers respectively.
861 Next, given frame N, generating stack trace needs us to get frame N+1.  This
862 can be done as follows:
864 @example
865      // Get the PC, SP, and FP for frame N.
866      pc = frame->pc;
867      sp = frame->sp;
868      fp = frame->fp;
869      // Populate frame N+1.
870      int err = get_next_frame (&next_frame, pc, sp, fp);
871 @end example
873 where given the values of the program counter, stack pointer and frame pointer
874 from frame N, @code{get_next_frame} populates the provided @code{next_frame}
875 object and returns the error code, if any. In the following pseudocode for
876 @code{get_next_frame}, the @code{sframe_*} functions fetch information from the
877 SFrame section.
879 @example
880     fre = sframe_find_fre (pc);
881     if (fre)
882         // Whether the base register for CFA tracking is REG_FP.
883         base_reg_val = sframe_fre_base_reg_fp_p (fre) ? fp : sp;
884         // Get the CFA stack offset from the FRE.
885         cfa_offset = sframe_fre_get_cfa_offset (fre);
886         // Get the fixed RA offset or FRE stack offset as applicable.
887         ra_offset = sframe_fre_get_ra_offset (fre);
888         // Get the fixed FP offset or FRE stack offset as applicable.
889         fp_offset = sframe_fre_get_fp_offset (fre);
891         cfa = base_reg_val + cfa_offset;
892         next_frame->sp = cfa;
894         ra_stack_loc = cfa + ra_offset;
895         // Get the address stored in the stack location.
896         next_frame->pc = read_value (ra_stack_loc);
898         if (fp_offset is VALID)
899             fp_stack_loc = cfa + fp_offset;
900             // Get the value stored in the stack location.
901             next_frame->fp = read_value (fp_stack_loc);
902         else
903             // Continue to use the value of fp as it has not
904             // been clobbered by the current frame yet.
905             next_frame->fp = fp;
906     else
907         ret = ERR_NO_SFRAME_FRE;
908 @end example
910 @node Index
911 @unnumbered Index
913 @syncodeindex tp cp
914 @printindex cp
916 @bye