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