Skip to content

Commit aff95e0

Browse files
achartrePeter Zijlstra
authored andcommitted
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
1 parent 07d70b2 commit aff95e0

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

tools/objtool/builtin-check.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static const struct option check_options[] = {
107107
OPT_STRING(0, "trace", &opts.trace, "func", "trace function validation"),
108108
OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"),
109109
OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"),
110+
OPT_BOOLEAN(0, "wide", &opts.wide, "wide output"),
110111

111112
OPT_END(),
112113
};

tools/objtool/disas.c

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,95 @@ static int disas_alt_default(struct disas_context *dctx, struct disas_alt *dalt)
856856
return 1;
857857
}
858858

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+
859948
/*
860949
* Print all alternatives one above the other.
861950
*/
@@ -993,7 +1082,11 @@ static void *disas_alt(struct disas_context *dctx,
9931082
/*
9941083
* Print default and non-default alternatives.
9951084
*/
996-
disas_alt_print_compact(alt_name, dalts, alt_count, insn_count);
1085+
1086+
if (opts.wide)
1087+
disas_alt_print_wide(alt_name, dalts, alt_count, insn_count);
1088+
else
1089+
disas_alt_print_compact(alt_name, dalts, alt_count, insn_count);
9971090

9981091
last_insn = orig_insn->alt_group ? orig_insn->alt_group->last_insn :
9991092
orig_insn;

tools/objtool/include/objtool/builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct opts {
4545
const char *trace;
4646
bool verbose;
4747
bool werror;
48+
bool wide;
4849
};
4950

5051
extern struct opts opts;

0 commit comments

Comments
 (0)