summaryrefslogtreecommitdiff
path: root/tools/objtool/include
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@kernel.org>2025-09-17 09:03:58 -0700
committerJosh Poimboeuf <jpoimboe@kernel.org>2025-10-14 14:50:18 -0700
commita3493b33384a01a1f0e38b420d1a4766aec903a6 (patch)
treeba6afc1289615358ad7c7d080e5bf0b99dc34e2b /tools/objtool/include
parent0d83da43b1e1c8ce19f2bb10f54a0fdf795364f7 (diff)
downloadlinux-a3493b33384a01a1f0e38b420d1a4766aec903a6.tar.gz
linux-a3493b33384a01a1f0e38b420d1a4766aec903a6.tar.bz2
linux-a3493b33384a01a1f0e38b420d1a4766aec903a6.zip
objtool/klp: Add --debug-checksum=<funcs> to show per-instruction checksums
Add a --debug-checksum=<funcs> option to the check subcommand to print the calculated checksum of each instruction in the given functions. This is useful for determining where two versions of a function begin to diverge. Acked-by: Petr Mladek <pmladek@suse.com> Tested-by: Joe Lawrence <joe.lawrence@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Diffstat (limited to 'tools/objtool/include')
-rw-r--r--tools/objtool/include/objtool/builtin.h1
-rw-r--r--tools/objtool/include/objtool/checksum.h1
-rw-r--r--tools/objtool/include/objtool/elf.h1
-rw-r--r--tools/objtool/include/objtool/warn.h19
4 files changed, 22 insertions, 0 deletions
diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index 338bdab6b9ad..cee9fc031877 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -32,6 +32,7 @@ struct opts {
/* options: */
bool backtrace;
bool backup;
+ const char *debug_checksum;
bool dryrun;
bool link;
bool mnop;
diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/include/objtool/checksum.h
index 927ca74b5c39..7fe21608722a 100644
--- a/tools/objtool/include/objtool/checksum.h
+++ b/tools/objtool/include/objtool/checksum.h
@@ -19,6 +19,7 @@ static inline void checksum_update(struct symbol *func,
const void *data, size_t size)
{
XXH3_64bits_update(func->csum.state, data, size);
+ dbg_checksum(func, insn, XXH3_64bits_digest(func->csum.state));
}
static inline void checksum_finish(struct symbol *func)
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index bc7d8a6167f8..a1f1762f89c4 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -82,6 +82,7 @@ struct symbol {
u8 nocfi : 1;
u8 cold : 1;
u8 prefix : 1;
+ u8 debug_checksum : 1;
struct list_head pv_target;
struct reloc *relocs;
struct section *group_sec;
diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h
index cb8fe846d9dd..29173a1368d7 100644
--- a/tools/objtool/include/objtool/warn.h
+++ b/tools/objtool/include/objtool/warn.h
@@ -102,4 +102,23 @@ static inline char *offstr(struct section *sec, unsigned long offset)
#define ERROR_FUNC(sec, offset, format, ...) __WARN_FUNC(ERROR_STR, sec, offset, format, ##__VA_ARGS__)
#define ERROR_INSN(insn, format, ...) WARN_FUNC(insn->sec, insn->offset, format, ##__VA_ARGS__)
+
+#define __dbg(format, ...) \
+ fprintf(stderr, \
+ "DEBUG: %s%s" format "\n", \
+ objname ?: "", \
+ objname ? ": " : "", \
+ ##__VA_ARGS__)
+
+#define dbg_checksum(func, insn, checksum) \
+({ \
+ if (unlikely(insn->sym && insn->sym->pfunc && \
+ insn->sym->pfunc->debug_checksum)) { \
+ char *insn_off = offstr(insn->sec, insn->offset); \
+ __dbg("checksum: %s %s %016lx", \
+ func->name, insn_off, checksum); \
+ free(insn_off); \
+ } \
+})
+
#endif /* _WARN_H */