1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * code tagging framework
4 */
5 #ifndef _LINUX_CODETAG_H
6 #define _LINUX_CODETAG_H
7
8 #include <linux/types.h>
9
10 struct codetag_iterator;
11 struct codetag_type;
12 struct codetag_module;
13 struct seq_buf;
14 struct module;
15
16 #define CODETAG_SECTION_START_PREFIX "__start_"
17 #define CODETAG_SECTION_STOP_PREFIX "__stop_"
18
19 /* codetag flags */
20 #define CODETAG_FLAG_INACCURATE (1 << 0)
21
22 /*
23 * An instance of this structure is created in a special ELF section at every
24 * code location being tagged. At runtime, the special section is treated as
25 * an array of these.
26 */
27 struct codetag {
28 unsigned int flags;
29 unsigned int lineno;
30 const char *modname;
31 const char *function;
32 const char *filename;
33 } __aligned(8);
34
35 union codetag_ref {
36 struct codetag *ct;
37 };
38
39 struct codetag_type_desc {
40 const char *section;
41 size_t tag_size;
42 int (*module_load)(struct module *mod,
43 struct codetag *start, struct codetag *end);
44 void (*module_unload)(struct module *mod,
45 struct codetag *start, struct codetag *end);
46 #ifdef CONFIG_MODULES
47 void (*module_replaced)(struct module *mod, struct module *new_mod);
48 bool (*needs_section_mem)(struct module *mod, unsigned long size);
49 void *(*alloc_section_mem)(struct module *mod, unsigned long size,
50 unsigned int prepend, unsigned long align);
51 void (*free_section_mem)(struct module *mod, bool used);
52 #endif
53 };
54
55 struct codetag_iterator {
56 struct codetag_type *cttype;
57 struct codetag_module *cmod;
58 unsigned long mod_id;
59 struct codetag *ct;
60 unsigned long mod_seq;
61 };
62
63 #ifdef MODULE
64 #define CT_MODULE_NAME KBUILD_MODNAME
65 #else
66 #define CT_MODULE_NAME NULL
67 #endif
68
69 #define CODE_TAG_INIT { \
70 .modname = CT_MODULE_NAME, \
71 .function = __func__, \
72 .filename = __FILE__, \
73 .lineno = __LINE__, \
74 .flags = 0, \
75 }
76
77 void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
78 bool codetag_trylock_module_list(struct codetag_type *cttype);
79 struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
80 struct codetag *codetag_next_ct(struct codetag_iterator *iter);
81
82 void codetag_to_text(struct seq_buf *out, struct codetag *ct);
83
84 struct codetag_type *
85 codetag_register_type(const struct codetag_type_desc *desc);
86
87 #if defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES)
88
89 bool codetag_needs_module_section(struct module *mod, const char *name,
90 unsigned long size);
91 void *codetag_alloc_module_section(struct module *mod, const char *name,
92 unsigned long size, unsigned int prepend,
93 unsigned long align);
94 void codetag_free_module_sections(struct module *mod);
95 void codetag_module_replaced(struct module *mod, struct module *new_mod);
96 int codetag_load_module(struct module *mod);
97 void codetag_unload_module(struct module *mod);
98
99 #else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
100
101 static inline bool
codetag_needs_module_section(struct module * mod,const char * name,unsigned long size)102 codetag_needs_module_section(struct module *mod, const char *name,
103 unsigned long size) { return false; }
104 static inline void *
codetag_alloc_module_section(struct module * mod,const char * name,unsigned long size,unsigned int prepend,unsigned long align)105 codetag_alloc_module_section(struct module *mod, const char *name,
106 unsigned long size, unsigned int prepend,
107 unsigned long align) { return NULL; }
codetag_free_module_sections(struct module * mod)108 static inline void codetag_free_module_sections(struct module *mod) {}
codetag_module_replaced(struct module * mod,struct module * new_mod)109 static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {}
codetag_load_module(struct module * mod)110 static inline int codetag_load_module(struct module *mod) { return 0; }
codetag_unload_module(struct module * mod)111 static inline void codetag_unload_module(struct module *mod) {}
112
113 #endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
114
115 #endif /* _LINUX_CODETAG_H */
116