aboutsummaryrefslogtreecommitdiff
path: root/libsframe/doc/sframe-spec.texi
diff options
context:
space:
mode:
Diffstat (limited to 'libsframe/doc/sframe-spec.texi')
-rw-r--r--libsframe/doc/sframe-spec.texi123
1 files changed, 113 insertions, 10 deletions
diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
index 69fe873..7307789 100644
--- a/libsframe/doc/sframe-spec.texi
+++ b/libsframe/doc/sframe-spec.texi
@@ -77,12 +77,13 @@ Appendices
@section Overview
@cindex Overview
-The SFrame stack trace 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 stack trace information is provided in a loaded section, known as
+the @code{.sframe} section. When available, the @code{.sframe} section appears
+in segment of type PT_GNU_SFRAME. An ELF SFrame section will have the type
+SHT_GNU_SFRAME.
-The SFrame format is currently supported only for select ABIs, namely, AMD64
-and AAPCS64.
+The SFrame format is currently supported only for select ABIs, namely, AMD64,
+AAPCS64, and s390x.
A portion of the SFrame format follows an unaligned on-disk representation.
Some data structures, however, (namely the SFrame header and the SFrame
@@ -139,6 +140,31 @@ bytes to the start PC of the associated function from the field itself.
bytes to the start PC of the associated function from the start of the SFrame
section.
@end itemize
+@item
+Add a new ABI/arch identifier SFRAME_ABI_S390X_ENDIAN_BIG for the s390
+architecture (64-bit) s390x ABI. Other s390x-specific backward compatible
+changes including the following helper definitions have been incrementally
+added to SFrame version 2 only:
+ @itemize @minus
+ @item SFRAME_S390X_SP_VAL_OFFSET: SP value offset from CFA.
+ @item SFRAME_V2_S390X_OFFSET_IS_REGNUM: Test whether FP/RA offset is an encoded
+DWARF register number.
+ @item SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM: Encode a DWARF register number as an
+FP/RA offset.
+ @item SFRAME_V2_S390X_OFFSET_DECODE_REGNUM: Decode a DWARF register number from
+an FP/RA offset.
+ @item SFRAME_FRE_RA_OFFSET_INVALID: Invalid RA offset value (like
+SFRAME_CFA_FIXED_RA_INVALID). Used on s390x as padding offset to represent
+FP without RA saved.
+ @item SFRAME_S390X_CFA_OFFSET_ADJUSTMENT: CFA offset (from CFA base register)
+adjustment value. Used to enable use of 8-bit SFrame offsets on s390x.
+ @item SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR: CFA offset alignment factor.
+Used to scale down the CFA offset to improve the use of 8-bit SFrame offsets.
+ @item SFRAME_V2_S390X_CFA_OFFSET_ENCODE: Encode CFA offset (i.e., apply
+CFA offset adjustment and then scale down by CFA offset alignment factor).
+ @item SFRAME_V2_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e., scale up
+by CFA offset alignment factor and then revert CFA offset adjustment).
+ @end itemize
@end itemize
SFrame version 1 is now obsolete and should not be used.
@@ -421,6 +447,10 @@ in the format.
@item @code{SFRAME_ABI_AMD64_ENDIAN_LITTLE}
@tab 3 @tab AMD64 little-endian
+@tindex SFRAME_ABI_S390X_ENDIAN_BIG
+@item @code{SFRAME_ABI_S390X_ENDIAN_BIG}
+@tab 4 @tab s390x big-endian
+
@end multitable
The presence of an explicit identification of ABI/arch in SFrame may allow
@@ -780,10 +810,11 @@ This section covers the ABI/arch-specific definition of the SFrame file format.
Currently, the only part of the SFrame file format definition that is
ABI/arch-specific is the interpretation of the variable number of bytes at the
-tail end of each SFrame FRE. Currently, these bytes are only used for
-representing stack offsets (for all the currently supported ABIs). It is
-recommended to peruse this section along with @xref{SFrame Frame Row Entries}
-for clarity of context.
+tail end of each SFrame FRE. Currently, these bytes are used for representing
+stack offsets (for AMD64 and AARCH64 ABIs). For s390x ABI, the interpretation
+of these bytes may be stack offsets or even register numbers. It is recommended
+to peruse this section along with @xref{SFrame Frame Row Entries} for clarity of
+context.
Future ABIs must specify the algorithm for identifying the appropriate SFrame
FRE stack offsets in this chapter. This should inevitably include the
@@ -794,6 +825,7 @@ auxiliary SFrame header, etc., if used, must also be outlined here.
@menu
* AMD64::
* AArch64::
+* s390x::
@end menu
@node AMD64
@@ -850,6 +882,77 @@ Hence, in summary:
@item 3 @tab FP = CFA + offset3
@end multitable
+@node s390x
+@section s390x
+
+A stack tracer implementation must initialize the SP to the designated SP
+register value, the FP to the preferred FP register value, and the RA to the
+designated RA register value in the topmost stack frame of the callchain. This
+is required, as either the SP or FP is used as CFA base register and as the FP
+and/or RA are not necessarily saved on the stack. For RA this may only be the
+case in the topmost stack frame of the callchain. For FP this may be the case
+in any stack frame.
+
+Irrespective of the ABI, the first stack offset is always used to locate the
+CFA. On s390x the value of the offset is stored adjusted by the s390x-specific
+@code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT} and scaled down by the s390x-specific
+@code{SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR}, to enable and improve the use
+of signed 8-bit offsets on s390x.
+s390x-specific helpers @code{SFRAME_V2_S390X_CFA_OFFSET_ENCODE} and
+@code{SFRAME_V2_S390X_CFA_OFFSET_DECODE} are provided to perform or undo
+the adjustment and scaling. The CFA offset can therefore be interpreted as:
+CFA = @code{BASE_REG} + offset1 - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}
+or
+CFA = @code{BASE_REG}
+ + (offset1 * @code{SFRAME_S390X_CFA_OFFSET_ALIGNMENT_FACTOR})
+ - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}.
+The identification of the @code{BASE_REG} is done by using the
+@code{fre_cfa_base_reg_id} field in the SFrame FRE info word.
+
+The (64-bit) s390x ELF ABI does not mandate the precise location in a function
+where the return address (RA) and frame pointer (FP) are saved, if at all.
+Hence the need to track RA in the SFrame stack trace format. As RA is being
+tracked in this ABI, the second stack offset is always used to locate the RA
+stack slot, by interpreting it as: RA = CFA + offset2, unless the offset has a
+value of @code{SFRAME_FRE_RA_OFFSET_INVALID}. RA remains unchanged, if the
+offset is not available or has a value of @code{SFRAME_FRE_RA_OFFSET_INVALID}.
+Stack tracers are recommended to validate that the "unchanged RA" pattern, when
+present, is seen only for the topmost stack frame. The third stack offset is
+used to locate the FP stack slot, by interpreting it as: FP = CFA + offset3.
+FP remains unchanged, if the offset is not available.
+
+In leaf functions the RA and FP may be saved in other registers, such as
+floating-point registers (FPRs), instead of on the stack. To represent this
+in the SFrame stack trace format the DWARF register number is encoded as
+RA/FP offset using the least-significant bit (LSB) as indication:
+offset = (regnum << 1) | 1. A LSB of zero indicates a stack slot offset.
+A LSB of one indicates a DWARF register number, which is interpreted as:
+regnum = offset >> 1. Given the nature of leaf functions, this can only occur
+in the topmost frame during stack tracing. It is recommended that a stack
+tracer implementation performs the required checks to ensure that restoring
+FP and RA from the said register locations is done only for topmost stack
+frame in the callchain.
+
+Given the nature of things, the number of stack offsets and/or register numbers
+seen on s390x per SFrame FRE is either 1, 2, or 3.
+
+Hence, in summary:
+
+@multitable @columnfractions .15 .85
+@headitem Offset ID @tab Interpretation in s390x
+@item 1 @tab CFA = @code{BASE_REG} + offset1
+@item 2 @tab RA stack slot = CFA + offset2, if (offset2 & 1 == 0)
+ @*RA register number = offset2 >> 1, if (offset2 & 1 == 1)
+ @*RA not saved if (offset2 == @code{SFRAME_FRE_RA_OFFSET_INVALID})
+@item 3 @tab FP stack slot = CFA + offset3, if (offset3 & 1 == 0)
+ @*FP register number = offset3 >> 1, if (offset3 & 1 == 1)
+@end multitable
+
+The s390x ELF ABI defines the CFA as stack pointer (SP) at call site +160. The
+SP can therefore be obtained using the SP value offset from CFA
+@code{SFRAME_S390X_SP_VAL_OFFSET} of -160 as follows:
+SP = CFA + @code{SFRAME_S390X_SP_VAL_OFFSET}
+
@node Generating Stack Traces using SFrame
@appendix Generating Stack Traces using SFrame
@@ -913,7 +1016,7 @@ SFrame section.
fp_offset = sframe_fre_get_fp_offset (fre);
cfa = base_reg_val + cfa_offset;
- next_frame->sp = cfa;
+ next_frame->sp = cfa [+ SFRAME_S390X_SP_VAL_OFFSET on s390x];
ra_stack_loc = cfa + ra_offset;
// Get the address stored in the stack location.