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

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 <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-30-alexandre.chartre@oracle.com

authored by

Alexandre Chartre and committed by
Peter Zijlstra
aff95e0d 07d70b27

+96 -1
+1
tools/objtool/builtin-check.c
··· 107 107 OPT_STRING(0, "trace", &opts.trace, "func", "trace function validation"), 108 108 OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), 109 109 OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"), 110 + OPT_BOOLEAN(0, "wide", &opts.wide, "wide output"), 110 111 111 112 OPT_END(), 112 113 };
+94 -1
tools/objtool/disas.c
··· 857 857 } 858 858 859 859 /* 860 + * For each alternative, if there is an instruction at the specified 861 + * offset then print this instruction, otherwise print a blank entry. 862 + * The offset is an offset from the start of the alternative. 863 + * 864 + * Return the offset for the next instructions to print, or -1 if all 865 + * instructions have been printed. 866 + */ 867 + static int disas_alt_print_insn(struct disas_alt *dalts, int alt_count, 868 + int insn_count, int offset) 869 + { 870 + struct disas_alt *dalt; 871 + int offset_next; 872 + char *str; 873 + int i, j; 874 + 875 + offset_next = -1; 876 + 877 + for (i = 0; i < alt_count; i++) { 878 + dalt = &dalts[i]; 879 + j = dalt->insn_idx; 880 + if (j == -1) { 881 + printf("| %-*s ", dalt->width, ""); 882 + continue; 883 + } 884 + 885 + if (dalt->insn[j].offset == offset) { 886 + str = dalt->insn[j].str; 887 + printf("| %-*s ", dalt->width, str ?: ""); 888 + if (++j < insn_count) { 889 + dalt->insn_idx = j; 890 + } else { 891 + dalt->insn_idx = -1; 892 + continue; 893 + } 894 + } else { 895 + printf("| %-*s ", dalt->width, ""); 896 + } 897 + 898 + if (dalt->insn[j].offset > 0 && 899 + (offset_next == -1 || 900 + (dalt->insn[j].offset < offset_next))) 901 + offset_next = dalt->insn[j].offset; 902 + } 903 + printf("\n"); 904 + 905 + return offset_next; 906 + } 907 + 908 + /* 909 + * Print all alternatives side-by-side. 910 + */ 911 + static void disas_alt_print_wide(char *alt_name, struct disas_alt *dalts, int alt_count, 912 + int insn_count) 913 + { 914 + struct instruction *orig_insn; 915 + int offset_next; 916 + int offset; 917 + int i; 918 + 919 + orig_insn = dalts[0].orig_insn; 920 + 921 + /* 922 + * Print an header with the name of each alternative. 923 + */ 924 + disas_print_info(stdout, orig_insn, -2, NULL); 925 + 926 + if (strlen(alt_name) > dalts[0].width) 927 + dalts[0].width = strlen(alt_name); 928 + printf("| %-*s ", dalts[0].width, alt_name); 929 + 930 + for (i = 1; i < alt_count; i++) 931 + printf("| %-*s ", dalts[i].width, dalts[i].name); 932 + 933 + printf("\n"); 934 + 935 + /* 936 + * Print instructions for each alternative. 937 + */ 938 + offset_next = 0; 939 + do { 940 + offset = offset_next; 941 + disas_print(stdout, orig_insn->sec, orig_insn->offset + offset, 942 + -2, NULL); 943 + offset_next = disas_alt_print_insn(dalts, alt_count, insn_count, 944 + offset); 945 + } while (offset_next > offset); 946 + } 947 + 948 + /* 860 949 * Print all alternatives one above the other. 861 950 */ 862 951 static void disas_alt_print_compact(char *alt_name, struct disas_alt *dalts, ··· 1082 993 /* 1083 994 * Print default and non-default alternatives. 1084 995 */ 1085 - disas_alt_print_compact(alt_name, dalts, alt_count, insn_count); 996 + 997 + if (opts.wide) 998 + disas_alt_print_wide(alt_name, dalts, alt_count, insn_count); 999 + else 1000 + disas_alt_print_compact(alt_name, dalts, alt_count, insn_count); 1086 1001 1087 1002 last_insn = orig_insn->alt_group ? orig_insn->alt_group->last_insn : 1088 1003 orig_insn;
+1
tools/objtool/include/objtool/builtin.h
··· 45 45 const char *trace; 46 46 bool verbose; 47 47 bool werror; 48 + bool wide; 48 49 }; 49 50 50 51 extern struct opts opts;