创建共享库时强制链接器导出已解析的符号

发布于 2024-09-06 23:25:17 字数 3040 浏览 9 评论 0原文

我正在使用 c++ -shared 创建一个共享库(这是在 x86_64 上运行的 gcc)。我无法将问题简化为最小的测试用例,但我遇到的问题是我正在从一堆 .o 文件中创建一个 .so 。其中一个 .o 文件导出一个符号(nm 显示“D”),我希望从 .so 导出该符号。其他 .o 需要该符号(nm 显示“U”)。结果,链接器使该符号在生成的 .so 中成为本地符号(nm 显示“d”)。

如果我从命令行中删除所需的 .o,则 .so 确实 会导出该符号。因此,链接器似乎正在决定,由于其他 .o 用于构建 .so 需要该符号,因此它必须被那些 .o 需要,并且不需要真正导出。

当我尝试构建一个最小的测试用例时,它不会以这种方式工作;无论我是否添加需要它的 .o,该符号​​总是被导出。

我的完整命令行是:

c++ -fno-rtti -fno-exceptions -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wcast-align -Wno-invalid-offsetof -Wno-可变宏-学究-Wno-long-long -gdwarf-2 -fno-strict-aliasing -pthread -pipe -DDEBUG -D_DEBUG -DDEBUG_sfink -DTRACING -gdwarf-2 -fPIC -shared -Wl,-z,defs -Wl ,-h,libmozjs.so -o libmozjs.so jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun。 o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf .o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o Assembler.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o CTypes.o Library.o mozjs-dtrace.o -lpthread - Wl,-rpath-link,/bin -Wl,-rpath-link,/lib -Wl,--whole-archive ctypes/libffi/.libs/libffi.a -Wl,--no-whole-archive -L/家/sfink/moz-central/obj-dtrace/dist/lib -lplds4 -lplc4 -lnspr4 -lpthread -ldl -ldl -lm -lm -ldl

我与它调用的核心命令得到了相同的行为(我还手动删除了一些不相关的标志):

/usr/bin/ld --no-add-needed --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -shared -o libmozjs.so /usr/lib/gcc/x86_64 -redhat-linux/4.4.4/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtbeginS.o -L/usr /lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 /../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4 .4/../../.. jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun.o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf。 o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o 汇编器.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o mozjs-dtrace.o -lnspr4 -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../ ../lib64/crtn.o

更新:可能更重要的是,这些符号位于不同的部分,并且具有隐藏的可见性。使用 objcopy 使它们全局化并没有帮助。我不知道哪些部分用于哪些用途的规则是什么。

I am creating a shared library using c++ -shared (which is gcc running on x86_64). I can't manage to strip my problem down to a minimal test case, but the issue I'm having is that I am creating a .so out of a bunch of .o files. One of those .o files exports a symbol (nm shows 'D') that I want exported from the .so. Others of the .o's require that symbol (nm shows 'U'). As a result, the linker makes that symbol local in the resulting .so (nm shows 'd').

If I eliminate the requiring .o's from the command line, the .so does export the symbol. So it seems like the linker is deciding that since other .o's used to build the .so require the symbol, that it must only be needed by those .o's and it needn't be exported for real.

When I try to construct a minimal test case, it doesn't work this way; the symbol is always exported whether or not I add in a .o that requires it.

My full command line is:


c++ -fno-rtti -fno-exceptions -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wcast-align -Wno-invalid-offsetof -Wno-variadic-macros -pedantic -Wno-long-long -gdwarf-2 -fno-strict-aliasing -pthread -pipe -DDEBUG -D_DEBUG -DDEBUG_sfink -DTRACING -gdwarf-2 -fPIC -shared -Wl,-z,defs -Wl,-h,libmozjs.so -o libmozjs.so jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun.o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf.o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o Assembler.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o CTypes.o Library.o mozjs-dtrace.o -lpthread -Wl,-rpath-link,/bin -Wl,-rpath-link,/lib -Wl,--whole-archive ctypes/libffi/.libs/libffi.a -Wl,--no-whole-archive -L/home/sfink/moz-central/obj-dtrace/dist/lib -lplds4 -lplc4 -lnspr4 -lpthread -ldl -ldl -lm -lm -ldl

I get the same behavior with the core command that this invokes (I also manually pruned out some irrelevant flags):


/usr/bin/ld --no-add-needed --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -shared -o libmozjs.so /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../.. jsapi.o jsarena.o jsarray.o jsatom.o jsbool.o jscntxt.o jsdate.o jsdbgapi.o jsdhash.o jsdtoa.o jsemit.o jsexn.o jsfun.o jsgc.o jsgcchunk.o jshash.o jsinterp.o jsinvoke.o jsiter.o jslock.o jslog2.o jsmath.o jsnativestack.o jsnum.o jsobj.o json.o jsopcode.o jsparse.o jsproxy.o jsprf.o jspropertycache.o jspropertytree.o jsregexp.o jsscan.o jsscope.o jsscript.o jsstr.o jstask.o jstypedarray.o jsutil.o jswrapper.o jsxdrapi.o jsxml.o prmjtime.o jsdtracef.o jstracer.o Assembler.o Allocator.o CodeAlloc.o Containers.o Fragmento.o LIR.o njconfig.o RegAlloc.o avmplus.o NativeX64.o jsbuiltins.o VMPI.o mozjs-dtrace.o -lnspr4 -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64/crtn.o

Update: probably more importantly, those symbols are in a different section, and have hidden visibility. Using objcopy to make them global doesn't help. I don't know what the rules are for which sections to use for what.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文