28

我最近在 GNU ld 中发现了链接器选项“-Bsymbolic-functions”:

-Bsymbolic
  When creating a shared library, bind references to global symbols to the 
  definition within the shared library, if any. Normally, it is possible 
  for a program linked against a shared library to override the definition 
  within the shared library. 

  This option is only meaningful on ELF platforms which support shared libraries.

-Bsymbolic-functions
  When creating a shared library, bind references to global function symbols 
  to the definition within the shared library, if any.  

  This option is only meaningful on ELF platforms which support shared libraries.

这似乎与 GCC 选项相反,-fvisibility=hidden因为它不是阻止将引用的函数导出到其他共享对象,而是阻止对该函数的库内部引用绑定到不同共享对象的导出函数。我告诉自己这-Bsymbolic-functions将阻止为函数创建 PLT 条目,这是一个很好的副作用。

  1. 但我想知道是否可能对此进行更细粒度的控制,例如覆盖-Bsymbolic库的各个函数定义。

  2. 我应该知道使用的任何陷阱-Bsymbolic-functions吗?我打算只使用它,因为-Bsymbolic我认为这会破坏异常(我认为它会使对 typeinfo 对象的引用不统一)。

谢谢!

4

4 回答 4

26

回答我自己的问题,因为我刚刚为此获得了 Tumbleweed 徽章……后来我发现了

但我想知道是否可能对此进行更细粒度的控制,例如覆盖-Bsymbolic库的各个函数定义。

是的,有一个选项--dynamic-list可以做到这一点

我应该知道使用的任何陷阱-Bsymbolic-functions吗?我打算只使用它,因为我认为 -Bsymbolic 会破坏异常(我认为它会使对 typeinfo 对象的引用不统一)。

我仔细研究了一下,似乎没有问题。libstdc++ 库显然做到了,或者至少考虑过,他们只需要添加--dynamic-list-cpp-new到仍然operator new统一(以防止多个分配器/释放器在程序中混合的问题,但我认为这样的程序无论如何都会被破坏)。Ubuntu 使用它或默认使用它,它似乎会导致与某些软件包发生冲突。但总的来说,我期望它应该能很好地工作。

于 2011-09-03T20:12:41.500 回答
2

好吧,您可以说这是一个“强化”选项,因为它确保您对库内函数的调用肯定会结束。但我发现的一个问题是一些项目测试套件。

例如,libvirt 测试套件会想要调用刚刚构建的 libvirt0.so,但也会模拟一些将从那里完成的调用。

由于-Bsymbolic-functions在破坏测试的构建上使用原始函数而不是调用模拟函数。

回溯示例 好案例:

#0  virHostCPUGetThreadsPerSubcore (arch=VIR_ARCH_PPC64) at ../../../tests/virhostcpumock.c:30
#1  0x00007ffff7c1e4c4 in virHostCPUGetInfoPopulateLinux (cpuinfo=<optimized out>, arch=VIR_ARCH_PPC64, cpus=0x7fffffffdf38, mhz=<optimized out>, nodes=0x7fffffffdf40, sockets=0x7fffffffdf44, cores=0x7fffffffdf48, threads=0x7fffffffdf4c)
    at ../../../src/util/virhostcpu.c:661                                           
#2  0x0000555555557e6f in linuxTestCompareFiles (outputfile=0x55555558f150 "/build/libvirt-OUKR8i/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.expected", arch=VIR_ARCH_PPC64,·
    cpuinfofile=0x5555555a3f10 "/build/libvirt-OUKR8i/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.cpuinfo") at ../../../tests/virhostcputest.c:44
#3  linuxTestHostCPU (opaque=<optimized out>) at ../../../tests/virhostcputest.c:189
#4  0x000055555555914d in virTestRun (title=0x55555555c0a1 "subcores2", body=0x555555557cc0 <linuxTestHostCPU>, data=0x7fffffffe0c0) at ../../../tests/testutils.c:176
#5  0x000055555555781a in mymain () at ../../../tests/virhostcputest.c:263          
#6  0x0000555555559df4 in virTestMain (argc=1, argv=0x7fffffffe2c8, func=0x5555555577b0 <mymain>) at ../../../tests/testutils.c:1114
#7  0x00007ffff79bb09b in __libc_start_main (main=0x5555555576a0 <main>, argc=1, argv=0x7fffffffe2c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe2b8) at ../csu/libc-start.c:308
#8  0x00005555555576ea in _start () at ../../../tests/virhostcputest.c:278 

坏情况:

#0  virHostCPUGetThreadsPerSubcore (arch=arch@entry=VIR_ARCH_PPC64) at ../../../src/util/virhostcpu.c:1119
#1  0x00007ffff7c27e04 in virHostCPUGetInfoPopulateLinux (cpuinfo=<optimized out>, arch=VIR_ARCH_PPC64, cpus=0x7fffffffdea8, mhz=<optimized out>, nodes=0x7fffffffdeb0, sockets=0x7fffffffdeb4, cores=0x7fffffffdeb8, threads=0x7fffffffdebc)
    at ../../../src/util/virhostcpu.c:661                                           
#2  0x0000555555557e6f in linuxTestCompareFiles (outputfile=0x5555555a5c30 "/build/libvirt-4biJ7f/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.expected", arch=VIR_ARCH_PPC64,·
    cpuinfofile=0x55555558fd20 "/build/libvirt-4biJ7f/libvirt-4.10.0/tests/virhostcpudata/linux-ppc64-subcores2.cpuinfo") at ../../../tests/virhostcputest.c:44
#3  linuxTestHostCPU (opaque=<optimized out>) at ../../../tests/virhostcputest.c:189
#4  0x000055555555914d in virTestRun (title=0x55555555c0a1 "subcores2", body=0x555555557cc0 <linuxTestHostCPU>, data=0x7fffffffe030) at ../../../tests/testutils.c:176
#5  0x000055555555781a in mymain () at ../../../tests/virhostcputest.c:263          
#6  0x0000555555559df4 in virTestMain (argc=1, argv=0x7fffffffe238, func=0x5555555577b0 <mymain>) at ../../../tests/testutils.c:1114
#7  0x00007ffff79b009b in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#8  0x00005555555576ea in _start () at ../../../tests/virhostcputest.c:278 

比较这两者的来源virHostCPUGetThreadsPerSubcore,您会发现差异。

我见过的另一个案例是:

由于最初的问题是关于潜在的缺点,我认为值得一提的是那些有些常见的相关问题类别。

于 2019-01-09T09:00:14.420 回答
0

有副作用的情况。一个记录在案的: https ://bugs.launchpad.net/ubuntu/+source/xfe/+bug/644645 我也想了解更多,因为我现在有这样的情况。

于 2013-12-22T12:17:49.487 回答
0

也不建议使用 -Bsymbolic-functions 构建 glibc。这是我得到的结果:

Core was generated by `/home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/elf/ld-linux                                                               .'.
Program terminated with signal 11, Segmentation fault.
#0  0x400a3e90 in _int_free ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
(gdb) where
#0  0x400a3e90 in _int_free ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#1  0x4016b94b in __libc_dlsym ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#2  0x4004c2c7 in __gconv_find_shlib ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#3  0x40042320 in find_derivation ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#4  0x40042889 in __gconv_find_transform ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#5  0x400d6f00 in __wcsmbs_load_conv ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#6  0x400c86f6 in mbrtowc ()
   from /home/lano1106/dev/packages/glibc/repos/core-i686/src/glibc-build/libc.so.6
#7  0x08048914 in ?? ()
#8  0x00000000 in ?? ()
于 2014-01-08T19:06:59.183 回答