Linux 通过添加内核模块增加系统调用编译报"提领指向不完全类型的指针"的错误

2020-05-17 18:12:22 +08:00
 gssong

内核是根据 linux-5.6.13 的源码自己编译的内核,虚拟机+Centos7 64 位

代码如下

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <asm/uaccess.h>
#include <linux/sched.h>

#define my_syscall_num 336
/*此处我也不知道为啥,执行
cat /proc/kallsyms | grep sys_call_table
结果如下
0000000000000000 R sys_call_table
0000000000000000 R ia32_sys_call_table
*/
#define sys_call_table_adress 0x00000000

unsigned int clear_and_return_cr0(void);
void setback_cr0(unsigned int val);
asmlinkage long sys_mycall(long long num);
int orig_cr0;
unsigned long *sys_call_table = 0;
static int (*anything_saved)(void);

MODULE_AUTHOR("GuoShuSong");
MODULE_LICENSE("GPL");
unsigned int clear_and_return_cr0(void){
	unsigned int cr0 = 0;
	unsigned int ret;
	asm("movl %%cr0,%%eax":"=a"(cr0));
	ret = cr0;
	cr0 &= 0xfffeffff;
	asm("movl %%eax,%%cr0"::"a"(cr0));
	return ret;
}
void setback_cr0(unsigned int val){
	asm volatile("movl %%eax,%%cr0"::"a"(val));
}

static int __init init_addsyscall(void){
	printk("hello,kernel");
	sys_call_table=(unsigned long *)sys_call_table_adress;
	anything_saved = (int(*)(void))(sys_call_table[my_syscall_num]);
	orig_cr0 = clear_and_return_cr0();
	sys_call_table[my_syscall_num]= (unsigned long)&sys_mycall;
	setback_cr0(orig_cr0);
	return 0;
}

asmlinkage long sys_mycall(long long num){
	int res =0;
	long long r = num;
	if(do_div(num,2)== 0){
		res = do_div(r,1000000);
	}else{
		res = do_div(r,100000);
	}
	return res;
}

static void __exit exit_addsyscall(void){
	orig_cr0 = clear_and_return_cr0();
	sys_call_table[my_syscall_num]= (unsigned long)anything_saved;
	setback_cr0(orig_cr0);
	printk("call exit \n");
}

module_init(init_addsyscall);
module_exit(exit_addsyscall);

MakeFile 代码如下

ifneq  ($(KERNELRELEASE),)
EXTRA_CFLAGS = -O0
obj-m := gss.o
else
KDIR = /lib/modules/$(shell uname -r)/build

#KDIR = /lib/modules/5.6.1318130500093-GuoShuSong/build

PWD := $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.symvers *.cmd *.cmd.o
endif

执行 make 时报错如下

make -C /lib/modules/5.6.1318130500093-GuoShuSong/build M=/home/gssplus/桌面 /test/os3 modules
make[1]: 进入目录“/home/gssplus/桌面 /test/linux-5.6.13”
  CC [M]  /home/gssplus/桌面 /test/os3/gss.o
In file included from /home/gssplus/桌面 /test/os3/gss.c:5:0:
./arch/x86/include/asm/uaccess.h: 在函数‘set_fs’中:
./arch/x86/include/asm/uaccess.h:31:9: 错误:提领指向不完全类型的指针
  current->thread.addr_limit = fs;
         ^
In file included from ./include/linux/init.h:5:0,
                 from /home/gssplus/桌面 /test/os3/gss.c:1:
./arch/x86/include/asm/uaccess.h: 在函数‘user_access_begin’中:
./arch/x86/include/asm/uaccess.h:37:33: 错误:提领指向不完全类型的指针
 #define user_addr_max() (current->thread.addr_limit.seg)
                                 ^
./include/linux/compiler.h:78:42: 附注:in definition of macro ‘unlikely’
 # define unlikely(x) __builtin_expect(!!(x), 0)
                                          ^
./arch/x86/include/asm/uaccess.h:96:2: 附注:in expansion of macro ‘likely’
  likely(!__range_not_ok(addr, size, user_addr_max()));  \
  ^
./arch/x86/include/asm/uaccess.h:96:10: 附注:in expansion of macro ‘__range_not_ok’
  likely(!__range_not_ok(addr, size, user_addr_max()));  \
          ^
./arch/x86/include/asm/uaccess.h:96:37: 附注:in expansion of macro ‘user_addr_max’
  likely(!__range_not_ok(addr, size, user_addr_max()));  \
                                     ^
./arch/x86/include/asm/uaccess.h:714:16: 附注:in expansion of macro ‘access_ok’
  if (unlikely(!access_ok(ptr,len)))
                ^
make[3]: *** [/home/gssplus/桌面 /test/os3/gss.o] 错误 1
make[2]: *** [/home/gssplus/桌面 /test/os3] 错误 2
make[1]: *** [sub-make] 错误 2
make[1]: 离开目录“/home/gssplus/桌面 /test/linux-5.6.13”
make: *** [all] 错误 2

有没有大佬知道是怎么回事儿

2802 次点击
所在节点    Linux
6 条回复
AmrtaShiva
2020-05-17 19:07:01 +08:00
路径换英文试试
redsonic
2020-05-17 22:48:42 +08:00
current 找不到定义。它是一个指向当前进程块的宏,应该是缺了头文件。 另外别用中文环境,这翻译比苹果官网的还迷。
May725
2020-05-18 01:52:21 +08:00
嗯,不完整的类型这种错误,一般就是没有定义或者没有头文件的问题
xiadong1994
2020-05-18 06:30:04 +08:00
谁语文好的解释一下提领是什么意思?
vk42
2020-05-18 06:55:50 +08:00
include 加上<asm/current.h>试试。另外现在 kernel 的系统调用表应该默认是只读的,要手动改 page table entry 才能改写
vk42
2020-05-18 06:58:02 +08:00
另外把 locale 设成英文错误提示可能更易懂些,网上也好搜解决方法……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/672624

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX