繁体   English   中英

32 位系统调用表入口点如何映射到 x86_64 中的 SYSCALL_DEFINE

[英]How does 32-bit system call table entry point maps to SYSCALL_DEFINE in x86_64

我正在深入研究系统调用,

在 syscall_32.tbl 和 syscall_64.tbl 中添加了系统调用

syscall_32.tbl

434     i386    hello           sys_hello           __ia32_sys_hello

syscall_64.tbl

434 common  hello           __x64_sys_hello

定义:

SYSCALL_DEFINE0(hello) {
    pr_info("%s\n", __func__);
    pr_info("Hello, world!\n");
    return 0;
 }

用户空间代码:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/syscall.h>
#include <string.h>
int main(void)
{
    long return_value = syscall(434);

    printf("return value from syscall: %ld, erron:%d\n", return_value, errno);
    return 0;
}

当我在 x86_64 上运行这个用户空间代码时,我在 dmesg 中得到以下输出

$ gcc userspace.c -o userspace

[  800.837360] __x64_sys_hello
[  800.837361] Hello, world!

但是当我为 32 位编译它时,我得到

$ gcc userspace.c -o userspace -m32

[  838.979286] __x64_sys_hello
[  838.979286] Hello, world!

syscall_32.tbl (__ia32_sys_hello) 中的入口点如何映射到 __x64_sys_hello?

在 64 位内核上, SYSCALL_DEFINE0将兼容(32 位)和其他 ABI(例如 x86_64 上的 x32)系统调用入口点定义真实 64 位函数的别名 它没有定义(也无法定义;这不是预处理器的工作方式)多个函数,这些函数是从宏计算)之后出现的单个主体构建的。 所以__func__扩展为写有__func__的实际函数的名称,而不是别名的名称。

对于 x>0 的SYSCALL_DEFINEx ,它更复杂,因为必须转换参数,而且我相信涉及包装器。

你可以在arch/x86/include/asm/syscall_wrapper.h (在顶级内核树下)找到所有的魔法。

如果你真的想要/需要有单独的功能,我相信有一种方法可以跳过魔法并做到这一点。 但这会使您的代码更难维护,因为当魔术背后的机制中断时它可能会中断。 最好探测调用(当前)用户空间进程是 32 位还是 64 位,并根据它采取不同的行动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM