/* kallsyms_compat.h - Compatibility layer for kallsyms_lookup_name */ #ifndef KALLSYMS_COMPAT_H #define KALLSYMS_COMPAT_H #include #include #include /* kallsyms_lookup_name is no longer exported since kernel 5.7 */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) /* Function pointer for kallsyms_lookup_name */ static unsigned long (*mcctrl_kallsyms_lookup_name)(const char *name); /* Kprobe-based approach to get kallsyms_lookup_name function pointer */ static struct kprobe kp_kallsyms = { .symbol_name = "kallsyms_lookup_name" }; static int init_kallsyms_lookup(void) { int ret; ret = register_kprobe(&kp_kallsyms); if (ret < 0) { pr_err("register_kprobe failed, returned %d\n", ret); return ret; } mcctrl_kallsyms_lookup_name = (unsigned long (*)(const char *))kp_kallsyms.addr; unregister_kprobe(&kp_kallsyms); if (!mcctrl_kallsyms_lookup_name) { pr_err("Failed to get kallsyms_lookup_name address\n"); return -EINVAL; } return 0; } static void cleanup_kallsyms_lookup(void) { mcctrl_kallsyms_lookup_name = NULL; } static inline unsigned long mcctrl_lookup_name(const char *name) { if (mcctrl_kallsyms_lookup_name) return mcctrl_kallsyms_lookup_name(name); return 0; } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0) */ static inline int init_kallsyms_lookup(void) { return 0; } static inline void cleanup_kallsyms_lookup(void) { } static inline unsigned long mcctrl_lookup_name(const char *name) { return kallsyms_lookup_name(name); } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ #endif /* KALLSYMS_COMPAT_H */