| /* SPDX-License-Identifier: GPL-2.0 */ | |
| /* | |
| * code tagging framework | |
| */ | |
| #ifndef _LINUX_CODETAG_H | |
| #define _LINUX_CODETAG_H | |
| #include <linux/types.h> | |
| struct codetag_iterator; | |
| struct codetag_type; | |
| struct codetag_module; | |
| struct seq_buf; | |
| struct module; | |
| #define CODETAG_SECTION_START_PREFIX "__start_" | |
| #define CODETAG_SECTION_STOP_PREFIX "__stop_" | |
| /* codetag flags */ | |
| #define CODETAG_FLAG_INACCURATE (1 << 0) | |
| /* | |
| * An instance of this structure is created in a special ELF section at every | |
| * code location being tagged. At runtime, the special section is treated as | |
| * an array of these. | |
| */ | |
| struct codetag { | |
| unsigned int flags; | |
| unsigned int lineno; | |
| const char *modname; | |
| const char *function; | |
| const char *filename; | |
| } __aligned(8); | |
| union codetag_ref { | |
| struct codetag *ct; | |
| }; | |
| struct codetag_type_desc { | |
| const char *section; | |
| size_t tag_size; | |
| int (*module_load)(struct module *mod, | |
| struct codetag *start, struct codetag *end); | |
| void (*module_unload)(struct module *mod, | |
| struct codetag *start, struct codetag *end); | |
| #ifdef CONFIG_MODULES | |
| void (*module_replaced)(struct module *mod, struct module *new_mod); | |
| bool (*needs_section_mem)(struct module *mod, unsigned long size); | |
| void *(*alloc_section_mem)(struct module *mod, unsigned long size, | |
| unsigned int prepend, unsigned long align); | |
| void (*free_section_mem)(struct module *mod, bool used); | |
| #endif | |
| }; | |
| struct codetag_iterator { | |
| struct codetag_type *cttype; | |
| struct codetag_module *cmod; | |
| unsigned long mod_id; | |
| struct codetag *ct; | |
| unsigned long mod_seq; | |
| }; | |
| #ifdef MODULE | |
| #define CT_MODULE_NAME KBUILD_MODNAME | |
| #else | |
| #define CT_MODULE_NAME NULL | |
| #endif | |
| #define CODE_TAG_INIT { \ | |
| .modname = CT_MODULE_NAME, \ | |
| .function = __func__, \ | |
| .filename = __FILE__, \ | |
| .lineno = __LINE__, \ | |
| .flags = 0, \ | |
| } | |
| void codetag_lock_module_list(struct codetag_type *cttype); | |
| bool codetag_trylock_module_list(struct codetag_type *cttype); | |
| void codetag_unlock_module_list(struct codetag_type *cttype); | |
| unsigned long codetag_get_content_id(struct codetag_type *cttype); | |
| unsigned int codetag_get_count(struct codetag_type *cttype); | |
| struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype); | |
| struct codetag *codetag_next_ct(struct codetag_iterator *iter); | |
| void codetag_to_text(struct seq_buf *out, struct codetag *ct); | |
| struct codetag_type * | |
| codetag_register_type(const struct codetag_type_desc *desc); | |
| #if defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) | |
| bool codetag_needs_module_section(struct module *mod, const char *name, | |
| unsigned long size); | |
| void *codetag_alloc_module_section(struct module *mod, const char *name, | |
| unsigned long size, unsigned int prepend, | |
| unsigned long align); | |
| void codetag_free_module_sections(struct module *mod); | |
| void codetag_module_replaced(struct module *mod, struct module *new_mod); | |
| int codetag_load_module(struct module *mod); | |
| void codetag_unload_module(struct module *mod); | |
| #else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */ | |
| static inline bool | |
| codetag_needs_module_section(struct module *mod, const char *name, | |
| unsigned long size) { return false; } | |
| static inline void * | |
| codetag_alloc_module_section(struct module *mod, const char *name, | |
| unsigned long size, unsigned int prepend, | |
| unsigned long align) { return NULL; } | |
| static inline void codetag_free_module_sections(struct module *mod) {} | |
| static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {} | |
| static inline int codetag_load_module(struct module *mod) { return 0; } | |
| static inline void codetag_unload_module(struct module *mod) {} | |
| #endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */ | |
| #endif /* _LINUX_CODETAG_H */ |