When an instruction warning (WARN_INSN) or backtrace (BT_INSN) is issued, disassemble the instruction to provide more context.
Showing the changes to tools/objtool/include/objtool (3 of 5 files). Show all
Unified · Split
| @@ -141,4 +141,6 @@ struct instruction *next_insn_same_sec(struct objtool_file *file, struct instruc · 140 unmodified lines | ||
| 141 | 141 | insn && insn->offset < sym->offset + sym->len; \ |
| 142 | 142 | insn = next_insn_same_sec(file, insn)) |
| 143 | 143 | |
| 144 | +const char *objtool_disas_insn(struct instruction *insn); | |
| 145 | + | |
| 144 | 146 | #endif /* _CHECK_H */ |
| @@ -17,6 +17,8 @@ void disas_warned_funcs(struct disas_context *dctx); · 16 unmodified lines | ||
| 17 | 17 | int disas_info_init(struct disassemble_info *dinfo, |
| 18 | 18 | int arch, int mach32, int mach64, |
| 19 | 19 | const char *options); |
| 20 | +size_t disas_insn(struct disas_context *dctx, struct instruction *insn); | |
| 21 | +char *disas_result(struct disas_context *dctx); | |
| 20 | 22 | |
| 21 | 23 | #else /* DISAS */ |
| 22 | 24 | |
| @@ -38,6 +40,17 @@ static inline int disas_info_init(struct disassemble_info *dinfo, · 15 unmodified lines | ||
| 38 | 40 | return -1; |
| 39 | 41 | } |
| 40 | 42 | |
| 43 | +static inline size_t disas_insn(struct disas_context *dctx, | |
| 44 | + struct instruction *insn) | |
| 45 | +{ | |
| 46 | + return -1; | |
| 47 | +} | |
| 48 | + | |
| 49 | +static inline char *disas_result(struct disas_context *dctx) | |
| 50 | +{ | |
| 51 | + return NULL; | |
| 52 | +} | |
| 53 | + | |
| 41 | 54 | #endif /* DISAS */ |
| 42 | 55 | |
| 43 | 56 | #endif /* _DISAS_H */ |
| @@ -77,9 +77,11 @@ static inline char *offstr(struct section *sec, unsigned long offset) · 76 unmodified lines | ||
| 77 | 77 | #define WARN_INSN(insn, format, ...) \ |
| 78 | 78 | ({ \ |
| 79 | 79 | struct instruction *_insn = (insn); \ |
| 80 | − if (!_insn->sym || !_insn->sym->warned) \ | |
| 80 | + if (!_insn->sym || !_insn->sym->warned) { \ | |
| 81 | 81 | WARN_FUNC(_insn->sec, _insn->offset, format, \ |
| 82 | 82 | ##__VA_ARGS__); \ |
| 83 | + BT_INSN(_insn, ""); \ | |
| 84 | + } \ | |
| 83 | 85 | if (_insn->sym) \ |
| 84 | 86 | _insn->sym->warned = 1; \ |
| 85 | 87 | }) |
| @@ -87,10 +89,14 @@ static inline char *offstr(struct section *sec, unsigned long offset) · 1 unmodified line | ||
| 87 | 89 | #define BT_INSN(insn, format, ...) \ |
| 88 | 90 | ({ \ |
| 89 | 91 | if (opts.verbose || opts.backtrace) { \ |
| 90 | − struct instruction *_insn = (insn); \ | |
| 91 | − char *_str = offstr(_insn->sec, _insn->offset); \ | |
| 92 | − WARN(" %s: " format, _str, ##__VA_ARGS__); \ | |
| 93 | − free(_str); \ | |
| 92 | + struct instruction *__insn = (insn); \ | |
| 93 | + char *_str = offstr(__insn->sec, __insn->offset); \ | |
| 94 | + const char *_istr = objtool_disas_insn(__insn); \ | |
| 95 | + int _len; \ | |
| 96 | + _len = snprintf(NULL, 0, " %s: " format, _str, ##__VA_ARGS__); \ | |
| 97 | + _len = (_len < 50) ? 50 - _len : 0; \ | |
| 98 | + WARN(" %s: " format " %*s%s", _str, ##__VA_ARGS__, _len, "", _istr); \ | |
| 99 | + free(_str); \ | |
| 94 | 100 | } \ |
| 95 | 101 | }) |
| 96 | 102 | |