1\input texinfo       @c                    -*- Texinfo -*-
2@setfilename sframe-spec.info
3@settitle The SFrame Format
4
5@copying
6Copyright @copyright{} 2021-2022 Free Software Foundation, Inc.
7
8Permission is granted to copy, distribute and/or modify this document
9under the terms of the GNU General Public License, Version 3 or any
10later version published by the Free Software Foundation.  A copy of the
11license is included in the section entitled ``GNU General Public
12License''.
13
14@end copying
15
16@dircategory Software development
17@direntry
18* SFrame: (sframe-spec).         The Simple Frame format.
19@end direntry
20
21@titlepage
22@title The SFrame Format
23@subtitle Version 1
24@author Indu Bhagat
25
26@page
27@vskip 0pt plus 1filll
28@insertcopying
29@end titlepage
30@contents
31
32@ifnottex
33@node Top
34@top The SFrame format
35
36This manual describes version 1 of the SFrame file format.  SFrame stands for
37Simple Frame format.  SFrame format keeps track of the minimal necessary
38information needed for stack unwinding:
39
40@itemize @minus
41@item
42Canonical Frame Address (CFA).
43@item
44Frame Pointer (FP).
45@item
46Return Address (RA).
47@end itemize
48
49The reason for existence of the SFrame format is to support fast, online
50backtracing using a simple unwinder.
51
52@menu
53* Overview::
54* SFrame section::
55* Index::
56@end menu
57
58@end ifnottex
59
60@node Overview
61@unnumbered Overview
62@cindex Overview
63@tindex PT_GNU_SFRAME
64
65The SFrame unwind information is provided in a loaded section, known as the
66@code{.sframe} section.  When available, the @code{.sframe} section appears in
67a new segment of its own, PT_GNU_SFRAME.
68
69The SFrame format is currently supported only for select ABIs, namely, AMD64
70and AAPCS64.
71
72The contents of the SFrame section are stored in the target endianness, i.e.,
73in the endianness of the system on which the section is targetted to be used.
74An SFrame section reader may use the magic number in the SFrame header to
75identify the endianness of the SFrame section.
76
77Addresses in this specification are expressed in bytes.
78
79The associated API to decode, probe and encode the SFrame section, provided via
80@code{libsframe}, is not accompanied here at this time.  This will be added
81later.
82
83This document is intended to be in sync with the C code in @file{sframe.h}.
84Please report descrepancies between the two, if any.
85
86@node SFrame section
87@chapter SFrame section
88@cindex SFrame section
89
90The SFrame section consists of an SFrame header, starting with a preamble, and
91two other sub-sections, namely the SFrame Function Descriptor Entry (SFrame
92FDE) sub-section, and the SFrame Frame Row Entry (SFrame FRE) sub-section.
93
94@menu
95* SFrame Preamble::
96* SFrame Header::
97* SFrame Function Descriptor Entries::
98* SFrame Frame Row Entries::
99@end menu
100
101@node SFrame Preamble
102@section SFrame Preamble
103@cindex SFrame preamble
104
105The preamble is a 32-bit packed structure; the only part of the SFrame whose
106format cannot vary between versions.
107
108@example
109typedef struct sframe_preamble
110@{
111  uint16_t sfp_magic;
112  uint8_t sfp_version;
113  uint8_t sfp_flags;
114@} ATTRIBUTE_PACKED sframe_preamble;
115@end example
116
117All values are stored in the endianness of the target system for which the
118SFrame section is intended.  Further details:
119
120@multitable {Offset} {@code{uint8_t sfp_version}} {The magic number for SFrame section: 0xdee2.  Defined}
121@headitem Offset @tab Name @tab Description
122@item 0x00
123@tab @code{uint16_t sfp_magic}
124@tab The magic number for SFrame section: 0xdee2.  Defined as a macro @code{SFRAME_MAGIC}.
125@tindex SFRAME_MAGIC
126
127@item 0x02
128@tab @code{uint8_t sfp_version}
129@tab The version number of this SFrame section.  @xref{SFrame version}, for the
130set of valid values.  Current version is
131@code{SFRAME_VERSION_1}.
132
133@item 0x03
134@tab @code{uint8_t sfp_flags}
135@tab Flags (section-wide) for this SFrame section.  @xref{SFrame flags}, for the
136set of valid values.
137@end multitable
138
139@menu
140* SFrame endianness::
141* SFrame version::
142* SFrame flags::
143@end menu
144
145@node SFrame endianness
146@subsection SFrame endianness
147
148@cindex endianness
149SFrame sections are stored in the target endianness of the system that consumes
150them.  The SFrame library (@code{libsframe}) can, however, detect whether to
151endian-flip an SFrame section at decode time, by inspecting the
152@code{sfp_magic} field in the SFrame header (If it appears as 0xe2de,
153endian-flipping is needed).
154
155@node SFrame version
156@subsection SFrame version
157
158The version of the SFrame format can be determined by inspecting
159@code{sfp_version}.  The following versions are currently valid:
160
161@tindex SFRAME_VERSION_1
162@cindex SFrame versions
163@multitable {SFRAME_VERSION_1} {Number} {First version, under development.}
164@headitem Version @tab Number @tab Description
165@item @code{SFRAME_VERSION_1}
166@tab 1 @tab First version, under development.
167@end multitable
168
169This section documents @code{SFRAME_VERSION_1}.
170
171@node SFrame flags
172@subsection SFrame flags
173@cindex SFrame flags
174@comment @vindex sfp_flags
175@comment @vindex SFrame section-wide flags
176@comment @subsection SFrame section-wide flags
177
178The preamble contains bitflags in its @code{sfp_flags} field that
179describe various section-wide properties.
180
181The following flags are currently defined.
182
183@multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries}
184@headitem Flag @tab Versions @tab Value @tab Meaning
185@tindex SFRAME_F_FDE_SORTED
186@item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor
187Entries are sorted on PC.
188@tindex SFRAME_F_FRAME_POINTER
189@item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2
190@tab Functions preserve frame-pointer.
191@end multitable
192
193Further flags may be added in future.
194
195@node SFrame Header
196@section SFrame Header
197@cindex SFrame header
198
199The SFrame header is the first part of an SFrame section.  It begins with the
200SFrame preamble.  All parts of it other than the preamble
201(@pxref{SFrame Preamble}) can vary between SFrame file versions.  It contains
202things that apply to the section as a whole, and offsets to the various other
203sub-sections defined in the format.  As with the rest of the SFrame section,
204all values are stored in the endianness of the target system.
205
206The two sub-sections tile the SFrame section: each section runs from the offset
207given until the start of the next section.  An explicit length is given for the
208last sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section.
209
210@example
211typedef struct sframe_header
212@{
213  sframe_preamble sfh_preamble;
214  uint8_t sfh_abi_arch;
215  int8_t sfh_cfa_fixed_fp_offset;
216  int8_t sfh_cfa_fixed_ra_offset;
217  uint8_t sfh_auxhdr_len;
218  uint32_t sfh_num_fdes;
219  uint32_t sfh_num_fres;
220  uint32_t sfh_fre_len;
221  uint32_t sfh_fdeoff;
222  uint32_t sfh_freoff;
223@} ATTRIBUTE_PACKED sframe_header;
224@end example
225
226The sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the
227SFrame header are relative to the @emph{end} of the SFrame header; they are
228each an offset in bytes into the SFrame section where the SFrame FDE
229sub-section and the SFrame FRE sub-section respectively start.
230
231SFrame header allows specifying explicitly the fixed offsets from CFA, if any,
232from which FP or RA may be recovered.  For example, in AMD64, the stack offset
233of the return address is @code{CFA - 8}.  Since this offset is in close
234vicinity with the CFA in most ABIs, @code{sfh_cfa_fixed_fp_offset} and
235@code{sfh_cfa_fixed_ra_offset} are limited to signed 8-bit integers.
236
237SFrame format has provisioned for future ABIs/architectures that it may
238support.  The @code{sframe_header} structure provides an unsigned 8-bit
239integral field to denote the size of an auxilliary SFrame header.  The
240auxilliary SFrame header follows right after the @code{sframe_header}
241structure.  As for the offset calculations, the @emph{end} of SFrame header
242must be the end of the auxilliary SFrame header, if the latter is present.
243
244Tieing it all together:
245
246@multitable {Offset} {@code{int8_t sfh_cfa_fixed_fp_offset}} {The ABI/arch identifier. See above}
247@headitem Offset @tab Name @tab Description
248@item 0x00
249@tab @code{sframe_preamble sfh_preamble}
250@tab The SFrame preamble. @xref{SFrame Preamble}.
251
252@item 0x04
253@tab @code{uint8_t sfh_abi_arch}
254@tab The ABI/arch identifier.  @xref{SFrame ABI/arch identifier}.
255
256@item 0x05
257@tab @code{int8_t sfh_cfa_fixed_fp_offset}
258@tab The CFA fixed FP offset, if any.
259
260@item 0x06
261@tab @code{int8_t sfh_cfa_fixed_ra_offset}
262@tab The CFA fixed RA offset, if any.
263
264@item 0x07
265@tab @code{uint8_t sfh_auxhdr_len}
266@tab Size in bytes of the auxilliary header that follows the
267@code{sframe_header} structure.
268
269@item 0x08
270@tab @code{uint32_t sfh_num_fdes}
271@tab The number of SFrame FDEs in the section.
272
273@item 0xc
274@tab @code{uint32_t sfh_num_fres}
275@tab The number of SFrame FREs in the section.
276
277@item 0x10
278@tab @code{uint32_t sfh_fre_len}
279@tab The length in bytes of the SFrame FRE sub-section.
280
281@item 0x14
282@tab @code{uint32_t sfh_fdeoff}
283@tab The offset in bytes of the SFrame FDE sub-section.  This sub-section
284contains @code{sfh_num_fdes} number of fixed-length array elements.  The array
285element is of type SFrame function desciptor entry, each providing a
286high-level function description for backtracing.
287@xref{SFrame Function Descriptor Entries}.
288
289@item 0x18
290@tab @code{uint32_t sfh_freoff}
291@tab The offset in bytes of the SFrame FRE sub-section, the core of the SFrame
292section, which describes the unwind information using variable-length array
293elements. @xref{SFrame Frame Row Entries}.
294
295@end multitable
296
297@menu
298* SFrame ABI/arch identifier::
299@end menu
300
301@node SFrame ABI/arch identifier
302@subsection SFrame ABI/arch identifier
303@cindex SFrame ABI/arch identifier
304
305SFrame header identifies the ABI/arch of the target system for which the
306executable and it's unwind information is intended.  There are currently three
307identifiable ABI/arch values in the format.
308
309@multitable {SFRAME_ABI_AARCH64_ENDIAN_LITTLE} {Value} {@code{AARCH64 little-endian}}
310@headitem ABI/arch Identifier @tab Value @tab Description
311
312@tindex SFRAME_ABI_AARCH64_ENDIAN_BIG
313@item @code{SFRAME_ABI_AARCH64_ENDIAN_BIG}
314@tab 1 @tab AARCH64 big-endian
315
316@tindex SFRAME_ABI_AARCH64_ENDIAN_LITTLE
317@item @code{SFRAME_ABI_AARCH64_ENDIAN_LITTLE}
318@tab 2 @tab AARCH64 little-endian
319
320@tindex SFRAME_ABI_AMD64_ENDIAN_LITTLE
321@item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE}
322@tab 3 @tab AMD64 little-endian
323
324@end multitable
325
326The presence of an explicit identification of ABI/arch in SFrame may allow
327unwinders to make certain ABI-specific decisions.
328
329@node SFrame Function Descriptor Entries
330@section SFrame FDE
331@cindex SFrame FDE
332
333The SFrame Function Descriptor Entry sub-section is a sorted array of
334fixed-length SFrame function descriptor entries (SFrame FDEs).  Each SFrame FDE
335is a packed structure which contains information to describe a function's unwind
336information at a high-level.
337
338@example
339typedef struct sframe_func_desc_entry
340@{
341  int32_t sfde_func_start_address;
342  uint32_t sfde_func_size;
343  uint32_t sfde_func_start_fre_off;
344  uint32_t sfde_func_num_fres;
345  uint8_t sfde_func_info;
346@} ATTRIBUTE_PACKED sframe_func_desc_entry;
347@end example
348
349@code{sfde_func_start_fre_off} is the offset to the first SFrame FRE for the
350function.  This offset is relative to the @emph{end of the SFrame FDE}
351sub-section (unlike the offsets in the SFrame header, which are relative to the
352@emph{end} of the SFrame header).
353
354@code{sfde_func_info} is the "info word", containing information on the FRE
355type and the FDE type for the function @xref{The SFrame FDE info word}.
356
357Following table describes each component of the SFrame FDE structure:
358
359@multitable {Offset} {@code{uint32_t sfde_func_start_fre_off}} {The ABI/arch identifier. See above}
360@headitem Offset @tab Name @tab Description
361@item 0x00
362@tab @code{int32_t sfde_func_start_address}
363@tab Signed 32-bit integral field denoting the virtual memory address of the
364described function.
365
366@item 0x04
367@tab @code{uint32_t sfde_func_size}
368@tab Unsigned 32-bit integral field specifying the size of the function in
369bytes.
370
371@item 0x08
372@tab @code{uint32_t sfde_func_start_fre_off}
373@tab Unsigned 32-bit integral field specifying the offset in bytes of the
374function's first SFrame FRE in the SFrame section.
375
376@item 0x0c
377@tab @code{uint32_t sfde_func_num_fres}
378@tab Unsigned 32-bit integral field specifying the total number of SFrame FREs
379used for the function.
380
381@item 0x10
382@tab @code{uint8_t sfde_func_info}
383@tab The SFrame FDE info word. @xref{The SFrame FDE info word}.
384
385@end multitable
386
387@menu
388* The SFrame FDE info word::
389* The SFrame FDE types::
390* The SFrame FRE types::
391@end menu
392
393@cindex The SFrame FDE info word
394@node The SFrame FDE info word
395@subsection The SFrame FDE info word
396
397The info word is a bitfield split into three parts.  From MSB to LSB:
398
399@multitable {Bit offset} {@code{isroot}} {Length of variable-length data for this type (some kinds only).}
400@headitem Bit offset @tab Name @tab Description
401@item 7--5
402@tab @code{unused}
403@tab Unused bits.
404
405@item 4
406@tab @code{fdetype}
407@tab SFRAME_FDE_TYPE_PCMASK (1) or SFRAME_FDE_TYPE_PCINC (0). @xref{The SFrame FDE types}.
408
409@item 0--3
410@tab @code{fretype}
411@tab Choice of three SFrame FRE types. @xref{The SFrame FRE types}.
412@end multitable
413
414@node The SFrame FDE types
415@subsection The SFrame FDE types
416@tindex SFRAME_FDE_TYPE_PCMASK
417@tindex SFRAME_FDE_TYPE_PCINC
418
419SFrame format defines two types of FDE entries.  The choice of which SFrame FDE
420type to use is made based on the instruction patterns in the relevant program
421stub.
422
423An SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the
424FREs should be treated as increments in bytes.  This is used fo the the bulk of
425the executable code of a program, which contains instructions with no specific
426pattern.
427
428In contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an
429indication that the PCs in the FREs should be treated as masks.  This type is
430useful for the cases where a small pattern of instructions in a program stub is
431used repeatedly for a specific functionality.  Typical usecases are pltN
432entries and trampolines.
433
434@multitable {Name of SFrame FDE type} {Value} {Unwinders perform a (PC >= FRE_START_ADDR)}
435@headitem Name of SFrame FDE type @tab Value @tab Description
436
437@item SFRAME_FDE_TYPE_PCINC
438@tab 0 @tab Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE.
439
440@item SFRAME_FDE_TYPE_PCMASK
441@tab 1 @tab  Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK)
442to look up a matching FRE.
443
444@end multitable
445
446@node The SFrame FRE types
447@subsection The SFrame FRE types
448
449A real world application can have functions of size big and small.  SFrame
450format defines three types of SFrame FRE entries to represent the unwind
451information for such a variety of function sizes.  These representations vary
452in the number of bits needed to encode the start address offset in the SFrame
453FRE.
454
455The following constants are defined and used to identify the SFrame FRE types:
456
457@multitable {SFRAME_FRE_TYPE_ADDR1} {@code{Value}} {The start address offset of FRE is an}
458@headitem Name @tab Value @tab Description
459
460@tindex SFRAME_FRE_TYPE_ADDR1
461@item @code{SFRAME_FRE_TYPE_ADDR1}
462@tab 0
463@tab The start address offset (in bytes) of the SFrame FRE is an unsigned
4648-bit value.
465
466@tindex SFRAME_FRE_TYPE_ADDR2
467@item @code{SFRAME_FRE_TYPE_ADDR2}
468@tab 1
469@tab The start address offset (in bytes) of the SFrame FRE is an unsigned
47016-bit value.
471
472@tindex SFRAME_FRE_TYPE_ADDR4
473@item @code{SFRAME_FRE_TYPE_ADDR4}
474@tab 2
475@tab The start address offset (in bytes) of the SFrame FRE is an unsigned
47632-bit value.
477@end multitable
478
479A single function must use the same type of FRE throughout.  The choice of
480which SFrame FRE is used to encode the unwind information of a function, is
481stored in the @xref{The SFrame FDE info word}.
482
483@node SFrame Frame Row Entries
484@section SFrame FRE
485@cindex SFrame FRE
486
487The SFrame Frame Row Entry sub-section contains the core of the unwind
488information.
489
490An SFrame Frame Row Entry is a self-sufficient record containing SFrame unwind
491info for a range of contiguous addresses, starting at the specified offset from
492the start of the function.  Each SFrame Frame Row Entry is followed by S*N
493bytes, where:
494
495@itemize @minus
496@item
497@code{S} is the size of the stack frame offset for the FRE, and
498@item
499@code{N} is the number of stack frame offsets in the FRE
500@end itemize
501
502The stack offsets, following the FRE, are interpreted in order as follows:
503
504@itemize @minus
505@item
506The first offset is always used to locate the CFA, by interpreting it as:
507CFA = @code{BASE_REG} + offset1.
508@item
509If RA is being tracked, the second offset is always used to locate the RA, by
510interpreting it as: RA = CFA + offset2.  If RA is @emph{not} being tracked
511@emph{and} FP is being tracked, the second offset will be used to locate the
512FP, by interpreting it as: FP = CFA + offset2.
513@item
514If both RA and FP are being tracked, the third offset will be used to locate
515the FP, by interpreting it as FP = CFA + offset3.
516@end itemize
517
518The entities @code{S}, @code{N} and @code{BASE_REG} are identified using the
519SFrame FRE info word, a.k.a. the @code{sframe_fre_info}
520@xref{The SFrame FRE info word}.
521
522Following are the definitions of the allowed SFrame FRE:
523
524@example
525typedef struct sframe_frame_row_entry_addr1
526@{
527  uint8_t sfre_start_address;
528  sframe_fre_info sfre_info;
529@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr1;
530@end example
531
532@example
533typedef struct sframe_frame_row_entry_addr2
534@{
535  uint16_t sfre_start_address;
536  sframe_fre_info sfre_info;
537@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr2;
538@end example
539
540@example
541typedef struct sframe_frame_row_entry_addr4
542@{
543  uint32_t sfre_start_address;
544  sframe_fre_info sfre_info;
545@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr4;
546@end example
547
548@code{sfre_start_address} is an unsigned 8-bit/16-bit/32-bit integral field
549identifies the start address of the range of program counters, for which the
550SFrame FRE applies.  The value encoded in the @code{sfre_start_address} field
551is the offset in bytes of the start address of the SFrame FRE, from the start
552address of the function.
553
554Further FRE types may be added in future.
555
556@menu
557* The SFrame FRE info word::
558@end menu
559
560@cindex The SFrame FRE info word
561@node The SFrame FRE info word
562@subsection The SFrame FRE info word
563
564The SFrame FRE info word is a bitfield split into four parts.  From MSB to LSB:
565
566@multitable {Bit offset} {@code{fre_cfa_base_reg_id}} {Size of stack offsets in bytes.  Valid values}
567@headitem Bit offset @tab Name @tab Description
568@item 7
569@tab @code{fre_mangled_ra_p}
570@tab Indicate whether the return address is mangled with any authorization bits (signed RA).
571
572@item 5-6
573@tab @code{fre_offset_size}
574@tab Size of stack offsets in bytes.  Valid values are SFRAME_FRE_OFFSET_1B,
575SFRAME_FRE_OFFSET_2B, and SFRAME_FRE_OFFSET_4B.
576
577@item 1-4
578@tab @code{fre_offset_count}
579@tab A value of upto 3 is allowed to track all three of CFA, FP and RA.
580
581@item 0
582@tab @code{fre_cfa_base_reg_id}
583@tab Distinguish between SP or FP based CFA recovery.
584
585@end multitable
586
587@multitable {SFRAME_FRE_OFFSET_4B} {@code{Value}} {All stack offsets following the fixed-length}
588@headitem Name @tab Value @tab Description
589
590@tindex SFRAME_FRE_OFFSET_1B
591@item @code{SFRAME_FRE_OFFSET_1B}
592@tab 0
593@tab All stack offsets following the fixed-length FRE structure are 1 byte
594long.
595
596@tindex SFRAME_FRE_OFFSET_2B
597@item @code{SFRAME_FRE_OFFSET_2B}
598@tab 1
599@tab All stack offsets following the fixed-length FRE structure are 2 bytes
600long.
601
602@tindex SFRAME_FRE_OFFSET_4B
603@item @code{SFRAME_FRE_OFFSET_4B}
604@tab 2
605@tab All stack offsets following the fixed-length FRE structure are 4 bytes
606long.
607
608@end multitable
609
610@node Index
611@unnumbered Index
612
613@syncodeindex tp cp
614@printindex cp
615
616@bye
617