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