链接到不进行函数调用的库会产生什么影响?

发布于 2024-11-16 04:36:35 字数 99 浏览 3 评论 0原文

我有一个程序的 make 文件,该程序使用以下行 -ldl 链接到 libdl.so。没有调用 dlopen 或任何相关函数。即使您不使用任何函数,以这种方式链接到该库会产生什么效果?

I have a make file for a program that links to libdl.so with the following line -ldl. There are no calls to dlopen or any of the related functions. What is the effect of linking to this library in this way even though you do not use any of the functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清晨说晚安 2024-11-23 04:36:35

您必须阅读链接器的文档。来自我的 Linux/ELF/GNU Binutils 系统上的 info ld(强调):

`--as-needed'
`--no-as-needed'
     This option affects ELF DT_NEEDED tags for dynamic libraries
     mentioned on the command line after the `--as-needed' option.
     Normally the linker will add a DT_NEEDED tag for each dynamic
     library mentioned on the command line, regardless of whether the
     library is actually needed or not.  `--as-needed' causes a
     DT_NEEDED tag to only be emitted for a library that satisfies an
     undefined symbol reference from a regular object file or, if the
     library is not found in the DT_NEEDED lists of other libraries
     linked up to that point, an undefined symbol reference from
     another dynamic library.  `--no-as-needed' restores the default
     behaviour.

您可以通过在测试程序上运行 ldd 来检查自己。在一个简单的测试程序中,我得到:

    linux-vdso.so.1 =>  (0x00007fffd8305000)
    libc.so.6 => /lib/libc.so.6 (0x00007f646c669000)
    /lib/ld-linux-x86-64.so.2 (0x00007f646c9ca000)

但是,如果我与 -ldl 链接,我得到:

    linux-vdso.so.1 =>  (0x00007fff644f1000)
    libdl.so.2 => /lib/libdl.so.2 (0x00007fb9b1375000)
    libc.so.6 => /lib/libc.so.6 (0x00007fb9b1014000)
    /lib/ld-linux-x86-64.so.2 (0x00007fb9b1579000)

即使我的程序没有使用 libdl 。但是,如果我使用 -Wl,--as-needed 运行 GCC,libdl 将不会被链接。根据我的测试,这仅在 - Wl,--as-needed 在命令行中 -ldl 之前列出。

有什么影响?这意味着即使您不使用共享库,您的二进制文件也无法在没有共享库的系统上运行。这也意味着如果您升级共享库并卸载旧的共享库,您的二进制文件将会损坏。这不是什么大问题,因为二进制兼容性无论如何都是一个问题,但我认为没有理由不为一般项目打开 -Wl,--as-needed

You'll have to read the documentation for your linker. From info ld on my Linux/ELF/GNU Binutils system (emphasis added):

`--as-needed'
`--no-as-needed'
     This option affects ELF DT_NEEDED tags for dynamic libraries
     mentioned on the command line after the `--as-needed' option.
     Normally the linker will add a DT_NEEDED tag for each dynamic
     library mentioned on the command line, regardless of whether the
     library is actually needed or not.  `--as-needed' causes a
     DT_NEEDED tag to only be emitted for a library that satisfies an
     undefined symbol reference from a regular object file or, if the
     library is not found in the DT_NEEDED lists of other libraries
     linked up to that point, an undefined symbol reference from
     another dynamic library.  `--no-as-needed' restores the default
     behaviour.

You can check yourself by running ldd on a test program. On a simple test program, I get:

    linux-vdso.so.1 =>  (0x00007fffd8305000)
    libc.so.6 => /lib/libc.so.6 (0x00007f646c669000)
    /lib/ld-linux-x86-64.so.2 (0x00007f646c9ca000)

However, if I link with -ldl, I get this:

    linux-vdso.so.1 =>  (0x00007fff644f1000)
    libdl.so.2 => /lib/libdl.so.2 (0x00007fb9b1375000)
    libc.so.6 => /lib/libc.so.6 (0x00007fb9b1014000)
    /lib/ld-linux-x86-64.so.2 (0x00007fb9b1579000)

Even though libdl isn't used by my program. However, if I run GCC with -Wl,--as-needed, libdl will not be linked in. According to my tests, this only works if -Wl,--as-needed is listed on the command line before -ldl.

What are the effects? It means that your binary won't run on systems without the shared library, even though you don't use it. It also means that your binary will break if you upgrade the shared library and uninstall the old one. It's not a big deal because binary compatibility is a bear anyway, but I see no reason not to turn on -Wl,--as-needed for projects in general.

醉殇 2024-11-23 04:36:35

我编写了一个小型应用程序,它只使用 STL。它的大小为 8275 字节,无需链接到任何特定库:

    linux-gate.so.1 =>  (0x00e1e000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x0015a000)
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x0044b000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00741000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00250000)
    /lib/ld-linux.so.2 (0x00a75000)

现在,当我编译它并将其与 boost_thread 链接时,它会增长到 8290 字节

    linux-gate.so.1 =>  (0x009d9000)
    libboost_thread.so.1.40.0 => /usr/lib/libboost_thread.so.1.40.0 (0x00e59000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x003a3000)
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bc5000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00f8a000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
    libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00bf0000)
    librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00dd8000)
    /lib/ld-linux.so.2 (0x00ba3000)

请注意,没有我的代码对 boost_thread 的功能进行函数调用。但是,无论如何,boost_thread 都会作为我的应用程序的依赖项添加(正如您在ldd 的输出中看到的那样)。

I have coded a small application which uses nothing but STL. It has 8275 bytes of size without linking to any specific libraries:

    linux-gate.so.1 =>  (0x00e1e000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x0015a000)
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x0044b000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00741000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00250000)
    /lib/ld-linux.so.2 (0x00a75000)

Now, when I compile it and link it with boost_thread, it grows to 8290 bytes:

    linux-gate.so.1 =>  (0x009d9000)
    libboost_thread.so.1.40.0 => /usr/lib/libboost_thread.so.1.40.0 (0x00e59000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x003a3000)
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bc5000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00f8a000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
    libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00bf0000)
    librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00dd8000)
    /lib/ld-linux.so.2 (0x00ba3000)

Note that there is no function call on my code to features of boost_thread. However, boost_thread is added anyway as a dependency of my application (as you can see on the output of ldd).

疯到世界奔溃 2024-11-23 04:36:35

链接到共享库与链接静态库不同。 @Dietrich Epp 已经解释了主要差异,但还有另一个重要细节。共享库定义了函数void _init()void _fini(void),它们在加载/卸载共享库时被调用;如果您没有自己定义它们,链接器将添加默认存根。

如果您将程序链接到共享库,但不引用库中的任何符号(并且不添加 --as-needed 链接器标志),这些也会被调用。

Linking to a shared library is different than linking a static library. The main differences were explained already by @Dietrich Epp, but there's another important detail. Shared libraries define functions void _init() and void _fini(void) which are called upon loading/unloading a shared library; if you don't define them yourself the linker will add default stubs.

Those will be called also if you link your program against a shared library, but don't reference any symbol from the library (and don't add --as-needed linker flag).

離殇 2024-11-23 04:36:35

大多数链接器会简单地从最终的二进制文件中省略未使用的对象,就像您一开始就没有链接到库一样。

Most linkers will simply omit the unused objects from the final binary, exactly as if you hadn't linked with the library in the first place.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文