xref: /linux-6.15/include/linux/codetag.h (revision 12ca42c2)
1916cc516SSuren Baghdasaryan /* SPDX-License-Identifier: GPL-2.0 */
2916cc516SSuren Baghdasaryan /*
3916cc516SSuren Baghdasaryan  * code tagging framework
4916cc516SSuren Baghdasaryan  */
5916cc516SSuren Baghdasaryan #ifndef _LINUX_CODETAG_H
6916cc516SSuren Baghdasaryan #define _LINUX_CODETAG_H
7916cc516SSuren Baghdasaryan 
8916cc516SSuren Baghdasaryan #include <linux/types.h>
9916cc516SSuren Baghdasaryan 
10916cc516SSuren Baghdasaryan struct codetag_iterator;
11916cc516SSuren Baghdasaryan struct codetag_type;
12916cc516SSuren Baghdasaryan struct codetag_module;
13916cc516SSuren Baghdasaryan struct seq_buf;
14916cc516SSuren Baghdasaryan struct module;
15916cc516SSuren Baghdasaryan 
164835f747SSuren Baghdasaryan #define CODETAG_SECTION_START_PREFIX	"__start_"
174835f747SSuren Baghdasaryan #define CODETAG_SECTION_STOP_PREFIX	"__stop_"
184835f747SSuren Baghdasaryan 
19916cc516SSuren Baghdasaryan /*
20916cc516SSuren Baghdasaryan  * An instance of this structure is created in a special ELF section at every
21916cc516SSuren Baghdasaryan  * code location being tagged.  At runtime, the special section is treated as
22916cc516SSuren Baghdasaryan  * an array of these.
23916cc516SSuren Baghdasaryan  */
24916cc516SSuren Baghdasaryan struct codetag {
25916cc516SSuren Baghdasaryan 	unsigned int flags; /* used in later patches */
26916cc516SSuren Baghdasaryan 	unsigned int lineno;
27916cc516SSuren Baghdasaryan 	const char *modname;
28916cc516SSuren Baghdasaryan 	const char *function;
29916cc516SSuren Baghdasaryan 	const char *filename;
30916cc516SSuren Baghdasaryan } __aligned(8);
31916cc516SSuren Baghdasaryan 
32916cc516SSuren Baghdasaryan union codetag_ref {
33916cc516SSuren Baghdasaryan 	struct codetag *ct;
34916cc516SSuren Baghdasaryan };
35916cc516SSuren Baghdasaryan 
36916cc516SSuren Baghdasaryan struct codetag_type_desc {
37916cc516SSuren Baghdasaryan 	const char *section;
38916cc516SSuren Baghdasaryan 	size_t tag_size;
39*12ca42c2SSuren Baghdasaryan 	void (*module_load)(struct module *mod,
40*12ca42c2SSuren Baghdasaryan 			    struct codetag *start, struct codetag *end);
41*12ca42c2SSuren Baghdasaryan 	void (*module_unload)(struct module *mod,
42*12ca42c2SSuren Baghdasaryan 			      struct codetag *start, struct codetag *end);
430db6f8d7SSuren Baghdasaryan #ifdef CONFIG_MODULES
440db6f8d7SSuren Baghdasaryan 	void (*module_replaced)(struct module *mod, struct module *new_mod);
450db6f8d7SSuren Baghdasaryan 	bool (*needs_section_mem)(struct module *mod, unsigned long size);
460db6f8d7SSuren Baghdasaryan 	void *(*alloc_section_mem)(struct module *mod, unsigned long size,
470db6f8d7SSuren Baghdasaryan 				   unsigned int prepend, unsigned long align);
480db6f8d7SSuren Baghdasaryan 	void (*free_section_mem)(struct module *mod, bool used);
490db6f8d7SSuren Baghdasaryan #endif
50916cc516SSuren Baghdasaryan };
51916cc516SSuren Baghdasaryan 
52916cc516SSuren Baghdasaryan struct codetag_iterator {
53916cc516SSuren Baghdasaryan 	struct codetag_type *cttype;
54916cc516SSuren Baghdasaryan 	struct codetag_module *cmod;
55916cc516SSuren Baghdasaryan 	unsigned long mod_id;
56916cc516SSuren Baghdasaryan 	struct codetag *ct;
57916cc516SSuren Baghdasaryan };
58916cc516SSuren Baghdasaryan 
59916cc516SSuren Baghdasaryan #ifdef MODULE
60916cc516SSuren Baghdasaryan #define CT_MODULE_NAME KBUILD_MODNAME
61916cc516SSuren Baghdasaryan #else
62916cc516SSuren Baghdasaryan #define CT_MODULE_NAME NULL
63916cc516SSuren Baghdasaryan #endif
64916cc516SSuren Baghdasaryan 
65916cc516SSuren Baghdasaryan #define CODE_TAG_INIT {					\
66916cc516SSuren Baghdasaryan 	.modname	= CT_MODULE_NAME,		\
67916cc516SSuren Baghdasaryan 	.function	= __func__,			\
68916cc516SSuren Baghdasaryan 	.filename	= __FILE__,			\
69916cc516SSuren Baghdasaryan 	.lineno		= __LINE__,			\
70916cc516SSuren Baghdasaryan 	.flags		= 0,				\
71916cc516SSuren Baghdasaryan }
72916cc516SSuren Baghdasaryan 
73916cc516SSuren Baghdasaryan void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
741438d349SSuren Baghdasaryan bool codetag_trylock_module_list(struct codetag_type *cttype);
75916cc516SSuren Baghdasaryan struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
76916cc516SSuren Baghdasaryan struct codetag *codetag_next_ct(struct codetag_iterator *iter);
77916cc516SSuren Baghdasaryan 
78916cc516SSuren Baghdasaryan void codetag_to_text(struct seq_buf *out, struct codetag *ct);
79916cc516SSuren Baghdasaryan 
80916cc516SSuren Baghdasaryan struct codetag_type *
81916cc516SSuren Baghdasaryan codetag_register_type(const struct codetag_type_desc *desc);
82916cc516SSuren Baghdasaryan 
83a4735739SSuren Baghdasaryan #if defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES)
840db6f8d7SSuren Baghdasaryan 
850db6f8d7SSuren Baghdasaryan bool codetag_needs_module_section(struct module *mod, const char *name,
860db6f8d7SSuren Baghdasaryan 				  unsigned long size);
870db6f8d7SSuren Baghdasaryan void *codetag_alloc_module_section(struct module *mod, const char *name,
880db6f8d7SSuren Baghdasaryan 				   unsigned long size, unsigned int prepend,
890db6f8d7SSuren Baghdasaryan 				   unsigned long align);
900db6f8d7SSuren Baghdasaryan void codetag_free_module_sections(struct module *mod);
910db6f8d7SSuren Baghdasaryan void codetag_module_replaced(struct module *mod, struct module *new_mod);
92a4735739SSuren Baghdasaryan void codetag_load_module(struct module *mod);
930db6f8d7SSuren Baghdasaryan void codetag_unload_module(struct module *mod);
940db6f8d7SSuren Baghdasaryan 
950db6f8d7SSuren Baghdasaryan #else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
960db6f8d7SSuren Baghdasaryan 
970db6f8d7SSuren Baghdasaryan static inline bool
codetag_needs_module_section(struct module * mod,const char * name,unsigned long size)980db6f8d7SSuren Baghdasaryan codetag_needs_module_section(struct module *mod, const char *name,
990db6f8d7SSuren Baghdasaryan 			     unsigned long size) { return false; }
1000db6f8d7SSuren Baghdasaryan static inline void *
codetag_alloc_module_section(struct module * mod,const char * name,unsigned long size,unsigned int prepend,unsigned long align)1010db6f8d7SSuren Baghdasaryan codetag_alloc_module_section(struct module *mod, const char *name,
1020db6f8d7SSuren Baghdasaryan 			     unsigned long size, unsigned int prepend,
1030db6f8d7SSuren Baghdasaryan 			     unsigned long align) { return NULL; }
codetag_free_module_sections(struct module * mod)1040db6f8d7SSuren Baghdasaryan static inline void codetag_free_module_sections(struct module *mod) {}
codetag_module_replaced(struct module * mod,struct module * new_mod)1050db6f8d7SSuren Baghdasaryan static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {}
codetag_load_module(struct module * mod)106a4735739SSuren Baghdasaryan static inline void codetag_load_module(struct module *mod) {}
codetag_unload_module(struct module * mod)1070db6f8d7SSuren Baghdasaryan static inline void codetag_unload_module(struct module *mod) {}
1080db6f8d7SSuren Baghdasaryan 
1090db6f8d7SSuren Baghdasaryan #endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
110a4735739SSuren Baghdasaryan 
111916cc516SSuren Baghdasaryan #endif /* _LINUX_CODETAG_H */
112