[英]Where is userspace wrapper for ioctl system call defined on x86_64 Linux?
I have (out of curiosity) been wondering where the user space wrapper for the ioctl system call is defined on x86_64 Linux. 我(出于好奇)一直想知道在x86_64 Linux上定义了ioctl系统调用的用户空间包装器。 My first thought was glibc - after checking the exposed symbols on the installed version on my Fedora 24 box, I can see that (unless I'm doing it wrong) libc exposes the ioctl symbol as 'W' meaning it is a weak symbol with a default implementation.
我的第一个想法是glibc - 在我的Fedora 24盒子上检查已安装版本上的暴露符号之后,我可以看到(除非我做错了)libc将ioctl符号暴露为'W'意味着它是一个弱符号默认实现。 The default implementation in the glibc source tree at misc/ioctl.c seems to be a stub though, and just sets errno to ENOSYS and returns -1.
misc / ioctl.c中的glibc源代码树中的默认实现似乎是一个存根,只是将errno设置为ENOSYS并返回-1。
Never the less, ioctl works (obviously or my system wouldn't be very usable). 从来没有,ioctl工作(显然或我的系统不会很有用)。 I am aware that it is probably assembly code somewhere in a file that is assembled and linked in somehow, thus overriding the weak symbol exposed by glibc.
我知道它可能是汇编代码在一个文件中的某个地方以某种方式组装和链接,从而覆盖glibc暴露的弱符号。 I am also aware that it is perfectly possible for applications to call ioctl directly using a system call, either via the glibc syscall wrapper or directly with assembly.
我也知道应用程序完全可以使用系统调用直接调用ioctl,可以通过glibc syscall包装器直接调用也可以直接使用程序集调用。
That said, given the library source code I happened to be observing (libdrm) includes the standard ioctl header /usr/include/sys/ioctl.h, and doesn't seem to contain its own implementation of the wrapper that I can see either, I am wondering where I should be looking. 也就是说,鉴于库源代码我碰巧观察(libdrm)包含标准的ioctl头文件/usr/include/sys/ioctl.h,并且似乎没有包含我自己可以看到的包装器实现,我想知道我应该在哪里看。
This is part of my push to understand the lowest levels of a GNU/Linux system more deeply. 这是我更深入地了解GNU / Linux系统最低级别的一部分。 Thanks for any pointers, and apologies if this has been asked before but I can't see any answer if it has.
感谢您的任何指示,并且如果之前已经提出过这样的道歉,但如果有的话,我看不到任何答案。
UPDATE: I neglected to mention above but I also checked the virtual vdso library mapped by the kernel - I could find only the following in it: 更新:我忽略了上面提到但我还检查了内核映射的虚拟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
UPDATE: It would appear I was incorrect about the glibc default definition being a stub. 更新:看起来我错误的glibc默认定义是存根。 As nos pointed out in the comments, disassembly shows it is performing the real system call.
正如nos在评论中指出的那样,反汇编表明它正在执行真正的系统调用。 I have posted an answer to reflect this.
我已经发布了一个答案来反映这一点。
As nos mentioned in the comment to my original question, it is indeed actually defined in libc, in my case as follows: 正如我在原始问题的评论中提到的那样,它实际上确实在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)
It is clearly making a system call here - as nos says, it must be autogenerated which is why I couldn't find it straight off in the glibc source tree. 这显然是在这里进行系统调用 - 正如nos所说,它必须是自动生成的,这就是我无法在glibc源代码树中直接找到它的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.