Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Add the --disas=<function-pattern> action

Add the --disas=<function-pattern> actions to disassemble the specified
functions. The function pattern can be a single function name (e.g.
--disas foo to disassemble the function with the name "foo"), or a shell
wildcard pattern (e.g. --disas foo* to disassemble 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-18-alexandre.chartre@oracle.com

authored by

Alexandre Chartre and committed by
Peter Zijlstra
5f326c88 c3b7d044

+53 -17
+2
tools/objtool/builtin-check.c
··· 75 75 OPT_GROUP("Actions:"), 76 76 OPT_BOOLEAN(0, "checksum", &opts.checksum, "generate per-function checksums"), 77 77 OPT_BOOLEAN(0, "cfi", &opts.cfi, "annotate kernel control flow integrity (kCFI) function preambles"), 78 + OPT_STRING_OPTARG('d', "disas", &opts.disas, "function-pattern", "disassemble functions", "*"), 78 79 OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake", "patch toolchain bugs/limitations", parse_hacks), 79 80 OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), 80 81 OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), ··· 177 176 } 178 177 179 178 if (opts.checksum || 179 + opts.disas || 180 180 opts.hack_jump_label || 181 181 opts.hack_noinstr || 182 182 opts.ibt ||
+21 -17
tools/objtool/check.c
··· 2611 2611 * Must be before add_jump_destinations(), which depends on 'func' 2612 2612 * being set for alternatives, to enable proper sibling call detection. 2613 2613 */ 2614 - if (validate_branch_enabled() || opts.noinstr || opts.hack_jump_label) { 2614 + if (validate_branch_enabled() || opts.noinstr || opts.hack_jump_label || opts.disas) { 2615 2615 if (add_special_section_alts(file)) 2616 2616 return -1; 2617 2617 } ··· 4915 4915 int ret = 0, warnings = 0; 4916 4916 4917 4917 /* 4918 - * If the verbose or backtrace option is used then we need a 4919 - * disassembly context to disassemble instruction or function 4920 - * on warning or backtrace. 4918 + * Create a disassembly context if we might disassemble any 4919 + * instruction or function. 4921 4920 */ 4922 - if (opts.verbose || opts.backtrace || opts.trace) { 4921 + if (opts.verbose || opts.backtrace || opts.trace || opts.disas) { 4923 4922 disas_ctx = disas_context_create(file); 4924 - if (!disas_ctx) 4923 + if (!disas_ctx) { 4924 + opts.disas = false; 4925 4925 opts.trace = false; 4926 + } 4926 4927 objtool_disas_ctx = disas_ctx; 4927 4928 } 4928 4929 ··· 5055 5054 } 5056 5055 5057 5056 out: 5058 - if (!ret && !warnings) { 5059 - free_insns(file); 5060 - return 0; 5061 - } 5062 - 5063 - if (opts.werror && warnings) 5064 - ret = 1; 5065 - 5066 - if (opts.verbose) { 5057 + if (ret || warnings) { 5067 5058 if (opts.werror && warnings) 5068 - WARN("%d warning(s) upgraded to errors", warnings); 5069 - disas_warned_funcs(disas_ctx); 5059 + ret = 1; 5060 + 5061 + if (opts.verbose) { 5062 + if (opts.werror && warnings) 5063 + WARN("%d warning(s) upgraded to errors", warnings); 5064 + disas_warned_funcs(disas_ctx); 5065 + } 5070 5066 } 5067 + 5068 + if (opts.disas) 5069 + disas_funcs(disas_ctx); 5071 5070 5072 5071 if (disas_ctx) { 5073 5072 disas_context_destroy(disas_ctx); ··· 5075 5074 } 5076 5075 5077 5076 free_insns(file); 5077 + 5078 + if (!ret && !warnings) 5079 + return 0; 5078 5080 5079 5081 if (opts.backup && make_backup()) 5080 5082 return 1;
+27
tools/objtool/disas.c
··· 4 4 */ 5 5 6 6 #define _GNU_SOURCE 7 + #include <fnmatch.h> 7 8 8 9 #include <objtool/arch.h> 9 10 #include <objtool/check.h> ··· 555 554 for_each_sym(dctx->file->elf, sym) { 556 555 if (sym->warned) 557 556 disas_func(dctx, sym); 557 + } 558 + } 559 + 560 + void disas_funcs(struct disas_context *dctx) 561 + { 562 + bool disas_all = !strcmp(opts.disas, "*"); 563 + struct section *sec; 564 + struct symbol *sym; 565 + 566 + for_each_sec(dctx->file->elf, sec) { 567 + 568 + if (!(sec->sh.sh_flags & SHF_EXECINSTR)) 569 + continue; 570 + 571 + sec_for_each_sym(sec, sym) { 572 + /* 573 + * If the function had a warning and the verbose 574 + * option is used then the function was already 575 + * disassemble. 576 + */ 577 + if (opts.verbose && sym->warned) 578 + continue; 579 + 580 + if (disas_all || fnmatch(opts.disas, sym->name, 0) == 0) 581 + disas_func(dctx, sym); 582 + } 558 583 } 559 584 }
+1
tools/objtool/include/objtool/builtin.h
··· 28 28 bool static_call; 29 29 bool uaccess; 30 30 int prefix; 31 + const char *disas; 31 32 32 33 /* options: */ 33 34 bool backtrace;
+2
tools/objtool/include/objtool/disas.h
··· 15 15 struct disas_context *disas_context_create(struct objtool_file *file); 16 16 void disas_context_destroy(struct disas_context *dctx); 17 17 void disas_warned_funcs(struct disas_context *dctx); 18 + void disas_funcs(struct disas_context *dctx); 18 19 int disas_info_init(struct disassemble_info *dinfo, 19 20 int arch, int mach32, int mach64, 20 21 const char *options); ··· 41 40 42 41 static inline void disas_context_destroy(struct disas_context *dctx) {} 43 42 static inline void disas_warned_funcs(struct disas_context *dctx) {} 43 + static inline void disas_funcs(struct disas_context *dctx) {} 44 44 45 45 static inline int disas_info_init(struct disassemble_info *dinfo, 46 46 int arch, int mach32, int mach64,