diff options
| author | Alexandre Chartre <alexandre.chartre@oracle.com> | 2025-11-21 10:53:17 +0100 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2025-11-21 15:30:08 +0100 |
| commit | 0bb080ba6469a573bc85122153d931334d10a173 (patch) | |
| tree | a5c158ee68e7bf24b55999c9ec58e1b9935f8606 /tools/objtool/include | |
| parent | d4e13c21497d0cde73694163908f89d7168c1243 (diff) | |
objtool: Disassemble instruction on warning or backtrace
When an instruction warning (WARN_INSN) or backtrace (BT_INSN) is issued,
disassemble the instruction to provide more context.
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-8-alexandre.chartre@oracle.com
Diffstat (limited to 'tools/objtool/include')
| -rw-r--r-- | tools/objtool/include/objtool/check.h | 2 | ||||
| -rw-r--r-- | tools/objtool/include/objtool/disas.h | 13 | ||||
| -rw-r--r-- | tools/objtool/include/objtool/warn.h | 16 |
3 files changed, 26 insertions, 5 deletions
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h index ad9c73504b12..f96aabd7d54d 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -141,4 +141,6 @@ struct instruction *next_insn_same_sec(struct objtool_file *file, struct instruc insn && insn->offset < sym->offset + sym->len; \ insn = next_insn_same_sec(file, insn)) +const char *objtool_disas_insn(struct instruction *insn); + #endif /* _CHECK_H */ diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/objtool/disas.h index 3ec3ce2e4e6f..1aee1fbe0bb9 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -17,6 +17,8 @@ void disas_warned_funcs(struct disas_context *dctx); int disas_info_init(struct disassemble_info *dinfo, int arch, int mach32, int mach64, const char *options); +size_t disas_insn(struct disas_context *dctx, struct instruction *insn); +char *disas_result(struct disas_context *dctx); #else /* DISAS */ @@ -38,6 +40,17 @@ static inline int disas_info_init(struct disassemble_info *dinfo, return -1; } +static inline size_t disas_insn(struct disas_context *dctx, + struct instruction *insn) +{ + return -1; +} + +static inline char *disas_result(struct disas_context *dctx) +{ + return NULL; +} + #endif /* DISAS */ #endif /* _DISAS_H */ diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h index a1e3927d8e7c..f32abc7b1be1 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -77,9 +77,11 @@ static inline char *offstr(struct section *sec, unsigned long offset) #define WARN_INSN(insn, format, ...) \ ({ \ struct instruction *_insn = (insn); \ - if (!_insn->sym || !_insn->sym->warned) \ + if (!_insn->sym || !_insn->sym->warned) { \ WARN_FUNC(_insn->sec, _insn->offset, format, \ ##__VA_ARGS__); \ + BT_INSN(_insn, ""); \ + } \ if (_insn->sym) \ _insn->sym->warned = 1; \ }) @@ -87,10 +89,14 @@ static inline char *offstr(struct section *sec, unsigned long offset) #define BT_INSN(insn, format, ...) \ ({ \ if (opts.verbose || opts.backtrace) { \ - struct instruction *_insn = (insn); \ - char *_str = offstr(_insn->sec, _insn->offset); \ - WARN(" %s: " format, _str, ##__VA_ARGS__); \ - free(_str); \ + struct instruction *__insn = (insn); \ + char *_str = offstr(__insn->sec, __insn->offset); \ + const char *_istr = objtool_disas_insn(__insn); \ + int _len; \ + _len = snprintf(NULL, 0, " %s: " format, _str, ##__VA_ARGS__); \ + _len = (_len < 50) ? 50 - _len : 0; \ + WARN(" %s: " format " %*s%s", _str, ##__VA_ARGS__, _len, "", _istr); \ + free(_str); \ } \ }) |
