V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
gssong
V2EX  ›  Linux

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

  •  
  •   gssong · 2020-05-17 18:12:22 +08:00 · 2823 次点击
    这是一个创建于 1682 天前的主题,其中的信息可能已经有所发展或是发生改变。

    内核是根据 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
    

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

    6 条回复    2020-05-18 06:58:02 +08:00
    AmrtaShiva
        1
    AmrtaShiva  
       2020-05-17 19:07:01 +08:00
    路径换英文试试
    redsonic
        2
    redsonic  
       2020-05-17 22:48:42 +08:00
    current 找不到定义。它是一个指向当前进程块的宏,应该是缺了头文件。 另外别用中文环境,这翻译比苹果官网的还迷。
    May725
        3
    May725  
       2020-05-18 01:52:21 +08:00 via iPhone
    嗯,不完整的类型这种错误,一般就是没有定义或者没有头文件的问题
    xiadong1994
        4
    xiadong1994  
       2020-05-18 06:30:04 +08:00 via iPhone
    谁语文好的解释一下提领是什么意思?
    vk42
        5
    vk42  
       2020-05-18 06:55:50 +08:00
    include 加上<asm/current.h>试试。另外现在 kernel 的系统调用表应该默认是只读的,要手动改 page table entry 才能改写
    vk42
        6
    vk42  
       2020-05-18 06:58:02 +08:00
    另外把 locale 设成英文错误提示可能更易懂些,网上也好搜解决方法……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5445 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 09:00 · PVG 17:00 · LAX 01:00 · JFK 04:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.