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