簡體   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