summaryrefslogtreecommitdiff
path: root/tools/objtool/include
diff options
context:
space:
mode:
authorAlexandre Chartre <alexandre.chartre@oracle.com>2025-11-21 10:53:20 +0100
committerPeter Zijlstra <peterz@infradead.org>2025-11-21 15:30:09 +0100
commit70589843b36fee0c6e73632469da4e5fd11f0968 (patch)
treeec571afb216ca9c4ad28de11288109257cd10b69 /tools/objtool/include
parentde0248fbbf999d0fd3ca2aa5ba515ab78703d129 (diff)
objtool: Add option to trace function validation
Add an option to trace and have information during the validation of specified functions. Functions are specified with the --trace option which can be a single function name (e.g. --trace foo to trace the function with the name "foo"), or a shell wildcard pattern (e.g. --trace foo* to trace all functions with a name starting with "foo"). Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://patch.msgid.link/20251121095340.464045-11-alexandre.chartre@oracle.com
Diffstat (limited to 'tools/objtool/include')
-rw-r--r--tools/objtool/include/objtool/builtin.h1
-rw-r--r--tools/objtool/include/objtool/check.h6
-rw-r--r--tools/objtool/include/objtool/disas.h11
-rw-r--r--tools/objtool/include/objtool/trace.h68
-rw-r--r--tools/objtool/include/objtool/warn.h1
5 files changed, 86 insertions, 1 deletions
diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index bb0b25eb08ba..991365c10f0e 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -41,6 +41,7 @@ struct opts {
const char *output;
bool sec_address;
bool stats;
+ const char *trace;
bool verbose;
bool werror;
};
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
index f96aabd7d54d..fde958683485 100644
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -66,7 +66,8 @@ struct instruction {
visited : 4,
no_reloc : 1,
hole : 1,
- fake : 1;
+ fake : 1,
+ trace : 1;
/* 9 bit hole */
struct alt_group *alt_group;
@@ -143,4 +144,7 @@ struct instruction *next_insn_same_sec(struct objtool_file *file, struct instruc
const char *objtool_disas_insn(struct instruction *insn);
+extern size_t sym_name_max_len;
+extern struct disas_context *objtool_disas_ctx;
+
#endif /* _CHECK_H */
diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/objtool/disas.h
index 1aee1fbe0bb9..5db75d06f219 100644
--- a/tools/objtool/include/objtool/disas.h
+++ b/tools/objtool/include/objtool/disas.h
@@ -19,6 +19,11 @@ int disas_info_init(struct disassemble_info *dinfo,
const char *options);
size_t disas_insn(struct disas_context *dctx, struct instruction *insn);
char *disas_result(struct disas_context *dctx);
+void disas_print_info(FILE *stream, struct instruction *insn, int depth,
+ const char *format, ...);
+void disas_print_insn(FILE *stream, struct disas_context *dctx,
+ struct instruction *insn, int depth,
+ const char *format, ...);
#else /* DISAS */
@@ -51,6 +56,12 @@ static inline char *disas_result(struct disas_context *dctx)
return NULL;
}
+static inline void disas_print_info(FILE *stream, struct instruction *insn,
+ int depth, const char *format, ...) {}
+static inline void disas_print_insn(FILE *stream, struct disas_context *dctx,
+ struct instruction *insn, int depth,
+ const char *format, ...) {}
+
#endif /* DISAS */
#endif /* _DISAS_H */
diff --git a/tools/objtool/include/objtool/trace.h b/tools/objtool/include/objtool/trace.h
new file mode 100644
index 000000000000..3f3c830ed114
--- /dev/null
+++ b/tools/objtool/include/objtool/trace.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#ifndef _TRACE_H
+#define _TRACE_H
+
+#include <objtool/check.h>
+#include <objtool/disas.h>
+
+#ifdef DISAS
+
+extern bool trace;
+extern int trace_depth;
+
+#define TRACE(fmt, ...) \
+({ if (trace) \
+ fprintf(stderr, fmt, ##__VA_ARGS__); \
+})
+
+#define TRACE_INSN(insn, fmt, ...) \
+({ \
+ if (trace) { \
+ disas_print_insn(stderr, objtool_disas_ctx, \
+ insn, trace_depth - 1, \
+ fmt, ##__VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ insn->trace = 1; \
+ } \
+})
+
+static inline void trace_enable(void)
+{
+ trace = true;
+ trace_depth = 0;
+}
+
+static inline void trace_disable(void)
+{
+ trace = false;
+}
+
+static inline void trace_depth_inc(void)
+{
+ if (trace)
+ trace_depth++;
+}
+
+static inline void trace_depth_dec(void)
+{
+ if (trace)
+ trace_depth--;
+}
+
+#else /* DISAS */
+
+#define TRACE(fmt, ...) ({})
+#define TRACE_INSN(insn, fmt, ...) ({})
+
+static inline void trace_enable(void) {}
+static inline void trace_disable(void) {}
+static inline void trace_depth_inc(void) {}
+static inline void trace_depth_dec(void) {}
+
+#endif
+
+#endif /* _TRACE_H */
diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h
index f32abc7b1be1..25ff7942b4d5 100644
--- a/tools/objtool/include/objtool/warn.h
+++ b/tools/objtool/include/objtool/warn.h
@@ -97,6 +97,7 @@ static inline char *offstr(struct section *sec, unsigned long offset)
_len = (_len < 50) ? 50 - _len : 0; \
WARN(" %s: " format " %*s%s", _str, ##__VA_ARGS__, _len, "", _istr); \
free(_str); \
+ __insn->trace = 1; \
} \
})