mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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
This commit is contained in:
committed by
Peter Zijlstra
parent
d490aa2197
commit
9b580accac
@@ -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>
|
||||
@@ -450,6 +452,76 @@ size_t disas_insn(struct disas_context *dctx, struct instruction *insn)
|
||||
return disasm(insn->offset, &dctx->info);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user