diff options
| -rw-r--r-- | tools/objtool/disas.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index ae69bef2eb37..6083a64f6ae4 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -47,7 +47,11 @@ struct disas_alt { struct alternative *alt; /* alternative or NULL if default code */ char *name; /* name for this alternative */ int width; /* formatting width */ - char *insn[DISAS_ALT_INSN_MAX]; /* alternative instructions */ + struct { + char *str; /* instruction string */ + int offset; /* instruction offset */ + } insn[DISAS_ALT_INSN_MAX]; /* alternative instructions */ + int insn_idx; /* index of the next instruction to print */ }; #define DALT_DEFAULT(dalt) (!(dalt)->alt) @@ -361,10 +365,9 @@ char *disas_result(struct disas_context *dctx) disas_print_insn(stdout, dctx, insn, depth, "\n") /* - * Print a message in the instruction flow. If insn is not NULL then - * the instruction address is printed in addition of the message, - * otherwise only the message is printed. In all cases, the instruction - * itself is not printed. + * Print a message in the instruction flow. If sec is not NULL then the + * address at the section offset is printed in addition of the message, + * otherwise only the message is printed. */ static int disas_vprint(FILE *stream, struct section *sec, unsigned long offset, int depth, const char *format, va_list ap) @@ -607,6 +610,7 @@ static int disas_alt_init(struct disas_alt *dalt, { dalt->orig_insn = orig_insn; dalt->alt = alt; + dalt->insn_idx = 0; dalt->name = alt ? disas_alt_name(alt) : strdup("DEFAULT"); if (!dalt->name) return -1; @@ -615,7 +619,8 @@ static int disas_alt_init(struct disas_alt *dalt, return 0; } -static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str) +static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str, + int offset) { int len; @@ -626,7 +631,8 @@ static int disas_alt_add_insn(struct disas_alt *dalt, int index, char *insn_str) } len = strlen(insn_str); - dalt->insn[index] = insn_str; + dalt->insn[index].str = insn_str; + dalt->insn[index].offset = offset; if (len > dalt->width) dalt->width = len; @@ -641,12 +647,14 @@ static int disas_alt_group(struct disas_context *dctx, struct disas_alt *dalt) { struct objtool_file *file; struct instruction *insn; + int offset; char *str; int count; int err; file = dctx->file; count = 0; + offset = 0; alt_for_each_insn(file, DALT_GROUP(dalt), insn) { @@ -655,9 +663,10 @@ static int disas_alt_group(struct disas_context *dctx, struct disas_alt *dalt) if (!str) return -1; - err = disas_alt_add_insn(dalt, count, str); + err = disas_alt_add_insn(dalt, count, str, offset); if (err) break; + offset += insn->len; count++; } @@ -685,7 +694,7 @@ static int disas_alt_default(struct disas_context *dctx, struct disas_alt *dalt) str = strdup(disas_result(dctx)); if (!str) return -1; - err = disas_alt_add_insn(dalt, 0, str); + err = disas_alt_add_insn(dalt, 0, str, 0); if (err) return -1; @@ -710,9 +719,11 @@ static void disas_alt_print_compact(char *alt_name, struct disas_alt *dalts, for (i = 0; i < alt_count; i++) { printf("%*s= %s\n", len, "", dalts[i].name); for (j = 0; j < insn_count; j++) { - if (!dalts[i].insn[j]) + if (!dalts[i].insn[j].str) break; - printf("%*s| %s\n", len, "", dalts[i].insn[j]); + disas_print(stdout, orig_insn->sec, + orig_insn->offset + dalts[i].insn[j].offset, 0, + "| %s\n", dalts[i].insn[j].str); } printf("%*s|\n", len, ""); } @@ -811,7 +822,7 @@ done: for (i = 0; i < alt_count; i++) { free(dalts[i].name); for (j = 0; j < insn_count; j++) - free(dalts[i].insn[j]); + free(dalts[i].insn[j].str); } free(alt_name); |
