32位系统调用table入口点如何映射到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;
}
用户space代码:
#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;
}
当我 运行 这个用户 space 在 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
将 compat(32 位)和其他 ABI(例如 x86_64 上的 x32)系统调用入口点定义为 [的别名] =26=]真正的64位函数。它没有定义(也没有办法定义;这不是预处理器的工作方式)从单个主体构建的多个函数出现在宏评估的 )
之后。所以 __func__
扩展为其中写入 __func__
的实际函数的名称,而不是别名的名称。
对于 x>0 的 SYSCALL_DEFINEx
,它更复杂,因为必须转换参数,我相信涉及包装器。
你可以在arch/x86/include/asm/syscall_wrapper.h
(在顶级内核树下)中找到所有的魔法。
如果你真的 want/need 有单独的功能,我相信有一种方法可以跳过魔术并做到这一点。但这会使您的代码更难维护,因为它可能会在魔术背后的机制中断时中断。最好探测调用(当前)用户空间进程是 32 位还是 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;
}
用户space代码:
#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;
}
当我 运行 这个用户 space 在 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
将 compat(32 位)和其他 ABI(例如 x86_64 上的 x32)系统调用入口点定义为 [的别名] =26=]真正的64位函数。它没有定义(也没有办法定义;这不是预处理器的工作方式)从单个主体构建的多个函数出现在宏评估的 )
之后。所以 __func__
扩展为其中写入 __func__
的实际函数的名称,而不是别名的名称。
对于 x>0 的 SYSCALL_DEFINEx
,它更复杂,因为必须转换参数,我相信涉及包装器。
你可以在arch/x86/include/asm/syscall_wrapper.h
(在顶级内核树下)中找到所有的魔法。
如果你真的 want/need 有单独的功能,我相信有一种方法可以跳过魔术并做到这一点。但这会使您的代码更难维护,因为它可能会在魔术背后的机制中断时中断。最好探测调用(当前)用户空间进程是 32 位还是 64 位,并据此采取不同的行动。