Skip to content

Commit bf37eef

Browse files
Weinan Liunathan-zcgao
Weinan Liu
authored andcommitted
unwind: add sframe v2 header
Add sframe header so that we know how to access the sframe section generated by compilers. This is the sframe header file borrowed from the patchset [1] Josh Poimboeuf according to sframe v2 spec [2]. [1]: https://lore.kernel.org/lkml/42c0a99236af65c09c8182e260af7bcf5aa1e158.1730150953.git.jpoimboe@kernel.org/ [2]: https://sourceware.org/binutils/docs/sframe-spec.html Signed-off-by: Weinan Liu <[email protected]>
1 parent e3c2446 commit bf37eef

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

kernel/sframe.h

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* Copyright (C) 2023, Oracle and/or its affiliates.
4+
*
5+
* This file contains definitions for the SFrame stack tracing format, which is
6+
* documented at https://sourceware.org/binutils/docs
7+
*/
8+
#ifndef _SFRAME_H
9+
#define _SFRAME_H
10+
11+
#include <linux/types.h>
12+
13+
#define SFRAME_VERSION_1 1
14+
#define SFRAME_VERSION_2 2
15+
#define SFRAME_MAGIC 0xdee2
16+
17+
/* Function Descriptor Entries are sorted on PC. */
18+
#define SFRAME_F_FDE_SORTED 0x1
19+
/* Frame-pointer based stack tracing. Defined, but not set. */
20+
#define SFRAME_F_FRAME_POINTER 0x2
21+
22+
#define SFRAME_CFA_FIXED_FP_INVALID 0
23+
#define SFRAME_CFA_FIXED_RA_INVALID 0
24+
25+
/* Supported ABIs/Arch. */
26+
#define SFRAME_ABI_AARCH64_ENDIAN_BIG 1 /* AARCH64 big endian. */
27+
#define SFRAME_ABI_AARCH64_ENDIAN_LITTLE 2 /* AARCH64 little endian. */
28+
#define SFRAME_ABI_AMD64_ENDIAN_LITTLE 3 /* AMD64 little endian. */
29+
30+
/* SFrame FRE types. */
31+
#define SFRAME_FRE_TYPE_ADDR1 0
32+
#define SFRAME_FRE_TYPE_ADDR2 1
33+
#define SFRAME_FRE_TYPE_ADDR4 2
34+
35+
/*
36+
* SFrame Function Descriptor Entry types.
37+
*
38+
* The SFrame format has two possible representations for functions. The
39+
* choice of which type to use is made according to the instruction patterns
40+
* in the relevant program stub.
41+
*/
42+
43+
/* Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. */
44+
#define SFRAME_FDE_TYPE_PCINC 0
45+
/*
46+
* Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK)
47+
* to look up a matching FRE. Typical usecases are pltN entries, trampolines
48+
* etc.
49+
*/
50+
#define SFRAME_FDE_TYPE_PCMASK 1
51+
52+
/**
53+
* struct sframe_preamble - SFrame Preamble.
54+
* @magic: Magic number (SFRAME_MAGIC).
55+
* @version: Format version number (SFRAME_VERSION).
56+
* @flags: Various flags.
57+
*/
58+
struct sframe_preamble {
59+
u16 magic;
60+
u8 version;
61+
u8 flags;
62+
} __packed;
63+
64+
/**
65+
* struct sframe_header - SFrame Header.
66+
* @preamble: SFrame preamble.
67+
* @abi_arch: Identify the arch (including endianness) and ABI.
68+
* @cfa_fixed_fp_offset: Offset for the Frame Pointer (FP) from CFA may be
69+
* fixed for some ABIs ((e.g, in AMD64 when -fno-omit-frame-pointer is
70+
* used). When fixed, this field specifies the fixed stack frame offset
71+
* and the individual FREs do not need to track it. When not fixed, it
72+
* is set to SFRAME_CFA_FIXED_FP_INVALID, and the individual FREs may
73+
* provide the applicable stack frame offset, if any.
74+
* @cfa_fixed_ra_offset: Offset for the Return Address from CFA is fixed for
75+
* some ABIs. When fixed, this field specifies the fixed stack frame
76+
* offset and the individual FREs do not need to track it. When not
77+
* fixed, it is set to SFRAME_CFA_FIXED_FP_INVALID.
78+
* @auxhdr_len: Number of bytes making up the auxiliary header, if any.
79+
* Some ABI/arch, in the future, may use this space for extending the
80+
* information in SFrame header. Auxiliary header is contained in bytes
81+
* sequentially following the sframe_header.
82+
* @num_fdes: Number of SFrame FDEs in this SFrame section.
83+
* @num_fres: Number of SFrame Frame Row Entries.
84+
* @fre_len: Number of bytes in the SFrame Frame Row Entry section.
85+
* @fdes_off: Offset of SFrame Function Descriptor Entry section.
86+
* @fres_off: Offset of SFrame Frame Row Entry section.
87+
*/
88+
struct sframe_header {
89+
struct sframe_preamble preamble;
90+
u8 abi_arch;
91+
s8 cfa_fixed_fp_offset;
92+
s8 cfa_fixed_ra_offset;
93+
u8 auxhdr_len;
94+
u32 num_fdes;
95+
u32 num_fres;
96+
u32 fre_len;
97+
u32 fdes_off;
98+
u32 fres_off;
99+
} __packed;
100+
101+
#define SFRAME_HDR_SIZE(sframe_hdr) \
102+
((sizeof(struct sframe_header) + (sframe_hdr).auxhdr_len))
103+
104+
/* Two possible keys for executable (instruction) pointers signing. */
105+
#define SFRAME_AARCH64_PAUTH_KEY_A 0 /* Key A. */
106+
#define SFRAME_AARCH64_PAUTH_KEY_B 1 /* Key B. */
107+
108+
/**
109+
* struct sframe_fde - SFrame Function Descriptor Entry.
110+
* @start_addr: Function start address. Encoded as a signed offset,
111+
* relative to the current FDE.
112+
* @size: Size of the function in bytes.
113+
* @fres_off: Offset of the first SFrame Frame Row Entry of the function,
114+
* relative to the beginning of the SFrame Frame Row Entry sub-section.
115+
* @fres_num: Number of frame row entries for the function.
116+
* @info: Additional information for deciphering the stack trace
117+
* information for the function. Contains information about SFrame FRE
118+
* type, SFrame FDE type, PAC authorization A/B key, etc.
119+
* @rep_size: Block size for SFRAME_FDE_TYPE_PCMASK
120+
* @padding: Unused
121+
*/
122+
struct sframe_fde {
123+
s32 start_addr;
124+
u32 size;
125+
u32 fres_off;
126+
u32 fres_num;
127+
u8 info;
128+
u8 rep_size;
129+
u16 padding;
130+
} __packed;
131+
132+
/*
133+
* 'func_info' in SFrame FDE contains additional information for deciphering
134+
* the stack trace information for the function. In V1, the information is
135+
* organized as follows:
136+
* - 4-bits: Identify the FRE type used for the function.
137+
* - 1-bit: Identify the FDE type of the function - mask or inc.
138+
* - 1-bit: PAC authorization A/B key (aarch64).
139+
* - 2-bits: Unused.
140+
* ---------------------------------------------------------------------
141+
* | Unused | PAC auth A/B key (aarch64) | FDE type | FRE type |
142+
* | | Unused (amd64) | | |
143+
* ---------------------------------------------------------------------
144+
* 8 6 5 4 0
145+
*/
146+
147+
/* Note: Set PAC auth key to SFRAME_AARCH64_PAUTH_KEY_A by default. */
148+
#define SFRAME_FUNC_INFO(fde_type, fre_enc_type) \
149+
(((SFRAME_AARCH64_PAUTH_KEY_A & 0x1) << 5) | \
150+
(((fde_type) & 0x1) << 4) | ((fre_enc_type) & 0xf))
151+
152+
#define SFRAME_FUNC_FRE_TYPE(data) ((data) & 0xf)
153+
#define SFRAME_FUNC_FDE_TYPE(data) (((data) >> 4) & 0x1)
154+
#define SFRAME_FUNC_PAUTH_KEY(data) (((data) >> 5) & 0x1)
155+
156+
/*
157+
* Size of stack frame offsets in an SFrame Frame Row Entry. A single
158+
* SFrame FRE has all offsets of the same size. Offset size may vary
159+
* across frame row entries.
160+
*/
161+
#define SFRAME_FRE_OFFSET_1B 0
162+
#define SFRAME_FRE_OFFSET_2B 1
163+
#define SFRAME_FRE_OFFSET_4B 2
164+
165+
/* An SFrame Frame Row Entry can be SP or FP based. */
166+
#define SFRAME_BASE_REG_FP 0
167+
#define SFRAME_BASE_REG_SP 1
168+
169+
/*
170+
* The index at which a specific offset is presented in the variable length
171+
* bytes of an FRE.
172+
*/
173+
#define SFRAME_FRE_CFA_OFFSET_IDX 0
174+
/*
175+
* The RA stack offset, if present, will always be at index 1 in the variable
176+
* length bytes of the FRE.
177+
*/
178+
#define SFRAME_FRE_RA_OFFSET_IDX 1
179+
/*
180+
* The FP stack offset may appear at offset 1 or 2, depending on the ABI as RA
181+
* may or may not be tracked.
182+
*/
183+
#define SFRAME_FRE_FP_OFFSET_IDX 2
184+
185+
/*
186+
* 'fre_info' in SFrame FRE contains information about:
187+
* - 1 bit: base reg for CFA
188+
* - 4 bits: Number of offsets (N). A value of up to 3 is allowed to track
189+
* all three of CFA, FP and RA (fixed implicit order).
190+
* - 2 bits: information about size of the offsets (S) in bytes.
191+
* Valid values are SFRAME_FRE_OFFSET_1B, SFRAME_FRE_OFFSET_2B,
192+
* SFRAME_FRE_OFFSET_4B
193+
* - 1 bit: Mangled RA state bit (aarch64 only).
194+
* ---------------------------------------------------------------
195+
* | Mangled-RA (aarch64) | Size of | Number of | base_reg |
196+
* | Unused (amd64) | offsets | offsets | |
197+
* ---------------------------------------------------------------
198+
* 8 7 5 1 0
199+
*/
200+
201+
/* Note: Set mangled_ra_p to zero by default. */
202+
#define SFRAME_FRE_INFO(base_reg_id, offset_num, offset_size) \
203+
(((0 & 0x1) << 7) | (((offset_size) & 0x3) << 5) | \
204+
(((offset_num) & 0xf) << 1) | ((base_reg_id) & 0x1))
205+
206+
/* Set the mangled_ra_p bit as indicated. */
207+
#define SFRAME_FRE_INFO_UPDATE_MANGLED_RA_P(mangled_ra_p, fre_info) \
208+
((((mangled_ra_p) & 0x1) << 7) | ((fre_info) & 0x7f))
209+
210+
#define SFRAME_FRE_CFA_BASE_REG_ID(data) ((data) & 0x1)
211+
#define SFRAME_FRE_OFFSET_COUNT(data) (((data) >> 1) & 0xf)
212+
#define SFRAME_FRE_OFFSET_SIZE(data) (((data) >> 5) & 0x3)
213+
#define SFRAME_FRE_MANGLED_RA_P(data) (((data) >> 7) & 0x1)
214+
215+
#endif /* _SFRAME_H */

0 commit comments

Comments
 (0)