从libc源代码中的哪个位置打开()获取链接?

时间:2015-07-11 09:36:19

标签: linux gcc linker system-calls libc

我基本上需要为我的目的定制一些 linux 系统调用接口(比如 sys_open )。我非常了解GNU Linker ld --wrap = symbol 选项,并使用该逻辑来改变open()libc包装器。虽然这有助于达到目的,但我真的想知道在libc源代码中的哪个位置,实际实现起了作用。

以下两个地方是我的主要嫌疑人(注意 fcntrl.h 只有声明)

  • GLIBC_DIR / IO / open.c
  • GLIBC_DIR /端口/ sysdeps / UNIX / SYSV / LINUX /通用/ 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;
}

有关摘录:

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)已经以某种方式放在可执行文件中。

所以我的问题如下:

  • 从libc的确切位置来看, open()相关的代码逻辑神奇地来了?
  • 当libc源代码树中没有明确命名为open的函数时,链接器如何能够成功挂钩open()函数?

1 个答案:

答案 0 :(得分:3)

  

从libc中的确切地说,open()相关的代码逻辑神奇地来了吗?

来自sysdeps/unix/syscall-template.S

  

当libc源代码树中没有明确命名为open的函数时,链接器如何成功挂钩open()函数?

如果您使用正确的-DSYSCALL_SYMBOL=...预处理上述来源,您会发现 在源中提及open