[PATCH v6 14/30] objtool: Add functions to better name alternatives

Alexandre Chartre posted 30 patches 1 week, 3 days ago
[PATCH v6 14/30] objtool: Add functions to better name alternatives
Posted by Alexandre Chartre 1 week, 3 days ago
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>
---
 tools/objtool/disas.c                 | 72 +++++++++++++++++++++++++++
 tools/objtool/include/objtool/disas.h | 12 +++++
 2 files changed, 84 insertions(+)

diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c
index 0ca6e6c8559fd..b53be240825da 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>
@@ -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.
  */
diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/objtool/disas.h
index 5db75d06f2197..8959d4c455622 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 */
 
-- 
2.43.5
[tip: objtool/core] objtool: Add functions to better name alternatives
Posted by tip-bot2 for Alexandre Chartre 1 week ago
The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     9b580accac003767a461bf52d738ad1ab4e8ccfa
Gitweb:        https://git.kernel.org/tip/9b580accac003767a461bf52d738ad1ab4e8ccfa
Author:        Alexandre Chartre <alexandre.chartre@oracle.com>
AuthorDate:    Fri, 21 Nov 2025 10:53:24 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 21 Nov 2025 15:30:11 +01: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
---
 tools/objtool/disas.c                 | 72 ++++++++++++++++++++++++++-
 tools/objtool/include/objtool/disas.h | 12 ++++-
 2 files changed, 84 insertions(+)

diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c
index 0ca6e6c..b53be24 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 5db75d0..8959d4c 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 */