sframe-spec.texi revision 1.1 1 \input texinfo @c -*- Texinfo -*-
2 @setfilename sframe-spec.info
3 @settitle The SFrame Format
4
5 @copying
6 Copyright @copyright{} 2021-2022 Free Software Foundation, Inc.
7
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''.
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
36 This manual describes version 1 of the SFrame file format. SFrame stands for
37 Simple Frame format. SFrame format keeps track of the minimal necessary
38 information needed for stack unwinding:
39
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
48
49 The reason for existence of the SFrame format is to support fast, online
50 backtracing 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
65 The SFrame unwind information is provided in a loaded section, known as the
66 @code{.sframe} section. When available, the @code{.sframe} section appears in
67 a new segment of its own, PT_GNU_SFRAME.
68
69 The SFrame format is currently supported only for select ABIs, namely, AMD64
70 and AAPCS64.
71
72 The contents of the SFrame section are stored in the target endianness, i.e.,
73 in the endianness of the system on which the section is targetted to be used.
74 An SFrame section reader may use the magic number in the SFrame header to
75 identify the endianness of the SFrame section.
76
77 Addresses in this specification are expressed in bytes.
78
79 The 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
81 later.
82
83 This document is intended to be in sync with the C code in @file{sframe.h}.
84 Please report descrepancies between the two, if any.
85
86 @node SFrame section
87 @chapter SFrame section
88 @cindex SFrame section
89
90 The SFrame section consists of an SFrame header, starting with a preamble, and
91 two other sub-sections, namely the SFrame Function Descriptor Entry (SFrame
92 FDE) 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
105 The preamble is a 32-bit packed structure; the only part of the SFrame whose
106 format cannot vary between versions.
107
108 @example
109 typedef 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
117 All values are stored in the endianness of the target system for which the
118 SFrame 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
130 set 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
136 set 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
149 SFrame sections are stored in the target endianness of the system that consumes
150 them. The SFrame library (@code{libsframe}) can, however, detect whether to
151 endian-flip an SFrame section at decode time, by inspecting the
152 @code{sfp_magic} field in the SFrame header (If it appears as 0xe2de,
153 endian-flipping is needed).
154
155 @node SFrame version
156 @subsection SFrame version
157
158 The 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
169 This 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
178 The preamble contains bitflags in its @code{sfp_flags} field that
179 describe various section-wide properties.
180
181 The 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
187 Entries 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
193 Further flags may be added in future.
194
195 @node SFrame Header
196 @section SFrame Header
197 @cindex SFrame header
198
199 The SFrame header is the first part of an SFrame section. It begins with the
200 SFrame preamble. All parts of it other than the preamble
201 (@pxref{SFrame Preamble}) can vary between SFrame file versions. It contains
202 things that apply to the section as a whole, and offsets to the various other
203 sub-sections defined in the format. As with the rest of the SFrame section,
204 all values are stored in the endianness of the target system.
205
206 The two sub-sections tile the SFrame section: each section runs from the offset
207 given until the start of the next section. An explicit length is given for the
208 last sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section.
209
210 @example
211 typedef 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
226 The sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the
227 SFrame header are relative to the @emph{end} of the SFrame header; they are
228 each an offset in bytes into the SFrame section where the SFrame FDE
229 sub-section and the SFrame FRE sub-section respectively start.
230
231 SFrame header allows specifying explicitly the fixed offsets from CFA, if any,
232 from which FP or RA may be recovered. For example, in AMD64, the stack offset
233 of the return address is @code{CFA - 8}. Since this offset is in close
234 vicinity 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
237 SFrame format has provisioned for future ABIs/architectures that it may
238 support. The @code{sframe_header} structure provides an unsigned 8-bit
239 integral field to denote the size of an auxilliary SFrame header. The
240 auxilliary SFrame header follows right after the @code{sframe_header}
241 structure. As for the offset calculations, the @emph{end} of SFrame header
242 must be the end of the auxilliary SFrame header, if the latter is present.
243
244 Tieing 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
284 contains @code{sfh_num_fdes} number of fixed-length array elements. The array
285 element is of type SFrame function desciptor entry, each providing a
286 high-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
292 section, which describes the unwind information using variable-length array
293 elements. @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
305 SFrame header identifies the ABI/arch of the target system for which the
306 executable and it's unwind information is intended. There are currently three
307 identifiable 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
326 The presence of an explicit identification of ABI/arch in SFrame may allow
327 unwinders to make certain ABI-specific decisions.
328
329 @node SFrame Function Descriptor Entries
330 @section SFrame FDE
331 @cindex SFrame FDE
332
333 The SFrame Function Descriptor Entry sub-section is a sorted array of
334 fixed-length SFrame function descriptor entries (SFrame FDEs). Each SFrame FDE
335 is a packed structure which contains information to describe a function's unwind
336 information at a high-level.
337
338 @example
339 typedef 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
350 function. This offset is relative to the @emph{end of the SFrame FDE}
351 sub-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
355 type and the FDE type for the function @xref{The SFrame FDE info word}.
356
357 Following 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
364 described 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
369 bytes.
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
374 function'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
379 used 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
397 The 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
419 SFrame format defines two types of FDE entries. The choice of which SFrame FDE
420 type to use is made based on the instruction patterns in the relevant program
421 stub.
422
423 An SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the
424 FREs should be treated as increments in bytes. This is used fo the the bulk of
425 the executable code of a program, which contains instructions with no specific
426 pattern.
427
428 In contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an
429 indication that the PCs in the FREs should be treated as masks. This type is
430 useful for the cases where a small pattern of instructions in a program stub is
431 used repeatedly for a specific functionality. Typical usecases are pltN
432 entries 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)
442 to look up a matching FRE.
443
444 @end multitable
445
446 @node The SFrame FRE types
447 @subsection The SFrame FRE types
448
449 A real world application can have functions of size big and small. SFrame
450 format defines three types of SFrame FRE entries to represent the unwind
451 information for such a variety of function sizes. These representations vary
452 in the number of bits needed to encode the start address offset in the SFrame
453 FRE.
454
455 The 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
464 8-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
470 16-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
476 32-bit value.
477 @end multitable
478
479 A single function must use the same type of FRE throughout. The choice of
480 which SFrame FRE is used to encode the unwind information of a function, is
481 stored in the @xref{The SFrame FDE info word}.
482
483 @node SFrame Frame Row Entries
484 @section SFrame FRE
485 @cindex SFrame FRE
486
487 The SFrame Frame Row Entry sub-section contains the core of the unwind
488 information.
489
490 An SFrame Frame Row Entry is a self-sufficient record containing SFrame unwind
491 info for a range of contiguous addresses, starting at the specified offset from
492 the start of the function. Each SFrame Frame Row Entry is followed by S*N
493 bytes, 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
502 The stack offsets, following the FRE, are interpreted in order as follows:
503
504 @itemize @minus
505 @item
506 The first offset is always used to locate the CFA, by interpreting it as:
507 CFA = @code{BASE_REG} + offset1.
508 @item
509 If RA is being tracked, the second offset is always used to locate the RA, by
510 interpreting 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
512 FP, by interpreting it as: FP = CFA + offset2.
513 @item
514 If both RA and FP are being tracked, the third offset will be used to locate
515 the FP, by interpreting it as FP = CFA + offset3.
516 @end itemize
517
518 The entities @code{S}, @code{N} and @code{BASE_REG} are identified using the
519 SFrame FRE info word, a.k.a. the @code{sframe_fre_info}
520 @xref{The SFrame FRE info word}.
521
522 Following are the definitions of the allowed SFrame FRE:
523
524 @example
525 typedef 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
533 typedef 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
541 typedef 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
549 identifies the start address of the range of program counters, for which the
550 SFrame FRE applies. The value encoded in the @code{sfre_start_address} field
551 is the offset in bytes of the start address of the SFrame FRE, from the start
552 address of the function.
553
554 Further 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
564 The 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,
575 SFRAME_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
594 long.
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
600 long.
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
606 long.
607
608 @end multitable
609
610 @node Index
611 @unnumbered Index
612
613 @syncodeindex tp cp
614 @printindex cp
615
616 @bye
617