【问题标题】:How does linker know what to link with a system call?链接器如何知道要与系统调用链接什么?
【发布时间】:2013-03-18 07:02:53
【问题描述】:

当我尝试在 RHEL 5.5 服务器上手动编译 squid 时,运行 configure 并得到

configure: WARNING: Eep!  Cannot find epoll, kqueue, /dev/poll, poll or select!
configure: WARNING: Will try select and hope for the best.
configure: Using select for the IO loop.

看起来内核没有配置CONFIG_EPOLL。所以我尝试编译this example epoll program来检查它是否有效。

在我的 gentoo 机器上(CONFIG_EPOLL 已启用。),它的编译没有任何问题。

在服务器上,我得到了

/tmp/cc8PhJh0.o: In function 'main':
epoll-exmaple.c:(.text+0x262): undefined reference to 'epoll_create1'
collect2: ld returned 1 exit status

我们都知道 c 程序编译器在 *.h 文件中查找定义,链接器将它们与 *.so 文件链接。

我的问题是,epoll_create1 是对内核的系统调用。链接器究竟搜索哪个文件来定位该系统调用的实现?

谢谢。

【问题讨论】:

    标签: linux compiler-construction linker epoll


    【解决方案1】:

    它在系统 C 库中查找(通常;少数系统调用在其他特殊库中,例如 librt)。 C 库为处理系统调用的用户空间程序提供了一个 C API。有时这可能是系统调用的一个非常薄的包装器,它只负责设置和返回参数,但更常见的是,它具有您不想担心的各种粘合,例如数据大小之间的差异用户空间和内核、不同架构的实现差异、内核系统调用 API 更改的向后或向前兼容性等等。

    % readelf -s /lib/i386-linux-gnu/libc.so.6 | grep epoll_create1
      1837: 000d5280    52 FUNC    GLOBAL DEFAULT   12 epoll_create1@@GLIBC_2.9
    

    如果您查看上面的 C 库,您可以看到链接器链接代码所针对的 C 函数。

    【讨论】:

    • 这解释了链接器搜索哪个文件。我可以在服务器上 grep 出epoll_create1 符号。但是,如果没有启用 epoll 的内核,为什么不能 ld 链接呢?
    • 更新:抱歉,我在 greping 时错过了 _create1。所以这是一个与 glibc 相关的问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多