1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Provide kernel headers useful to build tracing programs 4 * such as for running eBPF tracing tools. 5 * 6 * (Borrowed code from kernel/configs.c) 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/proc_fs.h> 12 #include <linux/init.h> 13 #include <linux/uaccess.h> 14 15 /* 16 * Define kernel_headers_data and kernel_headers_data_end, within which the 17 * compressed kernel headers are stored. The file is first compressed with xz. 18 */ 19 20 asm ( 21 " .pushsection .rodata, \"a\" \n" 22 " .global kernel_headers_data \n" 23 "kernel_headers_data: \n" 24 " .incbin \"kernel/kheaders_data.tar.xz\" \n" 25 " .global kernel_headers_data_end \n" 26 "kernel_headers_data_end: \n" 27 " .popsection \n" 28 ); 29 30 extern char kernel_headers_data; 31 extern char kernel_headers_data_end; 32 33 static ssize_t 34 ikheaders_read_current(struct file *file, char __user *buf, 35 size_t len, loff_t *offset) 36 { 37 return simple_read_from_buffer(buf, len, offset, 38 &kernel_headers_data, 39 &kernel_headers_data_end - 40 &kernel_headers_data); 41 } 42 43 static const struct file_operations ikheaders_file_ops = { 44 .read = ikheaders_read_current, 45 .llseek = default_llseek, 46 }; 47 48 static int __init ikheaders_init(void) 49 { 50 struct proc_dir_entry *entry; 51 52 /* create the current headers file */ 53 entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL, 54 &ikheaders_file_ops); 55 if (!entry) 56 return -ENOMEM; 57 58 proc_set_size(entry, 59 &kernel_headers_data_end - 60 &kernel_headers_data); 61 return 0; 62 } 63 64 static void __exit ikheaders_cleanup(void) 65 { 66 remove_proc_entry("kheaders.tar.xz", NULL); 67 } 68 69 module_init(ikheaders_init); 70 module_exit(ikheaders_cleanup); 71 72 MODULE_LICENSE("GPL v2"); 73 MODULE_AUTHOR("Joel Fernandes"); 74 MODULE_DESCRIPTION("Echo the kernel header artifacts used to build the kernel"); 75