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