gpt4 book ai didi

linux - 在 Linux 内核中找不到方法 __kernel_vsyscall

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:40:28 24 4
gpt4 key购买 nike

我正在寻找 linux 内核中用于进行系统调用的 __kernel_vsyscall 方法。我想观察它的代码以了解更多信息,但我的 grep 搜索似乎无法找到它,而且我无法在互联网上找到它的位置。任何人都可以指出它的确切位置吗?它可以被操纵吗?

感谢您的帮助!

最佳答案

假设您的当前目录位于 linux 内核源代码的开头,这里是定义 __kernel_vsyscall 符号的文件的位置。 (下面显示的仅适用于 x86,它还不存在于许多其他硬件架构中)。

./arch/x86/vdso/vdso32/syscall.S:
__kernel_vsyscall:

./arch/x86/vdso/vdso32/sysenter.S:
__kernel_vsyscall:

./arch/x86/vdso/vdso32/int80.S:
__kernel_vsyscall:

如您所见,它基本上是在三个文件中声明和实现的:int80.S、sysenter.S 和 syscall.S。

进行系统调用.S:

__kernel_vsyscall:
.LSTART_vsyscall:
push %ebp
.Lpush_ebp:
movl %ecx, %ebp
syscall
movl $__USER32_DS, %ecx
movl %ecx, %ss
movl %ebp, %ecx
popl %ebp

如果您阅读上面的文件和“arch/x86/vdso/vdso32/sigreturn.S”组合,上面的“系统调用”实际上解析为“int 0x80”。

而对于sysenter.S,它是使用intel汇编指令“sysenter”实现系统调用转换。

对于 int80.S,它使用“int 0x80”进行系统调用转换。

如果您询问哪个是用于系统调用实现的方法,请查看 arch/x86/vdso/vdso32-setup.c:

int __init sysenter_setup(void)
{
void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
const void *vsyscall;
size_t vsyscall_len;

vdso32_pages[0] = virt_to_page(syscall_page);

#ifdef CONFIG_X86_32
gate_vma_init();
#endif

if (vdso32_syscall()) {
vsyscall = &vdso32_syscall_start;
vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
} else if (vdso32_sysenter()){
vsyscall = &vdso32_sysenter_start;
vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
} else {
vsyscall = &vdso32_int80_start;
vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
}

memcpy(syscall_page, vsyscall, vsyscall_len);
relocate_vdso(syscall_page);

return 0;
}

如您所见,现代操作系统更喜欢 sysenter 方法,因为它比 int80 方法更快。 (象征性地,“vds32_syscall_start”将退回到 int80)。

关于linux - 在 Linux 内核中找不到方法 __kernel_vsyscall,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12905799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com