目标文件符号成为可执行文件中的动态符号

时间:2014-10-10 08:17:40

标签: c++ g++ ld dlopen dlsym

我有几个从构建系统中吐出的目标文件(来自C ++)。他们有几个extern "C" - 我希望在程序中使用的关键符号,并且可以从其他地方通过dlopen / dlsym访问。

当使用gcc编译成可执行文件时,这些符号不会使用nm -D <executable-here>列出(即afaik它们不是动态符号)。

如何让它们在编译的可执行文件中作为动态符号公开?

我可以更改目标文件和可执行文件的构建标志,但是更改C ++文件在最终可执行文件中的结束方式(即不首先将它们转换为目标文件)很困难。

(GCC 4.8,ld 2.24)

编辑:我遇到过这个问题,可能是也可能不是我要问的问题,但我并不完全确定。 Use dlsym on a static binary

1 个答案:

答案 0 :(得分:3)

您可以查看--export-dynamic ld选项:

   -E
   --export-dynamic
   --no-export-dynamic
       When creating a dynamically linked executable, using the -E option
       or the --export-dynamic option causes the linker to add all symbols
       to the dynamic symbol table.  The dynamic symbol table is the set
       of symbols which are visible from dynamic objects at run time.

       If you do not use either of these options (or use the
       --no-export-dynamic option to restore the default behavior), the
       dynamic symbol table will normally contain only those symbols which
       are referenced by some dynamic object mentioned in the link.

       If you use "dlopen" to load a dynamic object which needs to refer
       back to the symbols defined by the program, rather than some other
       dynamic object, then you will probably need to use this option when
       linking the program itself.

       You can also use the dynamic list to control what symbols should be
       added to the dynamic symbol table if the output format supports it.
       See the description of --dynamic-list.

       Note that this option is specific to ELF targeted ports.  PE
       targets support a similar function to export all symbols from a DLL
       or EXE; see the description of --export-all-symbols below.

此外,如果链接期间没有任何对象引用您的外部符号,您可能希望将它们放入--dynamic-list以确保它们被导出。


示例:

$ cat test.cc
#include <stdio.h>

int main() {
    printf("Hello, world\n");
}

extern "C" void export_this() {
    printf("Hello, world from export_this\n");
}

$ g++ -o test -W{all,extra} -Wl,--export-dynamic test.cc

$ ./test
Hello, world

$ nm --dynamic test | grep export_this
00000000004007f5 T export_this # <---- here you go