]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
objtool: Identify the different types of alternatives
authorAlexandre Chartre <alexandre.chartre@oracle.com>
Fri, 21 Nov 2025 09:53:23 +0000 (10:53 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Fri, 21 Nov 2025 14:30:11 +0000 (15:30 +0100)
Alternative code, including jump table and exception table, is represented
with the same struct alternative structure. But there is no obvious way to
identify whether the struct represents alternative instructions, a jump
table or an exception table.

So add a type to struct alternative to clearly identify the type of
alternative.

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-14-alexandre.chartre@oracle.com
tools/objtool/check.c
tools/objtool/include/objtool/check.h

index a02f8db75827f4279361b36dec2f7a27928834ea..93aaa4b5dce0eac582387287f3b67d9dac7d74ac 100644 (file)
 #include <linux/static_call_types.h>
 #include <linux/string.h>
 
-struct alternative {
-       struct alternative *next;
-       struct instruction *insn;
-};
-
 static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
 
 static struct cfi_init_state initial_func_cfi;
@@ -1924,6 +1919,7 @@ static int add_special_section_alts(struct objtool_file *file)
        struct list_head special_alts;
        struct instruction *orig_insn, *new_insn;
        struct special_alt *special_alt, *tmp;
+       enum alternative_type alt_type;
        struct alternative *alt;
 
        if (special_get_alts(file->elf, &special_alts))
@@ -1959,9 +1955,15 @@ static int add_special_section_alts(struct objtool_file *file)
                        if (handle_group_alt(file, special_alt, orig_insn, &new_insn))
                                return -1;
 
+                       alt_type = ALT_TYPE_INSTRUCTIONS;
+
                } else if (special_alt->jump_or_nop) {
                        if (handle_jump_alt(file, special_alt, orig_insn, &new_insn))
                                return -1;
+
+                       alt_type = ALT_TYPE_JUMP_TABLE;
+               } else {
+                       alt_type = ALT_TYPE_EX_TABLE;
                }
 
                alt = calloc(1, sizeof(*alt));
@@ -1972,6 +1974,7 @@ static int add_special_section_alts(struct objtool_file *file)
 
                alt->insn = new_insn;
                alt->next = orig_insn->alts;
+               alt->type = alt_type;
                orig_insn->alts = alt;
 
                list_del(&special_alt->list);
index fde958683485f20d2f17c411cae244f5b4da2262..cbf4af58e29b251a52a69f11935411f90a898b0b 100644 (file)
@@ -38,6 +38,18 @@ struct alt_group {
        bool ignore;
 };
 
+enum alternative_type {
+       ALT_TYPE_INSTRUCTIONS,
+       ALT_TYPE_JUMP_TABLE,
+       ALT_TYPE_EX_TABLE,
+};
+
+struct alternative {
+       struct alternative *next;
+       struct instruction *insn;
+       enum alternative_type type;
+};
+
 #define INSN_CHUNK_BITS                8
 #define INSN_CHUNK_SIZE                (1 << INSN_CHUNK_BITS)
 #define INSN_CHUNK_MAX         (INSN_CHUNK_SIZE - 1)