c - x86_64 Linux 上定义的 ioctl 系统调用的用户空间包装器在哪里?

标签 c linux system-calls symbols ioctl

我一直(出于好奇)想知道 ioctl 系统调用的用户空间包装器是在 x86_64 Linux 上定义的。我的第一个想法是 glibc——在我的 Fedora 24 盒子上检查已安装版本的暴露符号后,我可以看到(除非我做错了)libc 将 ioctl 符号暴露为“W”,这意味着它是一个弱符号默认实现。 misc/ioctl.c 的 glibc 源代码树中的默认实现似乎是一个 stub ,只是将 errno 设置为 ENOSYS 并返回 -1。

尽管如此,ioctl 仍然有效(很明显,否则我的系统将不太可用)。我知道它可能是文件中某处的汇编代码,以某种方式组装和链接,从而覆盖了 glibc 公开的弱符号。我还知道,应用程序完全有可能通过 glibc 系统调用包装器或直接使用程序集使用系统调用直接调用 ioctl。

也就是说,考虑到我碰巧观察到的库源代码 (libdrm) 包含标准的 ioctl 头文件/usr/include/sys/ioctl.h,并且似乎不包含我自己的包装器实现都可以看到,我想知道我应该看哪里。

这是我努力更深入地了解 GNU/Linux 系统的最低级别的一部分。感谢您的指点,如果之前有人问过这个问题,我深表歉意,但如果有的话,我看不到任何答案。

更新:我忽略了上面提到的,但我也检查了内核映射的虚拟 vdso 库 - 我只能在其中找到以下内容:

0000000000000a00 W clock_gettime
0000000000000db0 W getcpu
0000000000000c40 W gettimeofday
0000000000000000 A LINUX_2.6
0000000000000d90 W time
0000000000000a00 T __vdso_clock_gettime
0000000000000db0 T __vdso_getcpu
0000000000000c40 T __vdso_gettimeofday
0000000000000d90 T __vdso_time

更新:看来我对 glibc 默认定义是 stub 的看法是不正确的。正如 nos 在评论中指出的那样,反汇编表明它正在执行真正的系统调用。我已经发布了一个答案来反射(reflect)这一点。

最佳答案

正如我原来问题的评论中提到的,它确实是在 libc 中定义的,在我的例子中如下:

00000000000f8ce0 <ioctl>:
   f8ce0:       b8 10 00 00 00          mov    $0x10,%eax
   f8ce5:       0f 05                   syscall
   f8ce7:       48 3d 01 f0 ff ff       cmp    $0xfffffffffffff001,%rax
   f8ced:       73 01                   jae    f8cf0 <ioctl+0x10>
   f8cef:       c3                      retq
   f8cf0:       48 8b 0d 71 31 2c 00    mov    0x2c3171(%rip),%rcx        # 3bbe68 <_DYNAMIC+0x308>
   f8cf7:       f7 d8                   neg    %eax
   f8cf9:       64 89 01                mov    %eax,%fs:(%rcx)
   f8cfc:       48 83 c8 ff             or     $0xffffffffffffffff,%rax
   f8d00:       c3                      retq
   f8d01:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
   f8d08:       00 00 00
   f8d0b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

这里显然是在进行系统调用——正如 nos 所说,它必须是自动生成的,这就是为什么我无法直接在 glibc 源代码树中找到它。

关于c - x86_64 Linux 上定义的 ioctl 系统调用的用户空间包装器在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41246306/

相关文章:

linux - 如何为 *nix 进程实现 writer-preferring 读/写锁

c - 如何使用 pcap 从多个接口(interface)捕获流量

c - 函数参数中的舍入错误

linux - 如何在 linux 中构建 Tkinter GUI,就像在 window 中构建 exe 一样?

c - C 中管道、greps、wc 的堆栈崩溃问题

linux - 为什么这种使用 sys_write 的尝试没有做任何事情?

sockets - 在 Go 中加速系统调用

c - C中的重复声明全局变量

c - C99 中 'unlocked' I/O 函数的等价物是什么?

c - 对 C 中的指针感到困惑