diff options
Diffstat (limited to 'libsframe/doc/sframe-spec.texi')
-rw-r--r-- | libsframe/doc/sframe-spec.texi | 123 |
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. |