History

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.

Alexandre Chartre committed 11 months ago

Commit 0bb080b1 parent d4e13c25 files · +58 −14Browse files

Unified · Split

5 files
  1. tools/objtool/check.c +30 −6
  2. tools/objtool/disas.c +2 −3
  3. tools/objtool/include/objtool/check.h +2 −0
  4. tools/objtool/include/objtool/disas.h +13 −0
  5. tools/objtool/include/objtool/warn.h +11 −5
tools/objtool/check.c+30−6
@@ -4792,11 +4792,34 @@ static void free_insns(struct objtool_file *file) · 4791 unmodified lines
4792 free(chunk->addr);4792 free(chunk->addr);
4793}4793}
4794 4794
4795static struct disas_context *objtool_disas_ctx;
4796
4797const char *objtool_disas_insn(struct instruction *insn)
4798{
4799 struct disas_context *dctx = objtool_disas_ctx;
4800
4801 if (!dctx)
4802 return "";
4803
4804 disas_insn(dctx, insn);
4805 return disas_result(dctx);
4806}
4807
4795int check(struct objtool_file *file)4808int check(struct objtool_file *file)
4796{4809{
4797 struct disas_context *disas_ctx;4810 struct disas_context *disas_ctx = NULL;
4798 int ret = 0, warnings = 0;4811 int ret = 0, warnings = 0;
4799 4812
4813 /*
4814 * If the verbose or backtrace option is used then we need a
4815 * disassembly context to disassemble instruction or function
4816 * on warning or backtrace.
4817 */
4818 if (opts.verbose || opts.backtrace) {
4819 disas_ctx = disas_context_create(file);
4820 objtool_disas_ctx = disas_ctx;
4821 }
4822
4800 arch_initial_func_cfi_state(&initial_func_cfi);4823 arch_initial_func_cfi_state(&initial_func_cfi);
4801 init_cfi_state(&init_cfi);4824 init_cfi_state(&init_cfi);
4802 init_cfi_state(&func_cfi);4825 init_cfi_state(&func_cfi);
@@ -4936,11 +4959,12 @@ out: · 133 unmodified lines
4936 if (opts.verbose) {4959 if (opts.verbose) {
4937 if (opts.werror && warnings)4960 if (opts.werror && warnings)
4938 WARN("%d warning(s) upgraded to errors", warnings);4961 WARN("%d warning(s) upgraded to errors", warnings);
4939 disas_ctx = disas_context_create(file);4962 disas_warned_funcs(disas_ctx);
4940 if (disas_ctx) {4963 }
4941 disas_warned_funcs(disas_ctx);4964
4942 disas_context_destroy(disas_ctx);4965 if (disas_ctx) {
4943 }4966 disas_context_destroy(disas_ctx);
4967 objtool_disas_ctx = NULL;
4944 }4968 }
4945 4969
4946 free_insns(file);4970 free_insns(file);
tools/objtool/disas.c+2−3
@@ -303,7 +303,7 @@ void disas_context_destroy(struct disas_context *dctx) · 302 unmodified lines
303 free(dctx);303 free(dctx);
304}304}
305 305
306static char *disas_result(struct disas_context *dctx)306char *disas_result(struct disas_context *dctx)
307{307{
308 return dctx->result;308 return dctx->result;
309}309}
@@ -311,8 +311,7 @@ static char *disas_result(struct disas_context *dctx) · 1 unmodified line
311/*311/*
312 * Disassemble a single instruction. Return the size of the instruction.312 * Disassemble a single instruction. Return the size of the instruction.
313 */313 */
314static size_t disas_insn(struct disas_context *dctx,314size_t disas_insn(struct disas_context *dctx, struct instruction *insn)
315 struct instruction *insn)
316{315{
317 disassembler_ftype disasm = dctx->disassembler;316 disassembler_ftype disasm = dctx->disassembler;
318 struct disassemble_info *dinfo = &dctx->info;317 struct disassemble_info *dinfo = &dctx->info;
tools/objtool/include/objtool/check.h+2−0
@@ -141,4 +141,6 @@ struct instruction *next_insn_same_sec(struct objtool_file *file, struct instruc · 140 unmodified lines
141 insn && insn->offset < sym->offset + sym->len; \141 insn && insn->offset < sym->offset + sym->len; \
142 insn = next_insn_same_sec(file, insn))142 insn = next_insn_same_sec(file, insn))
143 143
144const char *objtool_disas_insn(struct instruction *insn);
145
144#endif /* _CHECK_H */146#endif /* _CHECK_H */
tools/objtool/include/objtool/disas.h+13−0
@@ -17,6 +17,8 @@ void disas_warned_funcs(struct disas_context *dctx); · 16 unmodified lines
17int disas_info_init(struct disassemble_info *dinfo,17int disas_info_init(struct disassemble_info *dinfo,
18 int arch, int mach32, int mach64,18 int arch, int mach32, int mach64,
19 const char *options);19 const char *options);
20size_t disas_insn(struct disas_context *dctx, struct instruction *insn);
21char *disas_result(struct disas_context *dctx);
20 22
21#else /* DISAS */23#else /* DISAS */
22 24
@@ -38,6 +40,17 @@ static inline int disas_info_init(struct disassemble_info *dinfo, · 15 unmodified lines
38 return -1;40 return -1;
39}41}
40 42
43static inline size_t disas_insn(struct disas_context *dctx,
44 struct instruction *insn)
45{
46 return -1;
47}
48
49static inline char *disas_result(struct disas_context *dctx)
50{
51 return NULL;
52}
53
41#endif /* DISAS */54#endif /* DISAS */
42 55
43#endif /* _DISAS_H */56#endif /* _DISAS_H */
tools/objtool/include/objtool/warn.h+11−5
@@ -77,9 +77,11 @@ static inline char *offstr(struct section *sec, unsigned long offset) · 76 unmodified lines
77#define WARN_INSN(insn, format, ...) \77#define WARN_INSN(insn, format, ...) \
78({ \78({ \
79 struct instruction *_insn = (insn); \79 struct instruction *_insn = (insn); \
80 if (!_insn->sym || !_insn->sym->warned) \80 if (!_insn->sym || !_insn->sym->warned) { \
81 WARN_FUNC(_insn->sec, _insn->offset, format, \81 WARN_FUNC(_insn->sec, _insn->offset, format, \
82 ##__VA_ARGS__); \82 ##__VA_ARGS__); \
83 BT_INSN(_insn, ""); \
84 } \
83 if (_insn->sym) \85 if (_insn->sym) \
84 _insn->sym->warned = 1; \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#define BT_INSN(insn, format, ...) \89#define BT_INSN(insn, format, ...) \
88({ \90({ \
89 if (opts.verbose || opts.backtrace) { \91 if (opts.verbose || opts.backtrace) { \
90 struct instruction *_insn = (insn); \92 struct instruction *__insn = (insn); \
91 char *_str = offstr(_insn->sec, _insn->offset); \93 char *_str = offstr(__insn->sec, __insn->offset); \
92 WARN(" %s: " format, _str, ##__VA_ARGS__); \94 const char *_istr = objtool_disas_insn(__insn); \
93 free(_str); \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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t