【发布时间】:2015-07-11 09:36:19
【问题描述】:
我基本上需要为我的目的定制几个 linux 系统调用接口(比如 sys_open)。我非常了解 GNU Linker ld --wrap=symbol 选项并使用该逻辑来更改 open() libc 包装器。虽然这可以达到目的,但我真的很想知道在 libc 源代码中的哪个位置,实际的实现发挥了作用。
以下两个地方是我的主要嫌疑人(注意fcntrl.h只有声明)
- GLIBC_DIR/io/open.c
- GLIBC_DIR/ports/sysdeps/unix/sysv/linux/generic/open.c
示例驱动程序:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd;
if ((fd = open("sample.c", O_RDONLY)) == -1) {
fprintf(stderr, "file not found\n");
exit(1);
}
return 0;
}
关注sn-p:
main:
401dd1: bf 44 90 48 00 mov $0x489044,%edi
401dd6: b8 00 00 00 00 mov $0x0,%eax
401ddb: e8 10 03 03 00 callq 4320f0 <__libc_open>
......
......
__libc_open:
4320f0: 83 3d 69 8e 28 00 00 cmpl $0x0,0x288e69(%rip)
4320f7: 75 14 jne 43210d <__open_nocancel+0x14>
__open_nocancel:
4320f9: b8 02 00 00 00 mov $0x2,%eax
4320fe: 0f 05 syscall
为简单起见,我准备了所有的 libc 源可执行文件静态。也足够小心以使 GCC 正确选择自定义 libc.a。我尝试添加一个 puts 语句,但上面提到的两个源代码根本没有被调用。查看可执行文件的程序集 [如上所示],sys_open 调用(__open_nocancel 中的 0x2)以某种方式放置在可执行文件中。
所以我的问题如下:
- open() 相关的代码逻辑究竟是从哪里来的?
- 当 libc 源代码树中没有明确命名为 open 的函数时,链接器如何成功挂钩 open() 函数?
【问题讨论】:
标签: linux gcc linker system-calls libc