| 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 | 
|---|
| 102 | codetag_needs_module_section(struct module *mod, const char *name, | 
|---|
| 103 | unsigned long size) { return false; } | 
|---|
| 104 | static inline void * | 
|---|
| 105 | codetag_alloc_module_section(struct module *mod, const char *name, | 
|---|
| 106 | unsigned long size, unsigned int prepend, | 
|---|
| 107 | unsigned long align) { return NULL; } | 
|---|
| 108 | static inline void codetag_free_module_sections(struct module *mod) {} | 
|---|
| 109 | static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {} | 
|---|
| 110 | static inline int codetag_load_module(struct module *mod) { return 0; } | 
|---|
| 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 |  | 
|---|