出于好奇,我一直想知道在x86_64 Linux上,ioctl系统调用的用户空间包装器是在哪里定义的。我的第一个想法是glibc - 经过检查我在Fedora 24上安装的版本的暴露符号后,我可以看到(除非我做错了什么)libc将ioctl符号公开为“W”,这意味着它是一个具有默认实现的弱符号。 glibc源代码树中misc / ioctl.c中的默认实现似乎只是一个存根,仅将errno设置为ENOSYS并返回-1。
尽管如此,ioctl可行(当然,否则我的系统就无法使用)。我知道它可能在某个文件中的汇编代码中,并以某种方式进行汇编和链接,从而覆盖了glibc公开的弱符号。我还知道,应用程序可以通过系统调用直接调用ioctl,无论是通过glibc系统调用包装器还是直接使用汇编语言。
话虽如此,鉴于我正观察的库源代码(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默认定义只是一个存根的说法是错误的。正如评论中nos指出的那样,反汇编显示它正在执行真正的系统调用。我已经发布了一篇答案来反映这一点。
objdump -D /lib64/libc.so.6
,您会发现它确实执行了实际的系统调用 - 它不是来自misc/ioctl.c的实现。它的定义很可能是作为glibc构建过程的一部分自动生成的,很可能sysdeps/unix/make-syscalls.sh是其中的一部分。 - nos