diff options
author | Indu Bhagat <indu.bhagat@oracle.com> | 2022-11-15 15:07:28 -0800 |
---|---|---|
committer | Indu Bhagat <indu.bhagat@oracle.com> | 2022-11-15 15:50:05 -0800 |
commit | c1c57352f56b802393453cfa76326922fd8da2f9 (patch) | |
tree | 7d1e3b9b4544487b89c60b8b29445162a0455be1 /libsframe/doc | |
parent | b2cb03d5c3bb0a61d07d00c497a4256f83a894fd (diff) | |
download | binutils-c1c57352f56b802393453cfa76326922fd8da2f9.zip binutils-c1c57352f56b802393453cfa76326922fd8da2f9.tar.gz binutils-c1c57352f56b802393453cfa76326922fd8da2f9.tar.bz2 |
doc: add SFrame spec file
ChangeLog:
* libsframe/Makefile.am: Add info-in-builddir to
AUTOMAKE_OPTIONS. Include doc/local.mk.
* libsframe/Makefile.in: Regenerated.
* libsframe/configure: Likewise.
* libsframe/configure.ac: Check for makeinfo and set BUILD_INFO.
* libsframe/doc/local.mk: New file.
* libsframe/doc/sframe-spec.texi: Likewise.
Diffstat (limited to 'libsframe/doc')
-rw-r--r-- | libsframe/doc/local.mk | 40 | ||||
-rw-r--r-- | libsframe/doc/sframe-spec.texi | 619 |
2 files changed, 659 insertions, 0 deletions
diff --git a/libsframe/doc/local.mk b/libsframe/doc/local.mk new file mode 100644 index 0000000..bdd1312 --- /dev/null +++ b/libsframe/doc/local.mk @@ -0,0 +1,40 @@ +## Process this file with automake to produce Makefile.in. +# +# Copyright (C) 2019-2022 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not see +# <http://www.gnu.org/licenses/>. +# + +if BUILD_INFO + +info_TEXINFOS += %D%/sframe-spec.texi + +AM_MAKEINFOFLAGS = --no-split + +DISTCLEANFILES += texput.log +MAINTAINERCLEANFILES += %D%/sframe-spec.info + +html-local: %D%/sframe-spec/index.html +%D%/sframe-spec/index.html: %D%/sframe-spec.texi %D%/$(am__dirstamp) + $(AM_V_GEN)$(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) \ + --split=node -I$(srcdir) --output %D%/sframe-spec $(srcdir)/%D%/sframe-spec.texi + +else + +# Workaround bug in automake: it can't handle conditionally building info pages +# since GNU projects normally include info pages in the source distributions. +%D%/sframe-spec.info: + +endif diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi new file mode 100644 index 0000000..41f4ba1 --- /dev/null +++ b/libsframe/doc/sframe-spec.texi @@ -0,0 +1,619 @@ +\input texinfo @c -*- Texinfo -*- +@setfilename sframe-spec.info +@settitle The SFrame Format +@ifnottex +@xrefautomaticsectiontitle on +@end ifnottex + +@copying +Copyright @copyright{} 2021-2022 Free Software Foundation, Inc. + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License, Version 3 or any +later version published by the Free Software Foundation. A copy of the +license is included in the section entitled ``GNU General Public +License''. + +@end copying + +@dircategory Software development +@direntry +* SFrame: (sframe-spec). The Simple Frame format. +@end direntry + +@titlepage +@title The SFrame Format +@subtitle Version 1 +@author Indu Bhagat + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage +@contents + +@ifnottex +@node Top +@top The SFrame format + +This manual describes version 1 of the SFrame file format. SFrame stands for +Simple Frame format. SFrame format keeps track of the minimal necessary +information needed for stack unwinding: + +@itemize @minus +@item +Canonical Frame Address (CFA). +@item +Frame Pointer (FP). +@item +Return Address (RA). +@end itemize + +The reason for existence of the SFrame format is to support fast, online +backtracing using a simple unwinder. + +@menu +* Overview:: +* SFrame section:: +* Index:: +@end menu + +@end ifnottex + +@node Overview +@unnumbered Overview +@cindex Overview +@tindex PT_GNU_SFRAME + +The SFrame unwind information is provided in a loaded section, known as the +@code{.sframe} section. When available, the @code{.sframe} section appears in +a new segment of its own, PT_GNU_SFRAME. + +The SFrame format is currently supported only for select ABIs, namely, AMD64 +and AAPCS64. + +The contents of the SFrame section are stored in the target endianness, i.e., +in the endianness of the system on which the section is targetted to be used. +An SFrame section reader may use the magic number in the SFrame header to +identify the endianness of the SFrame section. + +Addresses in this specification are expressed in bytes. + +The associated API to decode, probe and encode the SFrame section, provided via +@code{libsframe}, is not accompanied here at this time. This will be added +later. + +This document is intended to be in sync with the C code in @file{sframe.h}. +Please report descrepancies between the two, if any. + +@node SFrame section +@chapter SFrame section +@cindex SFrame section + +The SFrame section consists of an SFrame header, starting with a preamble, and +two other sub-sections, namely the SFrame Function Descriptor Entry (SFrame +FDE) sub-section, and the SFrame Frame Row Entry (SFrame FRE) sub-section. + +@menu +* SFrame Preamble:: +* SFrame Header:: +* SFrame Function Descriptor Entries:: +* SFrame Frame Row Entries:: +@end menu + +@node SFrame Preamble +@section SFrame Preamble +@cindex SFrame preamble + +The preamble is a 32-bit packed structure; the only part of the SFrame whose +format cannot vary between versions. + +@example +typedef struct sframe_preamble +@{ + uint16_t sfp_magic; + uint8_t sfp_version; + uint8_t sfp_flags; +@} ATTRIBUTE_PACKED sframe_preamble; +@end example + +All values are stored in the endianness of the target system for which the +SFrame section is intended. Further details: + +@multitable {Offset} {@code{uint8_t sfp_version}} {The magic number for SFrame section: 0xdee2. Defined} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{uint16_t sfp_magic} +@tab The magic number for SFrame section: 0xdee2. Defined as a macro @code{SFRAME_MAGIC}. +@tindex SFRAME_MAGIC + +@item 0x02 +@tab @code{uint8_t sfp_version} +@tab The version number of this SFrame section. @xref{SFrame version}, for the +set of valid values. Current version is +@code{SFRAME_VERSION_1}. + +@item 0x03 +@tab @code{uint8_t sfp_flags} +@tab Flags (section-wide) for this SFrame section. @xref{SFrame flags}, for the +set of valid values. +@end multitable + +@menu +* SFrame endianness:: +* SFrame version:: +* SFrame flags:: +@end menu + +@node SFrame endianness +@subsection SFrame endianness + +@cindex endianness +SFrame sections are stored in the target endianness of the system that consumes +them. The SFrame library (@code{libsframe}) can, however, detect whether to +endian-flip an SFrame section at decode time, by inspecting the +@code{sfp_magic} field in the SFrame header (If it appears as 0xe2de, +endian-flipping is needed). + +@node SFrame version +@subsection SFrame version + +The version of the SFrame format can be determined by inspecting +@code{sfp_version}. The following versions are currently valid: + +@tindex SFRAME_VERSION_1 +@cindex SFrame versions +@multitable {SFRAME_VERSION_1} {Number} {First version, under development.} +@headitem Version @tab Number @tab Description +@item @code{SFRAME_VERSION_1} +@tab 1 @tab First version, under development. +@end multitable + +This section documents @code{SFRAME_VERSION_1}. + +@node SFrame flags +@subsection SFrame flags +@cindex SFrame flags +@comment @vindex sfp_flags +@comment @vindex SFrame section-wide flags +@comment @subsection SFrame section-wide flags + +The preamble contains bitflags in its @code{sfp_flags} field that +describe various section-wide properties. + +The following flags are currently defined. + +@multitable {@code{SFRAME_F_FRAME_POINTER}} {Versions} {Value} {Function Descriptor Entries} +@headitem Flag @tab Versions @tab Value @tab Meaning +@tindex SFRAME_F_FDE_SORTED +@item @code{SFRAME_F_FDE_SORTED} @tab All @tab 0x1 @tab Function Descriptor +Entries are sorted on PC. +@tindex SFRAME_F_FRAME_POINTER +@item @code{SFRAME_F_FRAME_POINTER} @tab All @tab 0x2 +@tab Functions preserve frame-pointer. +@end multitable + +Further flags may be added in future. + +@node SFrame Header +@section SFrame Header +@cindex SFrame header + +The SFrame header is the first part of an SFrame section. It begins with the +SFrame preamble. All parts of it other than the preamble +(@pxref{SFrame Preamble}) can vary between SFrame file versions. It contains +things that apply to the section as a whole, and offsets to the various other +sub-sections defined in the format. As with the rest of the SFrame section, +all values are stored in the endianness of the target system. + +The two sub-sections tile the SFrame section: each section runs from the offset +given until the start of the next section. An explicit length is given for the +last sub-section, the SFrame Frame Row Entry (SFrame FRE) sub-section. + +@example +typedef struct sframe_header +@{ + sframe_preamble sfh_preamble; + uint8_t sfh_abi_arch; + int8_t sfh_cfa_fixed_fp_offset; + int8_t sfh_cfa_fixed_ra_offset; + uint8_t sfh_auxhdr_len; + uint32_t sfh_num_fdes; + uint32_t sfh_num_fres; + uint32_t sfh_fre_len; + uint32_t sfh_fdeoff; + uint32_t sfh_freoff; +@} ATTRIBUTE_PACKED sframe_header; +@end example + +The sub-section offsets, namely @code{sfh_fdeoff} and @code{sfh_freoff}, in the +SFrame header are relative to the @emph{end} of the SFrame header; they are +each an offset in bytes into the SFrame section where the SFrame FDE +sub-section and the SFrame FRE sub-section respectively start. + +SFrame header allows specifying explicitly the fixed offsets from CFA, if any, +from which FP or RA may be recovered. For example, in AMD64, the stack offset +of the return address is @code{CFA - 8}. Since this offset is in close +vicinity with the CFA in most ABIs, @code{sfh_cfa_fixed_fp_offset} and +@code{sfh_cfa_fixed_ra_offset} are limited to signed 8-bit integers. + +SFrame format has provisioned for future ABIs/architectures that it may +support. The @code{sframe_header} structure provides an unsigned 8-bit +integral field to denote the size of an auxilliary SFrame header. The +auxilliary SFrame header follows right after the @code{sframe_header} +structure. As for the offset calculations, the @emph{end} of SFrame header +must be the end of the auxilliary SFrame header, if the latter is present. + +Tieing it all together: + +@multitable {Offset} {@code{int8_t sfh_cfa_fixed_fp_offset}} {The ABI/arch identifier. See above} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{sframe_preamble sfh_preamble} +@tab The SFrame preamble. @xref{SFrame Preamble}. + +@item 0x04 +@tab @code{uint8_t sfh_abi_arch} +@tab The ABI/arch identifier. @xref{SFrame ABI/arch identifier}. + +@item 0x05 +@tab @code{int8_t sfh_cfa_fixed_fp_offset} +@tab The CFA fixed FP offset, if any. + +@item 0x06 +@tab @code{int8_t sfh_cfa_fixed_ra_offset} +@tab The CFA fixed RA offset, if any. + +@item 0x07 +@tab @code{uint8_t sfh_auxhdr_len} +@tab Size in bytes of the auxilliary header that follows the +@code{sframe_header} structure. + +@item 0x08 +@tab @code{uint32_t sfh_num_fdes} +@tab The number of SFrame FDEs in the section. + +@item 0xc +@tab @code{uint32_t sfh_num_fres} +@tab The number of SFrame FREs in the section. + +@item 0x10 +@tab @code{uint32_t sfh_fre_len} +@tab The length in bytes of the SFrame FRE sub-section. + +@item 0x14 +@tab @code{uint32_t sfh_fdeoff} +@tab The offset in bytes of the SFrame FDE sub-section. This sub-section +contains @code{sfh_num_fdes} number of fixed-length array elements. The array +element is of type SFrame function desciptor entry, each providing a +high-level function description for backtracing. +@xref{SFrame Function Descriptor Entries}. + +@item 0x18 +@tab @code{uint32_t sfh_freoff} +@tab The offset in bytes of the SFrame FRE sub-section, the core of the SFrame +section, which describes the unwind information using variable-length array +elements. @xref{SFrame Frame Row Entries}. + +@end multitable + +@menu +* SFrame ABI/arch identifier:: +@end menu + +@node SFrame ABI/arch identifier +@subsection SFrame ABI/arch identifier +@cindex SFrame ABI/arch identifier + +SFrame header identifies the ABI/arch of the target system for which the +executable and it's unwind information is intended. There are currently three +identifiable ABI/arch values in the format. + +@multitable {SFRAME_ABI_AARCH64_ENDIAN_LITTLE} {Value} {@code{AARCH64 little-endian}} +@headitem ABI/arch Identifier @tab Value @tab Description + +@tindex SFRAME_ABI_AARCH64_ENDIAN_BIG +@item @code{SFRAME_ABI_AARCH64_ENDIAN_BIG} +@tab 1 @tab AARCH64 big-endian + +@tindex SFRAME_ABI_AARCH64_ENDIAN_LITTLE +@item @code{SFRAME_ABI_AARCH64_ENDIAN_LITTLE} +@tab 2 @tab AARCH64 little-endian + +@tindex SFRAME_ABI_AMD64_ENDIAN_LITTLE +@item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE} +@tab 3 @tab AMD64 little-endian + +@end multitable + +The presence of an explicit identification of ABI/arch in SFrame may allow +unwinders to make certain ABI-specific decisions. + +@node SFrame Function Descriptor Entries +@section SFrame FDE +@cindex SFrame FDE + +The SFrame Function Descriptor Entry sub-section is a sorted array of +fixed-length SFrame function descriptor entries (SFrame FDEs). Each SFrame FDE +is a packed structure which contains information to describe a function's unwind +information at a high-level. + +@example +typedef struct sframe_func_desc_entry +@{ + int32_t sfde_func_start_address; + uint32_t sfde_func_size; + uint32_t sfde_func_start_fre_off; + uint32_t sfde_func_num_fres; + uint8_t sfde_func_info; +@} ATTRIBUTE_PACKED sframe_func_desc_entry; +@end example + +@code{sfde_func_start_fre_off} is the offset to the first SFrame FRE for the +function. This offset is relative to the @emph{end of the SFrame FDE} +sub-section (unlike the offsets in the SFrame header, which are relative to the +@emph{end} of the SFrame header). + +@code{sfde_func_info} is the "info word", containing information on the FRE +type and the FDE type for the function @xref{The SFrame FDE info word}. + +Following table describes each component of the SFrame FDE structure: + +@multitable {Offset} {@code{uint32_t sfde_func_start_fre_off}} {The ABI/arch identifier. See above} +@headitem Offset @tab Name @tab Description +@item 0x00 +@tab @code{int32_t sfde_func_start_address} +@tab Signed 32-bit integral field denoting the virtual memory address of the +described function. + +@item 0x04 +@tab @code{uint32_t sfde_func_size} +@tab Unsigned 32-bit integral field specifying the size of the function in +bytes. + +@item 0x08 +@tab @code{uint32_t sfde_func_start_fre_off} +@tab Unsigned 32-bit integral field specifying the offset in bytes of the +function's first SFrame FRE in the SFrame section. + +@item 0x0c +@tab @code{uint32_t sfde_func_num_fres} +@tab Unsigned 32-bit integral field specifying the total number of SFrame FREs +used for the function. + +@item 0x10 +@tab @code{uint8_t sfde_func_info} +@tab The SFrame FDE info word. @xref{The SFrame FDE info word}. + +@end multitable + +@menu +* The SFrame FDE info word:: +* The SFrame FDE types:: +* The SFrame FRE types:: +@end menu + +@cindex The SFrame FDE info word +@node The SFrame FDE info word +@subsection The SFrame FDE info word, sfde_func_info + +The info word is a bitfield split into three parts. From MSB to LSB: + +@multitable {Bit offset} {@code{isroot}} {Length of variable-length data for this type (some kinds only).} +@headitem Bit offset @tab Name @tab Description +@item 7--5 +@tab @code{unused} +@tab Unused bits. + +@item 4 +@tab @code{fdetype} +@tab SFRAME_FDE_TYPE_PCMASK (1) or SFRAME_FDE_TYPE_PCINC (0). @xref{The SFrame FDE types}. + +@item 0--3 +@tab @code{fretype} +@tab Choice of three SFrame FRE types. @xref{The SFrame FRE types}. +@end multitable + +@node The SFrame FDE types +@subsection The SFrame FDE types +@tindex SFRAME_FDE_TYPE_PCMASK +@tindex SFRAME_FDE_TYPE_PCINC + +SFrame format defines two types of FDE entries. The choice of which SFrame FDE +type to use is made based on the instruction patterns in the relevant program +stub. + +An SFrame FDE of type @code{SFRAME_FDE_TYPE_PCINC} is an indication that the PCs in the +FREs should be treated as increments in bytes. This is used fo the the bulk of +the executable code of a program, which contains instructions with no specific +pattern. + +In contrast, an SFrame FDE of type @code{SFRAME_FDE_TYPE_PCMASK} is an +indication that the PCs in the FREs should be treated as masks. This type is +useful for the cases where a small pattern of instructions in a program stub is +used repeatedly for a specific functionality. Typical usecases are pltN +entries and trampolines. + +@multitable {Name of SFrame FDE type} {Value} {Unwinders perform a (PC >= FRE_START_ADDR)} +@headitem Name of SFrame FDE type @tab Value @tab Description + +@item SFRAME_FDE_TYPE_PCINC +@tab 0 @tab Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. + +@item SFRAME_FDE_TYPE_PCMASK +@tab 1 @tab Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK) +to look up a matching FRE. + +@end multitable + +@node The SFrame FRE types +@subsection The SFrame FRE types + +A real world application can have functions of size big and small. SFrame +format defines three types of SFrame FRE entries to represent the unwind +information for such a variety of function sizes. These representations vary +in the number of bits needed to encode the start address offset in the SFrame +FRE. + +The following constants are defined and used to identify the SFrame FRE types: + +@multitable {SFRAME_FRE_TYPE_ADDR1} {@code{Value}} {The start address offset of FRE is an} +@headitem Name @tab Value @tab Description + +@tindex SFRAME_FRE_TYPE_ADDR1 +@item @code{SFRAME_FRE_TYPE_ADDR1} +@tab 0 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +8-bit value. + +@tindex SFRAME_FRE_TYPE_ADDR2 +@item @code{SFRAME_FRE_TYPE_ADDR2} +@tab 1 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +16-bit value. + +@tindex SFRAME_FRE_TYPE_ADDR4 +@item @code{SFRAME_FRE_TYPE_ADDR4} +@tab 2 +@tab The start address offset (in bytes) of the SFrame FRE is an unsigned +32-bit value. +@end multitable + +A single function must use the same type of FRE throughout. The choice of +which SFrame FRE is used to encode the unwind information of a function, is +stored in the @xref{The SFrame FDE info word}. + +@node SFrame Frame Row Entries +@section SFrame FRE +@cindex SFrame FRE + +The SFrame Frame Row Entry sub-section contains the core of the unwind +information. + +An SFrame Frame Row Entry is a self-sufficient record containing SFrame unwind +info for a range of contiguous addresses, starting at the specified offset from +the start of the function. Each SFrame Frame Row Entry is followed by S*N +bytes, where: + +@itemize @minus +@item +@code{S} is the size of the stack frame offset for the FRE, and +@item +@code{N} is the number of stack frame offsets in the FRE +@end itemize + +The stack offsets, following the FRE, are interpreted in order as follows: + +@itemize @minus +@item +The first offset is always used to locate the CFA, by interpreting it as: +CFA = @code{BASE_REG} + offset1. +@item +If RA is being tracked, the second offset is always used to locate the RA, by +interpreting it as: RA = CFA + offset2. If RA is @emph{not} being tracked +@emph{and} FP is being tracked, the second offset will be used to locate the +FP, by interpreting it as: FP = CFA + offset2. +@item +If both RA and FP are being tracked, the third offset will be used to locate +the FP, by interpreting it as FP = CFA + offset3. +@end itemize + +The entities @code{S}, @code{N} and @code{BASE_REG} are identified using the +SFrame FRE info word, a.k.a. the @code{sframe_fre_info} +@xref{The SFrame FRE info word}. + +Following are the definitions of the allowed SFrame FRE: + +@example +typedef struct sframe_frame_row_entry_addr1 +@{ + uint8_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr1; +@end example + +@example +typedef struct sframe_frame_row_entry_addr2 +@{ + uint16_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr2; +@end example + +@example +typedef struct sframe_frame_row_entry_addr4 +@{ + uint32_t sfre_start_address; + sframe_fre_info sfre_info; +@} ATTRIBUTE_PACKED sframe_frame_row_entry_addr4; +@end example + +@code{sfre_start_address} is an unsigned 8-bit/16-bit/32-bit integral field +identifies the start address of the range of program counters, for which the +SFrame FRE applies. The value encoded in the @code{sfre_start_address} field +is the offset in bytes of the start address of the SFrame FRE, from the start +address of the function. + +Further FRE types may be added in future. + +@menu +* The SFrame FRE info word:: +@end menu + +@cindex The SFrame FRE info word +@node The SFrame FRE info word +@subsection The SFrame FRE info word, sfre_info + +The SFrame FRE info word is a bitfield split into four parts. From MSB to LSB: + +@multitable {Bit offset} {@code{fre_cfa_base_reg_id}} {Size of stack offsets in bytes. Valid values} +@headitem Bit offset @tab Name @tab Description +@item 7 +@tab @code{unused} +@tab Unused bit. + +@item 5-6 +@tab @code{fre_offset_size} +@tab Size of stack offsets in bytes. Valid values are SFRAME_FRE_OFFSET_1B, +SFRAME_FRE_OFFSET_2B, and SFRAME_FRE_OFFSET_4B. + +@item 1-4 +@tab @code{fre_offset_count} +@tab A value of upto 3 is allowed to track all three of CFA, FP and RA. + +@item 0 +@tab @code{fre_cfa_base_reg_id} +@tab Distinguish between SP or FP based CFA recovery. + +@end multitable + +@multitable {SFRAME_FRE_OFFSET_4B} {@code{Value}} {All stack offsets following the fixed-length} +@headitem Name @tab Value @tab Description + +@tindex SFRAME_FRE_OFFSET_1B +@item @code{SFRAME_FRE_OFFSET_1B} +@tab 0 +@tab All stack offsets following the fixed-length FRE structure are 1 byte +long. + +@tindex SFRAME_FRE_OFFSET_2B +@item @code{SFRAME_FRE_OFFSET_2B} +@tab 1 +@tab All stack offsets following the fixed-length FRE structure are 2 bytes +long. + +@tindex SFRAME_FRE_OFFSET_4B +@item @code{SFRAME_FRE_OFFSET_4B} +@tab 2 +@tab All stack offsets following the fixed-length FRE structure are 4 bytes +long. + +@end multitable + +@node Index +@unnumbered Index + +@syncodeindex tp cp +@printindex cp + +@bye |