From: Alexandre Chartre Date: Fri, 21 Nov 2025 09:53:39 +0000 (+0100) Subject: objtool: Add wide output for disassembly X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aff95e0d4e277c53fa274f4a5b6854849f3fc84d;p=thirdparty%2Flinux.git objtool: Add wide output for disassembly Add the --wide option to provide a wide output when disassembling. With this option, the disassembly of alternatives is displayed side-by-side instead of one above the other. Signed-off-by: Alexandre Chartre Signed-off-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://patch.msgid.link/20251121095340.464045-30-alexandre.chartre@oracle.com --- diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index a0371312fe55a..b780df5137152 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -107,6 +107,7 @@ static const struct option check_options[] = { OPT_STRING(0, "trace", &opts.trace, "func", "trace function validation"), OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"), + OPT_BOOLEAN(0, "wide", &opts.wide, "wide output"), OPT_END(), }; diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index a4f905eac4e63..f04bc14bef39e 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -856,6 +856,95 @@ static int disas_alt_default(struct disas_context *dctx, struct disas_alt *dalt) return 1; } +/* + * For each alternative, if there is an instruction at the specified + * offset then print this instruction, otherwise print a blank entry. + * The offset is an offset from the start of the alternative. + * + * Return the offset for the next instructions to print, or -1 if all + * instructions have been printed. + */ +static int disas_alt_print_insn(struct disas_alt *dalts, int alt_count, + int insn_count, int offset) +{ + struct disas_alt *dalt; + int offset_next; + char *str; + int i, j; + + offset_next = -1; + + for (i = 0; i < alt_count; i++) { + dalt = &dalts[i]; + j = dalt->insn_idx; + if (j == -1) { + printf("| %-*s ", dalt->width, ""); + continue; + } + + if (dalt->insn[j].offset == offset) { + str = dalt->insn[j].str; + printf("| %-*s ", dalt->width, str ?: ""); + if (++j < insn_count) { + dalt->insn_idx = j; + } else { + dalt->insn_idx = -1; + continue; + } + } else { + printf("| %-*s ", dalt->width, ""); + } + + if (dalt->insn[j].offset > 0 && + (offset_next == -1 || + (dalt->insn[j].offset < offset_next))) + offset_next = dalt->insn[j].offset; + } + printf("\n"); + + return offset_next; +} + +/* + * Print all alternatives side-by-side. + */ +static void disas_alt_print_wide(char *alt_name, struct disas_alt *dalts, int alt_count, + int insn_count) +{ + struct instruction *orig_insn; + int offset_next; + int offset; + int i; + + orig_insn = dalts[0].orig_insn; + + /* + * Print an header with the name of each alternative. + */ + disas_print_info(stdout, orig_insn, -2, NULL); + + if (strlen(alt_name) > dalts[0].width) + dalts[0].width = strlen(alt_name); + printf("| %-*s ", dalts[0].width, alt_name); + + for (i = 1; i < alt_count; i++) + printf("| %-*s ", dalts[i].width, dalts[i].name); + + printf("\n"); + + /* + * Print instructions for each alternative. + */ + offset_next = 0; + do { + offset = offset_next; + disas_print(stdout, orig_insn->sec, orig_insn->offset + offset, + -2, NULL); + offset_next = disas_alt_print_insn(dalts, alt_count, insn_count, + offset); + } while (offset_next > offset); +} + /* * Print all alternatives one above the other. */ @@ -993,7 +1082,11 @@ static void *disas_alt(struct disas_context *dctx, /* * Print default and non-default alternatives. */ - disas_alt_print_compact(alt_name, dalts, alt_count, insn_count); + + if (opts.wide) + disas_alt_print_wide(alt_name, dalts, alt_count, insn_count); + else + disas_alt_print_compact(alt_name, dalts, alt_count, insn_count); last_insn = orig_insn->alt_group ? orig_insn->alt_group->last_insn : orig_insn; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index e3af664864f30..b9e229ed4dc05 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -45,6 +45,7 @@ struct opts { const char *trace; bool verbose; bool werror; + bool wide; }; extern struct opts opts;