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

objtool: Add verbose option for disassembling affected functions

When a warning is associated with a function, add an option to
disassemble that function.

This makes it easier for reporters to submit the information needed to
diagnose objtool warnings.

Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lore.kernel.org/r/dd0fe13428ede186f09c74059a8001f4adcea5fc.1681853186.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+88
+5
tools/objtool/Documentation/objtool.txt
··· 244 244 Objtool warnings 245 245 ---------------- 246 246 247 + NOTE: When requesting help with an objtool warning, please recreate with 248 + OBJTOOL_VERBOSE=1 (e.g., "make OBJTOOL_VERBOSE=1") and send the full 249 + output, including any disassembly below the warning, to the objtool 250 + maintainers. 251 + 247 252 For asm files, if you're getting an error which doesn't make sense, 248 253 first make sure that the affected code follows the above rules. 249 254
+5
tools/objtool/builtin-check.c
··· 93 93 OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"), 94 94 OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"), 95 95 OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), 96 + OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), 96 97 97 98 OPT_END(), 98 99 }; ··· 118 117 119 118 parse_options(envc, envv, check_options, env_usage, 0); 120 119 } 120 + 121 + env = getenv("OBJTOOL_VERBOSE"); 122 + if (env && !strcmp(env, "1")) 123 + opts.verbose = true; 121 124 122 125 argc = parse_options(argc, argv, check_options, usage, 0); 123 126 if (argc != 1)
+77
tools/objtool/check.c
··· 4530 4530 return warnings; 4531 4531 } 4532 4532 4533 + /* 'funcs' is a space-separated list of function names */ 4534 + static int disas_funcs(const char *funcs) 4535 + { 4536 + const char *objdump_str, *cross_compile; 4537 + int size, ret; 4538 + char *cmd; 4539 + 4540 + cross_compile = getenv("CROSS_COMPILE"); 4541 + 4542 + objdump_str = "%sobjdump -wdr %s | gawk -M -v _funcs='%s' '" 4543 + "BEGIN { split(_funcs, funcs); }" 4544 + "/^$/ { func_match = 0; }" 4545 + "/<.*>:/ { " 4546 + "f = gensub(/.*<(.*)>:/, \"\\\\1\", 1);" 4547 + "for (i in funcs) {" 4548 + "if (funcs[i] == f) {" 4549 + "func_match = 1;" 4550 + "base = strtonum(\"0x\" $1);" 4551 + "break;" 4552 + "}" 4553 + "}" 4554 + "}" 4555 + "{" 4556 + "if (func_match) {" 4557 + "addr = strtonum(\"0x\" $1);" 4558 + "printf(\"%%04x \", addr - base);" 4559 + "print;" 4560 + "}" 4561 + "}' 1>&2"; 4562 + 4563 + /* fake snprintf() to calculate the size */ 4564 + size = snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + 1; 4565 + if (size <= 0) { 4566 + WARN("objdump string size calculation failed"); 4567 + return -1; 4568 + } 4569 + 4570 + cmd = malloc(size); 4571 + 4572 + /* real snprintf() */ 4573 + snprintf(cmd, size, objdump_str, cross_compile, objname, funcs); 4574 + ret = system(cmd); 4575 + if (ret) { 4576 + WARN("disassembly failed: %d", ret); 4577 + return -1; 4578 + } 4579 + 4580 + return 0; 4581 + } 4582 + 4583 + static int disas_warned_funcs(struct objtool_file *file) 4584 + { 4585 + struct symbol *sym; 4586 + char *funcs = NULL, *tmp; 4587 + 4588 + for_each_sym(file, sym) { 4589 + if (sym->warned) { 4590 + if (!funcs) { 4591 + funcs = malloc(strlen(sym->name) + 1); 4592 + strcpy(funcs, sym->name); 4593 + } else { 4594 + tmp = malloc(strlen(funcs) + strlen(sym->name) + 2); 4595 + sprintf(tmp, "%s %s", funcs, sym->name); 4596 + free(funcs); 4597 + funcs = tmp; 4598 + } 4599 + } 4600 + } 4601 + 4602 + if (funcs) 4603 + disas_funcs(funcs); 4604 + 4605 + return 0; 4606 + } 4607 + 4533 4608 int check(struct objtool_file *file) 4534 4609 { 4535 4610 int ret, warnings = 0; ··· 4749 4674 warnings += ret; 4750 4675 } 4751 4676 4677 + if (opts.verbose) 4678 + disas_warned_funcs(file); 4752 4679 4753 4680 if (opts.stats) { 4754 4681 printf("nr_insns_visited: %ld\n", nr_insns_visited);
+1
tools/objtool/include/objtool/builtin.h
··· 37 37 bool no_unreachable; 38 38 bool sec_address; 39 39 bool stats; 40 + bool verbose; 40 41 }; 41 42 42 43 extern struct opts opts;