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