xref: /linux/tools/objtool/trace.c (revision fcb268b47a2f4a497fdb40ef24bb9e06488b7213)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2025, Oracle and/or its affiliates.
4  */
5 
6 #include <objtool/trace.h>
7 
8 bool trace;
9 int trace_depth;
10 
11 /*
12  * Macros to trace CFI state attributes changes.
13  */
14 
15 #define TRACE_CFI_ATTR(attr, prev, next, fmt, ...)		\
16 ({								\
17 	if ((prev)->attr != (next)->attr)			\
18 		TRACE("%s=" fmt " ", #attr, __VA_ARGS__);	\
19 })
20 
21 #define TRACE_CFI_ATTR_BOOL(attr, prev, next)			\
22 	TRACE_CFI_ATTR(attr, prev, next,			\
23 		       "%s", (next)->attr ? "true" : "false")
24 
25 #define TRACE_CFI_ATTR_NUM(attr, prev, next, fmt)		\
26 	TRACE_CFI_ATTR(attr, prev, next, fmt, (next)->attr)
27 
28 #define CFI_REG_NAME_MAXLEN   16
29 
30 /*
31  * Return the name of a register. Note that the same static buffer
32  * is returned if the name is dynamically generated.
33  */
34 static const char *cfi_reg_name(unsigned int reg)
35 {
36 	static char rname_buffer[CFI_REG_NAME_MAXLEN];
37 
38 	switch (reg) {
39 	case CFI_UNDEFINED:
40 		return "<undefined>";
41 	case CFI_CFA:
42 		return "cfa";
43 	case CFI_SP_INDIRECT:
44 		return "(sp)";
45 	case CFI_BP_INDIRECT:
46 		return "(bp)";
47 	}
48 
49 	if (snprintf(rname_buffer, CFI_REG_NAME_MAXLEN, "r%d", reg) == -1)
50 		return "<error>";
51 
52 	return (const char *)rname_buffer;
53 }
54 
55 /*
56  * Functions and macros to trace CFI registers changes.
57  */
58 
59 static void trace_cfi_reg(const char *prefix, int reg, const char *fmt,
60 			  int base_prev, int offset_prev,
61 			  int base_next, int offset_next)
62 {
63 	char *rname;
64 
65 	if (base_prev == base_next && offset_prev == offset_next)
66 		return;
67 
68 	if (prefix)
69 		TRACE("%s:", prefix);
70 
71 	if (base_next == CFI_UNDEFINED) {
72 		TRACE("%1$s=<undef> ", cfi_reg_name(reg));
73 	} else {
74 		rname = strdup(cfi_reg_name(reg));
75 		TRACE(fmt, rname, cfi_reg_name(base_next), offset_next);
76 		free(rname);
77 	}
78 }
79 
80 static void trace_cfi_reg_val(const char *prefix, int reg,
81 			      int base_prev, int offset_prev,
82 			      int base_next, int offset_next)
83 {
84 	trace_cfi_reg(prefix, reg, "%1$s=%2$s%3$+d ",
85 		      base_prev, offset_prev, base_next, offset_next);
86 }
87 
88 static void trace_cfi_reg_ref(const char *prefix, int reg,
89 			      int base_prev, int offset_prev,
90 			      int base_next, int offset_next)
91 {
92 	trace_cfi_reg(prefix, reg, "%1$s=(%2$s%3$+d) ",
93 		      base_prev, offset_prev, base_next, offset_next);
94 }
95 
96 #define TRACE_CFI_REG_VAL(reg, prev, next)				\
97 	trace_cfi_reg_val(NULL, reg, prev.base, prev.offset,		\
98 			  next.base, next.offset)
99 
100 #define TRACE_CFI_REG_REF(reg, prev, next)				\
101 	trace_cfi_reg_ref(NULL, reg, prev.base, prev.offset,		\
102 			  next.base, next.offset)
103 
104 void trace_insn_state(struct instruction *insn, struct insn_state *sprev,
105 		      struct insn_state *snext)
106 {
107 	struct cfi_state *cprev, *cnext;
108 	int i;
109 
110 	if (!memcmp(sprev, snext, sizeof(struct insn_state)))
111 		return;
112 
113 	cprev = &sprev->cfi;
114 	cnext = &snext->cfi;
115 
116 	disas_print_insn(stderr, objtool_disas_ctx, insn,
117 			 trace_depth - 1, "state: ");
118 
119 	/* print registers changes */
120 	TRACE_CFI_REG_VAL(CFI_CFA, cprev->cfa, cnext->cfa);
121 	for (i = 0; i < CFI_NUM_REGS; i++) {
122 		TRACE_CFI_REG_VAL(i, cprev->vals[i], cnext->vals[i]);
123 		TRACE_CFI_REG_REF(i, cprev->regs[i], cnext->regs[i]);
124 	}
125 
126 	/* print attributes changes */
127 	TRACE_CFI_ATTR_NUM(stack_size, cprev, cnext, "%d");
128 	TRACE_CFI_ATTR_BOOL(drap, cprev, cnext);
129 	if (cnext->drap) {
130 		trace_cfi_reg_val("drap", cnext->drap_reg,
131 				  cprev->drap_reg, cprev->drap_offset,
132 				  cnext->drap_reg, cnext->drap_offset);
133 	}
134 	TRACE_CFI_ATTR_BOOL(bp_scratch, cprev, cnext);
135 	TRACE_CFI_ATTR_NUM(instr, sprev, snext, "%d");
136 	TRACE_CFI_ATTR_NUM(uaccess_stack, sprev, snext, "%u");
137 
138 	TRACE("\n");
139 
140 	insn->trace = 1;
141 }
142