1*cb63e24eSchristos\input texinfo @c -*- Texinfo -*- 2*cb63e24eSchristos@setfilename sframe-spec.info 3*cb63e24eSchristos@settitle The SFrame Format 4*cb63e24eSchristos 5*cb63e24eSchristos@copying 6*cb63e24eSchristosCopyright @copyright{} 2021-2024 Free Software Foundation, Inc. 7*cb63e24eSchristos 8*cb63e24eSchristosPermission is granted to copy, distribute and/or modify this document 9*cb63e24eSchristosunder the terms of the GNU General Public License, Version 3 or any 10*cb63e24eSchristoslater version published by the Free Software Foundation. A copy of the 11*cb63e24eSchristoslicense is included in the section entitled ``GNU General Public 12*cb63e24eSchristosLicense''. 13*cb63e24eSchristos 14*cb63e24eSchristos@end copying 15*cb63e24eSchristos 16*cb63e24eSchristos@dircategory Software development 17*cb63e24eSchristos@direntry 18*cb63e24eSchristos* SFrame: (sframe-spec). The Simple Frame format. 19*cb63e24eSchristos@end direntry 20*cb63e24eSchristos 21*cb63e24eSchristos@titlepage 22*cb63e24eSchristos@title The SFrame Format 23*cb63e24eSchristos@subtitle Version 2 24*cb63e24eSchristos@author Indu Bhagat 25*cb63e24eSchristos 26*cb63e24eSchristos@page 27*cb63e24eSchristos@vskip 0pt plus 1filll 28*cb63e24eSchristos@insertcopying 29*cb63e24eSchristos@end titlepage 30*cb63e24eSchristos@contents 31*cb63e24eSchristos 32*cb63e24eSchristos@ifnottex 33*cb63e24eSchristos@node Top 34*cb63e24eSchristos@top The SFrame format 35*cb63e24eSchristos 36*cb63e24eSchristosThis manual describes version 2 of the SFrame file format. SFrame stands for 37*cb63e24eSchristosSimple Frame format. SFrame format keeps track of the minimal necessary 38*cb63e24eSchristosinformation needed for generating stack traces: 39*cb63e24eSchristos 40*cb63e24eSchristos@itemize @minus 41*cb63e24eSchristos@item 42*cb63e24eSchristosCanonical Frame Address (CFA). 43*cb63e24eSchristos@item 44*cb63e24eSchristosFrame Pointer (FP). 45*cb63e24eSchristos@item 46*cb63e24eSchristosReturn Address (RA). 47*cb63e24eSchristos@end itemize 48*cb63e24eSchristos 49*cb63e24eSchristosThe reason for existence of the SFrame format is to provide a simple, fast and 50*cb63e24eSchristoslow-overhead mechanism to generate stack traces. 51*cb63e24eSchristos 52*cb63e24eSchristos@menu 53*cb63e24eSchristos* Introduction:: 54*cb63e24eSchristos* SFrame section:: 55*cb63e24eSchristos* Index:: 56*cb63e24eSchristos@end menu 57*cb63e24eSchristos 58*cb63e24eSchristos@end ifnottex 59*cb63e24eSchristos 60*cb63e24eSchristos@node Introduction 61*cb63e24eSchristos@chapter Introduction 62*cb63e24eSchristos@cindex Introduction 63*cb63e24eSchristos 64*cb63e24eSchristos@menu 65*cb63e24eSchristos* Overview:: 66*cb63e24eSchristos* Changes from Version 1 to Version 2:: 67*cb63e24eSchristos@end menu 68*cb63e24eSchristos 69*cb63e24eSchristos@node Overview 70*cb63e24eSchristos@section Overview 71*cb63e24eSchristos@cindex Overview 72*cb63e24eSchristos 73*cb63e24eSchristosThe SFrame stack trace information is provided in a loaded section, known as the 74*cb63e24eSchristos@code{.sframe} section. When available, the @code{.sframe} section appears in 75*cb63e24eSchristosa new segment of its own, PT_GNU_SFRAME. 76*cb63e24eSchristos 77*cb63e24eSchristosThe SFrame format is currently supported only for select ABIs, namely, AMD64 78*cb63e24eSchristosand AAPCS64. 79*cb63e24eSchristos 80*cb63e24eSchristosA portion of the SFrame format follows an unaligned on-disk representation. 81*cb63e24eSchristosSome data structures, however, (namely the SFrame header and the SFrame 82*cb63e24eSchristosfunction descriptor entry) have elements at their natural boundaries. All data 83*cb63e24eSchristosstructures are packed, unless otherwise stated. 84*cb63e24eSchristos 85*cb63e24eSchristosThe contents of the SFrame section are stored in the target endianness, i.e., 86*cb63e24eSchristosin the endianness of the system on which the section is targetted to be used. 87*cb63e24eSchristosAn SFrame section reader may use the magic number in the SFrame header to 88*cb63e24eSchristosidentify the endianness of the SFrame section. 89*cb63e24eSchristos 90*cb63e24eSchristosAddresses in this specification are expressed in bytes. 91*cb63e24eSchristos 92*cb63e24eSchristosThe rest of this specification describes the current version of the format, 93*cb63e24eSchristos@code{SFRAME_VERSION_2}, in detail. Additional sections outline the major 94*cb63e24eSchristoschanges made to each previously published version of the SFrame stack trace 95*cb63e24eSchristosformat. 96*cb63e24eSchristos 97*cb63e24eSchristosThe associated API to decode, probe and encode the SFrame section, provided via 98*cb63e24eSchristos@code{libsframe}, is not accompanied here at this time. This will be added 99*cb63e24eSchristoslater. 100*cb63e24eSchristos 101*cb63e24eSchristosThis document is intended to be in sync with the C code in @file{sframe.h}. 102*cb63e24eSchristosPlease report discrepancies between the two, if any. 103*cb63e24eSchristos 104*cb63e24eSchristos@node Changes from Version 1 to Version 2 105*cb63e24eSchristos@section Changes from Version 1 to Version 2 106*cb63e24eSchristos@cindex Changes from Version 1 to Version 2 107*cb63e24eSchristos 108*cb63e24eSchristosThe following is a list of the changes made to the SFrame stack trace format 109*cb63e24eSchristossince Version 1 was published. 110*cb63e24eSchristos 111*cb63e24eSchristos@itemize @bullet 112*cb63e24eSchristos@item 113*cb63e24eSchristosSFrame Function Descriptor Entry encodes the size of the repetitive code 114*cb63e24eSchristosblocks, e.g., pltN entries for which an FDE of type SFRAME_FDE_TYPE_PCMASK is 115*cb63e24eSchristosused. 116*cb63e24eSchristos@item 117*cb63e24eSchristosSFrame Function Descriptor Entry includes an explicit padding of two bytes to 118*cb63e24eSchristosensure natural alignment for its data members. 119*cb63e24eSchristos@item 120*cb63e24eSchristosThe above two imply that each SFrame Function Descriptor Entry has a fixed size 121*cb63e24eSchristosof 20 bytes instead of its size of 17 bytes in SFrame format version 1. 122*cb63e24eSchristos@end itemize 123*cb63e24eSchristos 124*cb63e24eSchristos@node SFrame section 125*cb63e24eSchristos@chapter SFrame section 126*cb63e24eSchristos@cindex SFrame section 127*cb63e24eSchristos 128*cb63e24eSchristosThe SFrame section consists of an SFrame header, starting with a preamble, and 129*cb63e24eSchristostwo other sub-sections, namely the SFrame Function Descriptor Entry (SFrame 130*cb63e24eSchristosFDE) sub-section, and the SFrame Frame Row Entry (SFrame FRE) sub-section. 131*cb63e24eSchristos 132*cb63e24eSchristos@menu 133*cb63e24eSchristos* SFrame Preamble:: 134*cb63e24eSchristos* SFrame Header:: 135*cb63e24eSchristos* SFrame Function Descriptor Entries:: 136*cb63e24eSchristos* SFrame Frame Row Entries:: 137*cb63e24eSchristos@end menu 138*cb63e24eSchristos 139*cb63e24eSchristos@node SFrame Preamble 140*cb63e24eSchristos@section SFrame Preamble 141*cb63e24eSchristos@cindex SFrame preamble 142*cb63e24eSchristos 143*cb63e24eSchristosThe preamble is a 32-bit packed structure; the only part of the SFrame whose 144*cb63e24eSchristosformat cannot vary between versions. 145*cb63e24eSchristos 146*cb63e24eSchristos@example 147*cb63e24eSchristostypedef struct sframe_preamble 148*cb63e24eSchristos@{ 149*cb63e24eSchristos uint16_t sfp_magic; 150*cb63e24eSchristos uint8_t sfp_version; 151*cb63e24eSchristos uint8_t sfp_flags; 152*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_preamble; 153*cb63e24eSchristos@end example 154*cb63e24eSchristos 155*cb63e24eSchristosEvery element of the SFrame preamble is naturally aligned. 156*cb63e24eSchristos 157*cb63e24eSchristosAll values are stored in the endianness of the target system for which the 158*cb63e24eSchristosSFrame section is intended. Further details: 159*cb63e24eSchristos 160*cb63e24eSchristos@multitable {Offset} {@code{uint8_t sfp_version}} {The magic number for SFrame section: 0xdee2. Defined} 161*cb63e24eSchristos@headitem Offset @tab Name @tab Description 162*cb63e24eSchristos@item 0x00 163*cb63e24eSchristos@tab @code{uint16_t sfp_magic} 164*cb63e24eSchristos@tab The magic number for SFrame section: 0xdee2. Defined as a macro @code{SFRAME_MAGIC}. 165*cb63e24eSchristos@tindex SFRAME_MAGIC 166*cb63e24eSchristos 167*cb63e24eSchristos@item 0x02 168*cb63e24eSchristos@tab @code{uint8_t sfp_version} 169*cb63e24eSchristos@tab The version number of this SFrame section. @xref{SFrame version}, for the 170*cb63e24eSchristosset of valid values. Current version is 171*cb63e24eSchristos@code{SFRAME_VERSION_1}. 172*cb63e24eSchristos 173*cb63e24eSchristos@item 0x03 174*cb63e24eSchristos@tab @code{uint8_t sfp_flags} 175*cb63e24eSchristos@tab Flags (section-wide) for this SFrame section. @xref{SFrame flags}, for the 176*cb63e24eSchristosset of valid values. 177*cb63e24eSchristos@end multitable 178*cb63e24eSchristos 179*cb63e24eSchristos@menu 180*cb63e24eSchristos* SFrame endianness:: 181*cb63e24eSchristos* SFrame version:: 182*cb63e24eSchristos* SFrame flags:: 183*cb63e24eSchristos@end menu 184*cb63e24eSchristos 185*cb63e24eSchristos@node SFrame endianness 186*cb63e24eSchristos@subsection SFrame endianness 187*cb63e24eSchristos 188*cb63e24eSchristos@cindex endianness 189*cb63e24eSchristosSFrame sections are stored in the target endianness of the system that consumes 190*cb63e24eSchristosthem. The SFrame library (@code{libsframe}) can, however, detect whether to 191*cb63e24eSchristosendian-flip an SFrame section at decode time, by inspecting the 192*cb63e24eSchristos@code{sfp_magic} field in the SFrame header (If it appears as 0xe2de, 193*cb63e24eSchristosendian-flipping is needed). 194*cb63e24eSchristos 195*cb63e24eSchristos@node SFrame version 196*cb63e24eSchristos@subsection SFrame version 197*cb63e24eSchristos 198*cb63e24eSchristosThe version of the SFrame format can be determined by inspecting 199*cb63e24eSchristos@code{sfp_version}. The following versions are currently valid: 200*cb63e24eSchristos 201*cb63e24eSchristos@tindex SFRAME_VERSION_1 202*cb63e24eSchristos@cindex SFrame versions 203*cb63e24eSchristos@multitable {SFRAME_VERSION_2} {Number} {Current version, under development.} 204*cb63e24eSchristos@headitem Version @tab Number @tab Description 205*cb63e24eSchristos@item @code{SFRAME_VERSION_1} 206*cb63e24eSchristos@tab 1 @tab First version, obsolete. 207*cb63e24eSchristos@item @code{SFRAME_VERSION_2} 208*cb63e24eSchristos@tab 2 @tab Current version, under development. 209*cb63e24eSchristos@end multitable 210*cb63e24eSchristos 211*cb63e24eSchristosThis document describes @code{SFRAME_VERSION_2}. 212*cb63e24eSchristos 213*cb63e24eSchristos@node SFrame flags 214*cb63e24eSchristos@subsection SFrame flags 215*cb63e24eSchristos@cindex SFrame flags 216*cb63e24eSchristos@comment @vindex sfp_flags 217*cb63e24eSchristos@comment @vindex SFrame section-wide flags 218*cb63e24eSchristos@comment @subsection SFrame section-wide flags 219*cb63e24eSchristos 220*cb63e24eSchristosThe preamble contains bitflags in its @code{sfp_flags} field that 221*cb63e24eSchristosdescribe various section-wide properties. 222*cb63e24eSchristos 223*cb63e24eSchristosThe following flags are currently defined. 224*cb63e24eSchristos 225*cb63e24eSchristos@multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries} 226*cb63e24eSchristos@headitem Flag @tab Versions @tab Value @tab Meaning 227*cb63e24eSchristos@tindex SFRAME_F_FDE_SORTED 228*cb63e24eSchristos@item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor 229*cb63e24eSchristosEntries are sorted on PC. 230*cb63e24eSchristos@tindex SFRAME_F_FRAME_POINTER 231*cb63e24eSchristos@item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2 232*cb63e24eSchristos@tab Functions preserve frame-pointer. 233*cb63e24eSchristos@end multitable 234*cb63e24eSchristos 235*cb63e24eSchristosFurther flags may be added in future. 236*cb63e24eSchristos 237*cb63e24eSchristos@node SFrame Header 238*cb63e24eSchristos@section SFrame Header 239*cb63e24eSchristos@cindex SFrame header 240*cb63e24eSchristos 241*cb63e24eSchristosThe SFrame header is the first part of an SFrame section. It begins with the 242*cb63e24eSchristosSFrame preamble. All parts of it other than the preamble 243*cb63e24eSchristos(@pxref{SFrame Preamble}) can vary between SFrame file versions. It contains 244*cb63e24eSchristosthings that apply to the section as a whole, and offsets to the various other 245*cb63e24eSchristossub-sections defined in the format. As with the rest of the SFrame section, 246*cb63e24eSchristosall values are stored in the endianness of the target system. 247*cb63e24eSchristos 248*cb63e24eSchristosThe two sub-sections tile the SFrame section: each section runs from the offset 249*cb63e24eSchristosgiven until the start of the next section. An explicit length is given for the 250*cb63e24eSchristoslast sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section. 251*cb63e24eSchristos 252*cb63e24eSchristos@example 253*cb63e24eSchristostypedef struct sframe_header 254*cb63e24eSchristos@{ 255*cb63e24eSchristos sframe_preamble sfh_preamble; 256*cb63e24eSchristos uint8_t sfh_abi_arch; 257*cb63e24eSchristos int8_t sfh_cfa_fixed_fp_offset; 258*cb63e24eSchristos int8_t sfh_cfa_fixed_ra_offset; 259*cb63e24eSchristos uint8_t sfh_auxhdr_len; 260*cb63e24eSchristos uint32_t sfh_num_fdes; 261*cb63e24eSchristos uint32_t sfh_num_fres; 262*cb63e24eSchristos uint32_t sfh_fre_len; 263*cb63e24eSchristos uint32_t sfh_fdeoff; 264*cb63e24eSchristos uint32_t sfh_freoff; 265*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_header; 266*cb63e24eSchristos@end example 267*cb63e24eSchristos 268*cb63e24eSchristosEvery element of the SFrame header is naturally aligned. 269*cb63e24eSchristos 270*cb63e24eSchristosThe sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the 271*cb63e24eSchristosSFrame header are relative to the @emph{end} of the SFrame header; they are 272*cb63e24eSchristoseach an offset in bytes into the SFrame section where the SFrame FDE 273*cb63e24eSchristossub-section and the SFrame FRE sub-section respectively start. 274*cb63e24eSchristos 275*cb63e24eSchristosSFrame header allows specifying explicitly the fixed offsets from CFA, if any, 276*cb63e24eSchristosfrom which FP or RA may be recovered. For example, in AMD64, the stack offset 277*cb63e24eSchristosof the return address is @code{CFA - 8}. Since this offset is in close 278*cb63e24eSchristosvicinity with the CFA in most ABIs, @code{sfh_cfa_fixed_fp_offset} and 279*cb63e24eSchristos@code{sfh_cfa_fixed_ra_offset} are limited to signed 8-bit integers. 280*cb63e24eSchristos 281*cb63e24eSchristosSFrame format has made some provisions for supporting more ABIs/architectures 282*cb63e24eSchristosin the future. The @code{sframe_header} structure provides an unsigned 8-bit 283*cb63e24eSchristosintegral field to denote the size of an auxiliary SFrame header. The 284*cb63e24eSchristosauxiliary SFrame header follows right after the @code{sframe_header} 285*cb63e24eSchristosstructure. As for the offset calculations, the @emph{end} of SFrame header 286*cb63e24eSchristosmust be the end of the auxiliary SFrame header, if the latter is present. 287*cb63e24eSchristos 288*cb63e24eSchristosPutting it all together: 289*cb63e24eSchristos 290*cb63e24eSchristos@multitable {Offset} {@code{int8_t sfh_cfa_fixed_fp_offset}} {The number of SFrame FREs in the section.} 291*cb63e24eSchristos@headitem Offset @tab Name @tab Description 292*cb63e24eSchristos@item 0x00 293*cb63e24eSchristos@tab @code{sframe_preamble sfh_preamble} 294*cb63e24eSchristos@tab The SFrame preamble. @xref{SFrame Preamble}. 295*cb63e24eSchristos 296*cb63e24eSchristos@item 0x04 297*cb63e24eSchristos@tab @code{uint8_t sfh_abi_arch} 298*cb63e24eSchristos@tab The ABI/arch identifier. @xref{SFrame ABI/arch identifier}. 299*cb63e24eSchristos 300*cb63e24eSchristos@item 0x05 301*cb63e24eSchristos@tab @code{int8_t sfh_cfa_fixed_fp_offset} 302*cb63e24eSchristos@tab The CFA fixed FP offset, if any. 303*cb63e24eSchristos 304*cb63e24eSchristos@item 0x06 305*cb63e24eSchristos@tab @code{int8_t sfh_cfa_fixed_ra_offset} 306*cb63e24eSchristos@tab The CFA fixed RA offset, if any. 307*cb63e24eSchristos 308*cb63e24eSchristos@item 0x07 309*cb63e24eSchristos@tab @code{uint8_t sfh_auxhdr_len} 310*cb63e24eSchristos@tab Size in bytes of the auxiliary header that follows the 311*cb63e24eSchristos@code{sframe_header} structure. 312*cb63e24eSchristos 313*cb63e24eSchristos@item 0x08 314*cb63e24eSchristos@tab @code{uint32_t sfh_num_fdes} 315*cb63e24eSchristos@tab The number of SFrame FDEs in the section. 316*cb63e24eSchristos 317*cb63e24eSchristos@item 0xc 318*cb63e24eSchristos@tab @code{uint32_t sfh_num_fres} 319*cb63e24eSchristos@tab The number of SFrame FREs in the section. 320*cb63e24eSchristos 321*cb63e24eSchristos@item 0x10 322*cb63e24eSchristos@tab @code{uint32_t sfh_fre_len} 323*cb63e24eSchristos@tab The length in bytes of the SFrame FRE sub-section. 324*cb63e24eSchristos 325*cb63e24eSchristos@item 0x14 326*cb63e24eSchristos@tab @code{uint32_t sfh_fdeoff} 327*cb63e24eSchristos@tab The offset in bytes of the SFrame FDE sub-section. This sub-section 328*cb63e24eSchristoscontains @code{sfh_num_fdes} number of fixed-length array elements. The array 329*cb63e24eSchristoselement is of type SFrame function desciptor entry, each providing a 330*cb63e24eSchristoshigh-level function description for backtracing. 331*cb63e24eSchristos@xref{SFrame Function Descriptor Entries}. 332*cb63e24eSchristos 333*cb63e24eSchristos@item 0x18 334*cb63e24eSchristos@tab @code{uint32_t sfh_freoff} 335*cb63e24eSchristos@tab The offset in bytes of the SFrame FRE sub-section, the core of the SFrame 336*cb63e24eSchristossection, which describes the stack trace information using variable-length array 337*cb63e24eSchristoselements. @xref{SFrame Frame Row Entries}. 338*cb63e24eSchristos 339*cb63e24eSchristos@end multitable 340*cb63e24eSchristos 341*cb63e24eSchristos@menu 342*cb63e24eSchristos* SFrame ABI/arch identifier:: 343*cb63e24eSchristos@end menu 344*cb63e24eSchristos 345*cb63e24eSchristos@node SFrame ABI/arch identifier 346*cb63e24eSchristos@subsection SFrame ABI/arch identifier 347*cb63e24eSchristos@cindex SFrame ABI/arch identifier 348*cb63e24eSchristos 349*cb63e24eSchristosSFrame header identifies the ABI/arch of the target system for which the 350*cb63e24eSchristosexecutable and hence, the stack trace information contained in the SFrame 351*cb63e24eSchristossection, is intended. There are currently three identifiable ABI/arch values 352*cb63e24eSchristosin the format. 353*cb63e24eSchristos 354*cb63e24eSchristos@multitable {SFRAME_ABI_AARCH64_ENDIAN_LITTLE} {Value} {@code{AARCH64 little-endian}} 355*cb63e24eSchristos@headitem ABI/arch Identifier @tab Value @tab Description 356*cb63e24eSchristos 357*cb63e24eSchristos@tindex SFRAME_ABI_AARCH64_ENDIAN_BIG 358*cb63e24eSchristos@item @code{SFRAME_ABI_AARCH64_ENDIAN_BIG} 359*cb63e24eSchristos@tab 1 @tab AARCH64 big-endian 360*cb63e24eSchristos 361*cb63e24eSchristos@tindex SFRAME_ABI_AARCH64_ENDIAN_LITTLE 362*cb63e24eSchristos@item @code{SFRAME_ABI_AARCH64_ENDIAN_LITTLE} 363*cb63e24eSchristos@tab 2 @tab AARCH64 little-endian 364*cb63e24eSchristos 365*cb63e24eSchristos@tindex SFRAME_ABI_AMD64_ENDIAN_LITTLE 366*cb63e24eSchristos@item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE} 367*cb63e24eSchristos@tab 3 @tab AMD64 little-endian 368*cb63e24eSchristos 369*cb63e24eSchristos@end multitable 370*cb63e24eSchristos 371*cb63e24eSchristosThe presence of an explicit identification of ABI/arch in SFrame may allow 372*cb63e24eSchristosstack trace generators to make certain ABI-specific decisions. 373*cb63e24eSchristos 374*cb63e24eSchristos@node SFrame Function Descriptor Entries 375*cb63e24eSchristos@section SFrame FDE 376*cb63e24eSchristos@cindex SFrame FDE 377*cb63e24eSchristos 378*cb63e24eSchristosThe SFrame Function Descriptor Entry sub-section is a sorted array of 379*cb63e24eSchristosfixed-length SFrame function descriptor entries (SFrame FDEs). Each SFrame FDE 380*cb63e24eSchristosis a packed structure which contains information to describe a function's stack 381*cb63e24eSchristostrace information at a high-level. 382*cb63e24eSchristos 383*cb63e24eSchristos@example 384*cb63e24eSchristostypedef struct sframe_func_desc_entry 385*cb63e24eSchristos@{ 386*cb63e24eSchristos int32_t sfde_func_start_address; 387*cb63e24eSchristos uint32_t sfde_func_size; 388*cb63e24eSchristos uint32_t sfde_func_start_fre_off; 389*cb63e24eSchristos uint32_t sfde_func_num_fres; 390*cb63e24eSchristos uint8_t sfde_func_info; 391*cb63e24eSchristos uint8_t sfde_func_rep_size; 392*cb63e24eSchristos uint16_t sfde_func_padding2; 393*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_func_desc_entry; 394*cb63e24eSchristos@end example 395*cb63e24eSchristos 396*cb63e24eSchristosEvery element of the SFrame function descriptor entry is naturally aligned. 397*cb63e24eSchristos 398*cb63e24eSchristos@code{sfde_func_start_fre_off} is the offset to the first SFrame FRE for the 399*cb63e24eSchristosfunction. This offset is relative to the @emph{end of the SFrame FDE} 400*cb63e24eSchristossub-section (unlike the offsets in the SFrame header, which are relative to the 401*cb63e24eSchristos@emph{end} of the SFrame header). 402*cb63e24eSchristos 403*cb63e24eSchristos@code{sfde_func_info} is the "info word", containing information on the FRE 404*cb63e24eSchristostype and the FDE type for the function @xref{The SFrame FDE info word}. 405*cb63e24eSchristos 406*cb63e24eSchristosFollowing table describes each component of the SFrame FDE structure: 407*cb63e24eSchristos 408*cb63e24eSchristos@multitable {Offset} {@code{uint32_t sfde_func_start_fre_off}} {Signed 32-bit integral field denoting the} 409*cb63e24eSchristos@headitem Offset @tab Name @tab Description 410*cb63e24eSchristos@item 0x00 411*cb63e24eSchristos@tab @code{int32_t sfde_func_start_address} 412*cb63e24eSchristos@tab Signed 32-bit integral field denoting the virtual memory address of the 413*cb63e24eSchristosdescribed function. 414*cb63e24eSchristos 415*cb63e24eSchristos@item 0x04 416*cb63e24eSchristos@tab @code{uint32_t sfde_func_size} 417*cb63e24eSchristos@tab Unsigned 32-bit integral field specifying the size of the function in 418*cb63e24eSchristosbytes. 419*cb63e24eSchristos 420*cb63e24eSchristos@item 0x08 421*cb63e24eSchristos@tab @code{uint32_t sfde_func_start_fre_off} 422*cb63e24eSchristos@tab Unsigned 32-bit integral field specifying the offset in bytes of the 423*cb63e24eSchristosfunction's first SFrame FRE in the SFrame section. 424*cb63e24eSchristos 425*cb63e24eSchristos@item 0x0c 426*cb63e24eSchristos@tab @code{uint32_t sfde_func_num_fres} 427*cb63e24eSchristos@tab Unsigned 32-bit integral field specifying the total number of SFrame FREs 428*cb63e24eSchristosused for the function. 429*cb63e24eSchristos 430*cb63e24eSchristos@item 0x10 431*cb63e24eSchristos@tab @code{uint8_t sfde_func_info} 432*cb63e24eSchristos@tab Unsigned 8-bit integral field specifying the SFrame FDE info word. 433*cb63e24eSchristos@xref{The SFrame FDE info word}. 434*cb63e24eSchristos 435*cb63e24eSchristos@item 0x11 436*cb63e24eSchristos@tab @code{uint8_t sfde_func_rep_size} 437*cb63e24eSchristos@tab Unsigned 8-bit integral field specifying the size of the repetitive code 438*cb63e24eSchristosblock for which an SFrame FDE of type SFRAME_FDE_TYPE_PCMASK is used. For 439*cb63e24eSchristosexample, in AMD64, the size of a pltN entry is 16 bytes. 440*cb63e24eSchristos 441*cb63e24eSchristos@item 0x12 442*cb63e24eSchristos@tab @code{uint16_t sfde_func_padding2} 443*cb63e24eSchristos@tab Padding of 2 bytes. Currently unused bytes. 444*cb63e24eSchristos 445*cb63e24eSchristos@end multitable 446*cb63e24eSchristos 447*cb63e24eSchristos@menu 448*cb63e24eSchristos* The SFrame FDE info word:: 449*cb63e24eSchristos* The SFrame FDE types:: 450*cb63e24eSchristos* The SFrame FRE types:: 451*cb63e24eSchristos@end menu 452*cb63e24eSchristos 453*cb63e24eSchristos@cindex The SFrame FDE info word 454*cb63e24eSchristos@node The SFrame FDE info word 455*cb63e24eSchristos@subsection The SFrame FDE info word 456*cb63e24eSchristos 457*cb63e24eSchristosThe info word is a bitfield split into three parts. From MSB to LSB: 458*cb63e24eSchristos 459*cb63e24eSchristos@multitable {Bit offset} {@code{pauth_key}} {Specify which key is used for signing the return addresses} 460*cb63e24eSchristos@headitem Bit offset @tab Name @tab Description 461*cb63e24eSchristos@item 7--6 462*cb63e24eSchristos@tab @code{unused} 463*cb63e24eSchristos@tab Unused bits. 464*cb63e24eSchristos 465*cb63e24eSchristos@item 5 466*cb63e24eSchristos@tab @code{pauth_key} 467*cb63e24eSchristos@tab Specify which key is used for signing the return addresses in the SFrame 468*cb63e24eSchristosFDE. Two possible values: @* 469*cb63e24eSchristosSFRAME_AARCH64_PAUTH_KEY_A (0), or @* 470*cb63e24eSchristosSFRAME_AARCH64_PAUTH_KEY_B (1). 471*cb63e24eSchristos 472*cb63e24eSchristos@item 4 473*cb63e24eSchristos@tab @code{fdetype} 474*cb63e24eSchristos@tab Specify the SFrame FDE type. Two possible values: @* 475*cb63e24eSchristosSFRAME_FDE_TYPE_PCMASK (1), or @* 476*cb63e24eSchristosSFRAME_FDE_TYPE_PCINC (0). @* 477*cb63e24eSchristos@xref{The SFrame FDE types}. 478*cb63e24eSchristos 479*cb63e24eSchristos@item 0--3 480*cb63e24eSchristos@tab @code{fretype} 481*cb63e24eSchristos@tab Choice of three SFrame FRE types. @xref{The SFrame FRE types}. 482*cb63e24eSchristos@end multitable 483*cb63e24eSchristos 484*cb63e24eSchristos@node The SFrame FDE types 485*cb63e24eSchristos@subsection The SFrame FDE types 486*cb63e24eSchristos@tindex SFRAME_FDE_TYPE_PCMASK 487*cb63e24eSchristos@tindex SFRAME_FDE_TYPE_PCINC 488*cb63e24eSchristos 489*cb63e24eSchristosSFrame format defines two types of FDE entries. The choice of which SFrame FDE 490*cb63e24eSchristostype to use is made based on the instruction patterns in the relevant program 491*cb63e24eSchristosstub. 492*cb63e24eSchristos 493*cb63e24eSchristosAn SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the 494*cb63e24eSchristosFREs should be treated as increments in bytes. This is used fo the the bulk of 495*cb63e24eSchristosthe executable code of a program, which contains instructions with no specific 496*cb63e24eSchristospattern. 497*cb63e24eSchristos 498*cb63e24eSchristosIn contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an 499*cb63e24eSchristosindication that the PCs in the FREs should be treated as masks. This type is 500*cb63e24eSchristosuseful for the cases where a small pattern of instructions in a program stub is 501*cb63e24eSchristosused repeatedly for a specific functionality. Typical usecases are pltN 502*cb63e24eSchristosentries and trampolines. 503*cb63e24eSchristos 504*cb63e24eSchristos@multitable {SFRAME_FDE_TYPE_PCMASK} {Value} {Unwinders perform a Unwinders perform a} 505*cb63e24eSchristos@headitem Name of SFrame FDE type @tab Value @tab Description 506*cb63e24eSchristos 507*cb63e24eSchristos@item SFRAME_FDE_TYPE_PCINC 508*cb63e24eSchristos@tab 0 @tab Unwinders perform a @* 509*cb63e24eSchristos(PC >= FRE_START_ADDR) to look up a matching FRE. 510*cb63e24eSchristos 511*cb63e24eSchristos@item SFRAME_FDE_TYPE_PCMASK 512*cb63e24eSchristos@tab 1 @tab Unwinders perform a @* 513*cb63e24eSchristos(PC % REP_BLOCK_SIZE @* 514*cb63e24eSchristos >= FRE_START_ADDR) 515*cb63e24eSchristosto look up a matching FRE. REP_BLOCK_SIZE is the size in bytes of the 516*cb63e24eSchristosrepeating block of program instructions. 517*cb63e24eSchristos 518*cb63e24eSchristos@end multitable 519*cb63e24eSchristos 520*cb63e24eSchristos@node The SFrame FRE types 521*cb63e24eSchristos@subsection The SFrame FRE types 522*cb63e24eSchristos 523*cb63e24eSchristosA real world application can have functions of size big and small. SFrame 524*cb63e24eSchristosformat defines three types of SFrame FRE entries to represent the stack trace 525*cb63e24eSchristosinformation for such a variety of function sizes. These representations vary 526*cb63e24eSchristosin the number of bits needed to encode the start address offset in the SFrame 527*cb63e24eSchristosFRE. 528*cb63e24eSchristos 529*cb63e24eSchristosThe following constants are defined and used to identify the SFrame FRE types: 530*cb63e24eSchristos 531*cb63e24eSchristos@multitable {SFRAME_FRE_TYPE_ADDR1} {@code{Value}} {The start address offset of FRE is an} 532*cb63e24eSchristos@headitem Name @tab Value @tab Description 533*cb63e24eSchristos 534*cb63e24eSchristos@tindex SFRAME_FRE_TYPE_ADDR1 535*cb63e24eSchristos@item @code{SFRAME_FRE_TYPE_ADDR1} 536*cb63e24eSchristos@tab 0 537*cb63e24eSchristos@tab The start address offset (in bytes) of the SFrame FRE is an unsigned 538*cb63e24eSchristos8-bit value. 539*cb63e24eSchristos 540*cb63e24eSchristos@tindex SFRAME_FRE_TYPE_ADDR2 541*cb63e24eSchristos@item @code{SFRAME_FRE_TYPE_ADDR2} 542*cb63e24eSchristos@tab 1 543*cb63e24eSchristos@tab The start address offset (in bytes) of the SFrame FRE is an unsigned 544*cb63e24eSchristos16-bit value. 545*cb63e24eSchristos 546*cb63e24eSchristos@tindex SFRAME_FRE_TYPE_ADDR4 547*cb63e24eSchristos@item @code{SFRAME_FRE_TYPE_ADDR4} 548*cb63e24eSchristos@tab 2 549*cb63e24eSchristos@tab The start address offset (in bytes) of the SFrame FRE is an unsigned 550*cb63e24eSchristos32-bit value. 551*cb63e24eSchristos@end multitable 552*cb63e24eSchristos 553*cb63e24eSchristosA single function must use the same type of SFrame FRE throughout. An 554*cb63e24eSchristosidentifier to reflect the chosen SFrame FRE type is stored in the 555*cb63e24eSchristos@xref{The SFrame FDE info word}. 556*cb63e24eSchristos 557*cb63e24eSchristos@node SFrame Frame Row Entries 558*cb63e24eSchristos@section SFrame FRE 559*cb63e24eSchristos@cindex SFrame FRE 560*cb63e24eSchristos 561*cb63e24eSchristosThe SFrame Frame Row Entry sub-section contains the core of the stack trace 562*cb63e24eSchristosinformation. 563*cb63e24eSchristos 564*cb63e24eSchristosAn SFrame Frame Row Entry is a self-sufficient record containing SFrame stack 565*cb63e24eSchristostrace information for a range of contiguous addresses, starting at the 566*cb63e24eSchristosspecified offset from the start of the function. Each SFrame Frame Row Entry 567*cb63e24eSchristosis followed by S*N bytes, where: 568*cb63e24eSchristos 569*cb63e24eSchristos@itemize @minus 570*cb63e24eSchristos@item 571*cb63e24eSchristos@code{S} is the size of the stack frame offset for the FRE, and 572*cb63e24eSchristos@item 573*cb63e24eSchristos@code{N} is the number of stack frame offsets in the FRE 574*cb63e24eSchristos@end itemize 575*cb63e24eSchristos 576*cb63e24eSchristosThe stack offsets, following the FRE, are interpreted in order as follows: 577*cb63e24eSchristos 578*cb63e24eSchristos@itemize @minus 579*cb63e24eSchristos@item 580*cb63e24eSchristosThe first offset is always used to locate the CFA, by interpreting it as: 581*cb63e24eSchristosCFA = @code{BASE_REG} + offset1. 582*cb63e24eSchristos@item 583*cb63e24eSchristosIf RA is being tracked, the second offset is always used to locate the RA, by 584*cb63e24eSchristosinterpreting it as: RA = CFA + offset2. If RA is @emph{not} being tracked 585*cb63e24eSchristos@emph{and} FP is being tracked, the second offset will be used to locate the 586*cb63e24eSchristosFP, by interpreting it as: FP = CFA + offset2. 587*cb63e24eSchristos@item 588*cb63e24eSchristosIf both RA and FP are being tracked, the third offset will be used to locate 589*cb63e24eSchristosthe FP, by interpreting it as FP = CFA + offset3. 590*cb63e24eSchristos@end itemize 591*cb63e24eSchristos 592*cb63e24eSchristosThe entities @code{S}, @code{N} and @code{BASE_REG} are identified using the 593*cb63e24eSchristosSFrame FRE info word, a.k.a. the @code{sframe_fre_info} 594*cb63e24eSchristos@xref{The SFrame FRE info word}. 595*cb63e24eSchristos 596*cb63e24eSchristosFollowing are the definitions of the allowed SFrame FRE: 597*cb63e24eSchristos 598*cb63e24eSchristos@example 599*cb63e24eSchristostypedef struct sframe_frame_row_entry_addr1 600*cb63e24eSchristos@{ 601*cb63e24eSchristos uint8_t sfre_start_address; 602*cb63e24eSchristos sframe_fre_info sfre_info; 603*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr1; 604*cb63e24eSchristos@end example 605*cb63e24eSchristos 606*cb63e24eSchristos@example 607*cb63e24eSchristostypedef struct sframe_frame_row_entry_addr2 608*cb63e24eSchristos@{ 609*cb63e24eSchristos uint16_t sfre_start_address; 610*cb63e24eSchristos sframe_fre_info sfre_info; 611*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr2; 612*cb63e24eSchristos@end example 613*cb63e24eSchristos 614*cb63e24eSchristos@example 615*cb63e24eSchristostypedef struct sframe_frame_row_entry_addr4 616*cb63e24eSchristos@{ 617*cb63e24eSchristos uint32_t sfre_start_address; 618*cb63e24eSchristos sframe_fre_info sfre_info; 619*cb63e24eSchristos@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr4; 620*cb63e24eSchristos@end example 621*cb63e24eSchristos 622*cb63e24eSchristosFor ensuring compactness, SFrame frame row entries are stored unaligned on 623*cb63e24eSchristosdisk. Appropriate mechanisms need to be employed, as necessary, by the 624*cb63e24eSchristosserializing and deserializing entities, if unaligned accesses need to be 625*cb63e24eSchristosavoided. 626*cb63e24eSchristos 627*cb63e24eSchristos@code{sfre_start_address} is an unsigned 8-bit/16-bit/32-bit integral field 628*cb63e24eSchristosidentifies the start address of the range of program counters, for which the 629*cb63e24eSchristosSFrame FRE applies. The value encoded in the @code{sfre_start_address} field 630*cb63e24eSchristosis the offset in bytes of the start address of the SFrame FRE, from the start 631*cb63e24eSchristosaddress of the function. 632*cb63e24eSchristos 633*cb63e24eSchristosFurther FRE types may be added in future. 634*cb63e24eSchristos 635*cb63e24eSchristos@menu 636*cb63e24eSchristos* The SFrame FRE info word:: 637*cb63e24eSchristos@end menu 638*cb63e24eSchristos 639*cb63e24eSchristos@cindex The SFrame FRE info word 640*cb63e24eSchristos@node The SFrame FRE info word 641*cb63e24eSchristos@subsection The SFrame FRE info word 642*cb63e24eSchristos 643*cb63e24eSchristosThe SFrame FRE info word is a bitfield split into four parts. From MSB to LSB: 644*cb63e24eSchristos 645*cb63e24eSchristos@multitable {Bit offset} {@code{fre_cfa_base_reg_id}} {Size of stack offsets in bytes. Valid values} 646*cb63e24eSchristos@headitem Bit offset @tab Name @tab Description 647*cb63e24eSchristos@item 7 648*cb63e24eSchristos@tab @code{fre_mangled_ra_p} 649*cb63e24eSchristos@tab Indicate whether the return address is mangled with any authorization bits (signed RA). 650*cb63e24eSchristos 651*cb63e24eSchristos@item 5-6 652*cb63e24eSchristos@tab @code{fre_offset_size} 653*cb63e24eSchristos@tab Size of stack offsets in bytes. Valid values are: @* 654*cb63e24eSchristosSFRAME_FRE_OFFSET_1B, @* 655*cb63e24eSchristosSFRAME_FRE_OFFSET_2B, and @* 656*cb63e24eSchristosSFRAME_FRE_OFFSET_4B. 657*cb63e24eSchristos 658*cb63e24eSchristos@item 1-4 659*cb63e24eSchristos@tab @code{fre_offset_count} 660*cb63e24eSchristos@tab A value of upto 3 is allowed to track all three of CFA, FP and RA. 661*cb63e24eSchristos 662*cb63e24eSchristos@item 0 663*cb63e24eSchristos@tab @code{fre_cfa_base_reg_id} 664*cb63e24eSchristos@tab Distinguish between SP or FP based CFA recovery. 665*cb63e24eSchristos 666*cb63e24eSchristos@end multitable 667*cb63e24eSchristos 668*cb63e24eSchristos@multitable {SFRAME_FRE_OFFSET_4B} {@code{Value}} {All stack offsets following the fixed-length} 669*cb63e24eSchristos@headitem Name @tab Value @tab Description 670*cb63e24eSchristos 671*cb63e24eSchristos@tindex SFRAME_FRE_OFFSET_1B 672*cb63e24eSchristos@item @code{SFRAME_FRE_OFFSET_1B} 673*cb63e24eSchristos@tab 0 674*cb63e24eSchristos@tab All stack offsets following the fixed-length FRE structure are 1 byte 675*cb63e24eSchristoslong. 676*cb63e24eSchristos 677*cb63e24eSchristos@tindex SFRAME_FRE_OFFSET_2B 678*cb63e24eSchristos@item @code{SFRAME_FRE_OFFSET_2B} 679*cb63e24eSchristos@tab 1 680*cb63e24eSchristos@tab All stack offsets following the fixed-length FRE structure are 2 bytes 681*cb63e24eSchristoslong. 682*cb63e24eSchristos 683*cb63e24eSchristos@tindex SFRAME_FRE_OFFSET_4B 684*cb63e24eSchristos@item @code{SFRAME_FRE_OFFSET_4B} 685*cb63e24eSchristos@tab 2 686*cb63e24eSchristos@tab All stack offsets following the fixed-length FRE structure are 4 bytes 687*cb63e24eSchristoslong. 688*cb63e24eSchristos 689*cb63e24eSchristos@end multitable 690*cb63e24eSchristos 691*cb63e24eSchristos@node Index 692*cb63e24eSchristos@unnumbered Index 693*cb63e24eSchristos 694*cb63e24eSchristos@syncodeindex tp cp 695*cb63e24eSchristos@printindex cp 696*cb63e24eSchristos 697*cb63e24eSchristos@bye 698