Skip to content

Commit 15e7ad8

Browse files
achartrePeter Zijlstra
authored andcommitted
objtool: Print addresses with alternative instructions
All alternatives are disassemble side-by-side when using the --disas option. However the address of each instruction is not printed because instructions from different alternatives are not necessarily aligned. Change this behavior to print the address of each instruction. Spaces will appear between instructions from the same alternative when instructions from different alternatives do not have the same alignment. 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-22-alexandre.chartre@oracle.com
1 parent a4f1599 commit 15e7ad8

1 file changed

Lines changed: 23 additions & 12 deletions

File tree

tools/objtool/disas.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ struct disas_alt {
4747
struct alternative *alt; /* alternative or NULL if default code */
4848
char *name; /* name for this alternative */
4949
int width; /* formatting width */
50-
char *insn[DISAS_ALT_INSN_MAX]; /* alternative instructions */
50+
struct {
51+
char *str; /* instruction string */
52+
int offset; /* instruction offset */
53+
} insn[DISAS_ALT_INSN_MAX]; /* alternative instructions */
54+
int insn_idx; /* index of the next instruction to print */
5155
};
5256

5357
#define DALT_DEFAULT(dalt) (!(dalt)->alt)
@@ -361,10 +365,9 @@ char *disas_result(struct disas_context *dctx)
361365
disas_print_insn(stdout, dctx, insn, depth, "\n")
362366

363367
/*
364-
* Print a message in the instruction flow. If insn is not NULL then
365-
* the instruction address is printed in addition of the message,
366-
* otherwise only the message is printed. In all cases, the instruction
367-
* itself is not printed.
368+
* Print a message in the instruction flow. If sec is not NULL then the
369+
* address at the section offset is printed in addition of the message,
370+
* otherwise only the message is printed.
368371
*/
369372
static int disas_vprint(FILE *stream, struct section *sec, unsigned long offset,
370373
int depth, const char *format, va_list ap)
@@ -607,6 +610,7 @@ static int disas_alt_init(struct disas_alt *dalt,
607610
{
608611
dalt->orig_insn = orig_insn;
609612
dalt->alt = alt;
613+
dalt->insn_idx = 0;
610614
dalt->name = alt ? disas_alt_name(alt) : strdup("DEFAULT");
611615
if (!dalt->name)
612616
return -1;
@@ -615,7 +619,8 @@ static int disas_alt_init(struct disas_alt *dalt,
615619
return 0;
616620
}
617621

618-
static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str)
622+
static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str,
623+
int offset)
619624
{
620625
int len;
621626

@@ -626,7 +631,8 @@ static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str)
626631
}
627632

628633
len = strlen(insn_str);
629-
dalt->insn[index] = insn_str;
634+
dalt->insn[index].str = insn_str;
635+
dalt->insn[index].offset = offset;
630636
if (len > dalt->width)
631637
dalt->width = len;
632638

@@ -641,12 +647,14 @@ static int disas_alt_group(struct disas_context *dctx, struct disas_alt *dalt)
641647
{
642648
struct objtool_file *file;
643649
struct instruction *insn;
650+
int offset;
644651
char *str;
645652
int count;
646653
int err;
647654

648655
file = dctx->file;
649656
count = 0;
657+
offset = 0;
650658

651659
alt_for_each_insn(file, DALT_GROUP(dalt), insn) {
652660

@@ -655,9 +663,10 @@ static int disas_alt_group(struct disas_context *dctx, struct disas_alt *dalt)
655663
if (!str)
656664
return -1;
657665

658-
err = disas_alt_add_insn(dalt, count, str);
666+
err = disas_alt_add_insn(dalt, count, str, offset);
659667
if (err)
660668
break;
669+
offset += insn->len;
661670
count++;
662671
}
663672

@@ -685,7 +694,7 @@ static int disas_alt_default(struct disas_context *dctx, struct disas_alt *dalt)
685694
str = strdup(disas_result(dctx));
686695
if (!str)
687696
return -1;
688-
err = disas_alt_add_insn(dalt, 0, str);
697+
err = disas_alt_add_insn(dalt, 0, str, 0);
689698
if (err)
690699
return -1;
691700

@@ -710,9 +719,11 @@ static void disas_alt_print_compact(char *alt_name, struct disas_alt *dalts,
710719
for (i = 0; i < alt_count; i++) {
711720
printf("%*s= %s\n", len, "", dalts[i].name);
712721
for (j = 0; j < insn_count; j++) {
713-
if (!dalts[i].insn[j])
722+
if (!dalts[i].insn[j].str)
714723
break;
715-
printf("%*s| %s\n", len, "", dalts[i].insn[j]);
724+
disas_print(stdout, orig_insn->sec,
725+
orig_insn->offset + dalts[i].insn[j].offset, 0,
726+
"| %s\n", dalts[i].insn[j].str);
716727
}
717728
printf("%*s|\n", len, "");
718729
}
@@ -811,7 +822,7 @@ static void *disas_alt(struct disas_context *dctx,
811822
for (i = 0; i < alt_count; i++) {
812823
free(dalts[i].name);
813824
for (j = 0; j < insn_count; j++)
814-
free(dalts[i].insn[j]);
825+
free(dalts[i].insn[j].str);
815826
}
816827

817828
free(alt_name);

0 commit comments

Comments
 (0)