72 lines
1.6 KiB
C
72 lines
1.6 KiB
C
/* kallsyms_compat.h - Compatibility layer for kallsyms_lookup_name */
|
|
|
|
#ifndef KALLSYMS_COMPAT_H
|
|
#define KALLSYMS_COMPAT_H
|
|
|
|
#include <linux/version.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/kprobes.h>
|
|
|
|
/* 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 */ |