]> www.infradead.org Git - linux.git/commitdiff
objtool: Generic annotation infrastructure
authorPeter Zijlstra <peterz@infradead.org>
Thu, 28 Nov 2024 09:38:52 +0000 (10:38 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 2 Dec 2024 11:01:41 +0000 (12:01 +0100)
Avoid endless .discard.foo sections for each annotation, create a
single .discard.annotate_insn section that takes an annotation type along
with the instruction.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
Link: https://lore.kernel.org/r/20241128094310.932794537@infradead.org
include/linux/objtool.h
tools/objtool/check.c

index b3b8d3dab52d5c5b43b390bb5a204226164c2796..d98531ecc68735ddb1414d261ddaba53509e948f 100644 (file)
        ".long 998b\n\t"                                                \
        ".popsection\n\t"
 
+#define ASM_ANNOTATE(type)                                             \
+       "911:\n\t"                                                      \
+       ".pushsection .discard.annotate_insn,\"M\",@progbits,8\n\t"     \
+       ".long 911b - .\n\t"                                            \
+       ".long " __stringify(type) "\n\t"                               \
+       ".popsection\n\t"
+
 #else /* __ASSEMBLY__ */
 
 /*
        .popsection
 .endm
 
+.macro ANNOTATE type:req
+.Lhere_\@:
+       .pushsection .discard.annotate_insn,"M",@progbits,8
+       .long   .Lhere_\@ - .
+       .long   \type
+       .popsection
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_OBJTOOL */
 #define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t"
 #define STACK_FRAME_NON_STANDARD(func)
 #define STACK_FRAME_NON_STANDARD_FP(func)
+#define ASM_ANNOTATE(type)
 #define ANNOTATE_NOENDBR
 #define ASM_REACHABLE
 #else
 .endm
 .macro REACHABLE
 .endm
+.macro ANNOTATE type:req
+.endm
 #endif
 
 #endif /* CONFIG_OBJTOOL */
index 4ce176ad411fb12a10101bbedbb6180275941b4b..b0efc8ee16d6d3a72500cc8d695c3325df08d8cb 100644 (file)
@@ -2373,6 +2373,49 @@ static int read_unwind_hints(struct objtool_file *file)
        return 0;
 }
 
+static int read_annotate(struct objtool_file *file, void (*func)(int type, struct instruction *insn))
+{
+       struct section *sec;
+       struct instruction *insn;
+       struct reloc *reloc;
+       int type;
+
+       sec = find_section_by_name(file->elf, ".discard.annotate_insn");
+       if (!sec)
+               return 0;
+
+       if (!sec->rsec)
+               return 0;
+
+       if (sec->sh.sh_entsize != 8) {
+               static bool warned = false;
+               if (!warned) {
+                       WARN("%s: dodgy linker, sh_entsize != 8", sec->name);
+                       warned = true;
+               }
+               sec->sh.sh_entsize = 8;
+       }
+
+       for_each_reloc(sec->rsec, reloc) {
+               type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
+
+               insn = find_insn(file, reloc->sym->sec,
+                                reloc->sym->offset + reloc_addend(reloc));
+               if (!insn) {
+                       WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type);
+                       return -1;
+               }
+
+               func(type, insn);
+       }
+
+       return 0;
+}
+
+static void __annotate_nop(int type, struct instruction *insn)
+{
+}
+
 static int read_noendbr_hints(struct objtool_file *file)
 {
        struct instruction *insn;
@@ -2670,6 +2713,8 @@ static int decode_sections(struct objtool_file *file)
        if (ret)
                return ret;
 
+       read_annotate(file, __annotate_nop);
+
        /*
         * Must be before read_unwind_hints() since that needs insn->noendbr.
         */