diff options
| author | Alexandre Chartre <alexandre.chartre@oracle.com> | 2025-11-21 10:53:24 +0100 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2025-11-21 15:30:11 +0100 |
| commit | 9b580accac003767a461bf52d738ad1ab4e8ccfa (patch) | |
| tree | ede7270a0a23e71e5291886cb659438949607268 | |
| parent | d490aa21973fe66ec35ad825c19f88ac7f7abb27 (diff) | |
objtool: Add functions to better name alternatives
Add the disas_alt_name() and disas_alt_type_name() to provide a
name and a type name for an alternative. This will be used to
better name alternatives when tracing their execution.
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-15-alexandre.chartre@oracle.com
| -rw-r--r-- | tools/objtool/disas.c | 72 | ||||
| -rw-r--r-- | tools/objtool/include/objtool/disas.h | 12 |
2 files changed, 84 insertions, 0 deletions
diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 0ca6e6c8559f..b53be240825d 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -3,6 +3,8 @@ * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com> */ +#define _GNU_SOURCE + #include <objtool/arch.h> #include <objtool/check.h> #include <objtool/disas.h> @@ -451,6 +453,76 @@ size_t disas_insn(struct disas_context *dctx, struct instruction *insn) } /* + * Provide a name for the type of alternatives present at the + * specified instruction. + * + * An instruction can have alternatives with different types, for + * example alternative instructions and an exception table. In that + * case the name for the alternative instructions type is used. + * + * Return NULL if the instruction as no alternative. + */ +const char *disas_alt_type_name(struct instruction *insn) +{ + struct alternative *alt; + const char *name; + + name = NULL; + for (alt = insn->alts; alt; alt = alt->next) { + if (alt->type == ALT_TYPE_INSTRUCTIONS) { + name = "alternative"; + break; + } + + switch (alt->type) { + case ALT_TYPE_EX_TABLE: + name = "ex_table"; + break; + case ALT_TYPE_JUMP_TABLE: + name = "jump_table"; + break; + default: + name = "unknown"; + break; + } + } + + return name; +} + +/* + * Provide a name for an alternative. + */ +char *disas_alt_name(struct alternative *alt) +{ + char *str = NULL; + + switch (alt->type) { + + case ALT_TYPE_EX_TABLE: + str = strdup("EXCEPTION"); + break; + + case ALT_TYPE_JUMP_TABLE: + str = strdup("JUMP"); + break; + + case ALT_TYPE_INSTRUCTIONS: + /* + * This is a non-default group alternative. Create a unique + * name using the offset of the first original and alternative + * instructions. + */ + asprintf(&str, "ALTERNATIVE %lx.%lx", + alt->insn->alt_group->orig_group->first_insn->offset, + alt->insn->alt_group->first_insn->offset); + break; + } + + return str; +} + +/* * Disassemble a function. */ static void disas_func(struct disas_context *dctx, struct symbol *func) diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/objtool/disas.h index 5db75d06f219..8959d4c45562 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -6,6 +6,7 @@ #ifndef _DISAS_H #define _DISAS_H +struct alternative; struct disas_context; struct disassemble_info; @@ -24,6 +25,8 @@ void disas_print_info(FILE *stream, struct instruction *insn, int depth, void disas_print_insn(FILE *stream, struct disas_context *dctx, struct instruction *insn, int depth, const char *format, ...); +char *disas_alt_name(struct alternative *alt); +const char *disas_alt_type_name(struct instruction *insn); #else /* DISAS */ @@ -61,6 +64,15 @@ static inline void disas_print_info(FILE *stream, struct instruction *insn, static inline void disas_print_insn(FILE *stream, struct disas_context *dctx, struct instruction *insn, int depth, const char *format, ...) {} +static inline char *disas_alt_name(struct alternative *alt) +{ + return NULL; +} + +static inline const char *disas_alt_type_name(struct instruction *insn) +{ + return NULL; +} #endif /* DISAS */ |
