1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
4 */
5
6 #ifndef _ORC_TYPES_H
7 #define _ORC_TYPES_H
8
9 #include <linux/types.h>
10 #include <linux/compiler.h>
11
12 /*
13 * The ORC_REG_* registers are base registers which are used to find other
14 * registers on the stack.
15 *
16 * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
17 * address of the previous frame: the caller's SP before it called the current
18 * function.
19 *
20 * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
21 * the current frame.
22 *
23 * The most commonly used base registers are SP and BP -- which the previous SP
24 * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
25 * usually based on.
26 *
27 * The rest of the base registers are needed for special cases like entry code
28 * and GCC realigned stacks.
29 */
30 #define ORC_REG_UNDEFINED 0
31 #define ORC_REG_PREV_SP 1
32 #define ORC_REG_DX 2
33 #define ORC_REG_DI 3
34 #define ORC_REG_BP 4
35 #define ORC_REG_SP 5
36 #define ORC_REG_R10 6
37 #define ORC_REG_R13 7
38 #define ORC_REG_BP_INDIRECT 8
39 #define ORC_REG_SP_INDIRECT 9
40 #define ORC_REG_MAX 15
41
42 /*
43 * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
44 * caller's SP right before it made the call). Used for all callable
45 * functions, i.e. all C code and all callable asm functions.
46 *
47 * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
48 * to a fully populated pt_regs from a syscall, interrupt, or exception.
49 *
50 * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
51 * points to the iret return frame.
52 *
53 * The UNWIND_HINT macros are used only for the unwind_hint struct. They
54 * aren't used in struct orc_entry due to size and complexity constraints.
55 * Objtool converts them to real types when it converts the hints to orc
56 * entries.
57 */
58 #define ORC_TYPE_CALL 0
59 #define ORC_TYPE_REGS 1
60 #define ORC_TYPE_REGS_IRET 2
61 #define UNWIND_HINT_TYPE_SAVE 3
62 #define UNWIND_HINT_TYPE_RESTORE 4
63
64 #ifndef __ASSEMBLY__
65 /*
66 * This struct is more or less a vastly simplified version of the DWARF Call
67 * Frame Information standard. It contains only the necessary parts of DWARF
68 * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
69 * unwinder how to find the previous SP and BP (and sometimes entry regs) on
70 * the stack for a given code address. Each instance of the struct corresponds
71 * to one or more code locations.
72 */
73 struct orc_entry {
74 s16 sp_offset;
75 s16 bp_offset;
76 unsigned sp_reg:4;
77 unsigned bp_reg:4;
78 unsigned type:2;
79 unsigned end:1;
80 } __packed;
81
82 /*
83 * This struct is used by asm and inline asm code to manually annotate the
84 * location of registers on the stack for the ORC unwinder.
85 *
86 * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
87 */
88 struct unwind_hint {
89 u32 ip;
90 s16 sp_offset;
91 u8 sp_reg;
92 u8 type;
93 u8 end;
94 };
95 #endif /* __ASSEMBLY__ */
96
97 #endif /* _ORC_TYPES_H */