本文介绍了gcc 无效版本(最大)错误添加符号:错误值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在 Linux x86_x64 上成功构建了几个 32 位静态和共享库,现在我正在尝试将它们链接到一个可执行文件,但出现以下错误:

I've successfully build several 32 bit, static and Shared, libraries on Linux x86_x64 and I'm now trying to link them together to an executable and I get the following error:

/usr/bin/ld: foo.so: __moddi3: invalid version 21 (max 0)

foo.so: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

其中 foo.so 是我构建的共享库之一.

where foo.so is one of the shared libraries I built.

__moddi3 函数是 libgcc 整数库例程的一部分.它的签名是:

the __moddi3 function is part of the libgcc Integer Library Routines. Its signature is:

— Runtime Function: long __moddi3 (long a, long b)

它的作用是为 32 位代码提供 64 位算法.

And its role is to provide 64 bit arithmetic for 32 bit code.

我什至找不到这个库版本的含义.

I can't even find the meaning of the versions of this library.

为什么我现在看到这个错误 - 在库已经构建之后?

我使用 -fPIC-m32 标志构建了所有共享库,用于编译和链接.

I built all the shared libs with -fPIC and -m32 flag for compiling and linking.

可执行文件是 CXX 可执行文件.

The executable is CXX executable.

这是带有 --verbose 的链接器输出

here's the linker output with --verbose

Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/32/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/:/lib/i386-linux-gnu/:/lib/../lib32/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib32/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/i386-linux-gnu/:/lib/:/usr/lib/i386-linux-gnu/:/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-m32' '-v' '-o' '../BIN/Y' '-L/home/X/W/Y/LibTee/lib/Linux' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=i686'
 /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccM5EczN.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib/ld-linux.so.2 -z relro -o ../BIN/Y /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/32/crtbegin.o -L/home/X/W/Y/LibTee/lib/Linux -L/usr/lib/gcc/x86_64-linux-gnu/5/32 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32 -L/lib/i386-linux-gnu -L/lib/../lib32 -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib32 -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. -L/lib/i386-linux-gnu -L/usr/lib/i386-linux-gnu -rpath /home/X/W/Y/LibTee/lib/Linux:/home/X/W/Y/BIN -ltee ../openssl/Lib/Linux/libssl.a ../IPP_5_3_1_064/IA32/lib/Linux/libippcore.a ../IPP_5_3_1_064/IA32/lib/Linux/libippcp.a ../IPP_5_3_1_064/IA32/lib/Linux/libipps.a ../BIN/libCryptoDataGen.so -lgcc -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5/32/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib32/crtn.o
/usr/bin/ld: ../BIN/libCryptoDataGen.so: __moddi3: invalid version 21 (max 0)
../BIN/libCryptoDataGen.so: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

推荐答案

所以,我找到了解决方案.问题是:

So, I found the solution. The problem was:

我构建了一个共享库 - foo.so.foo 与一些静态链接图书馆.我发现其中很多都包含了 __moddi3 函数以及更多 libgcc 的东西.

I built a shared library - foo.so. foo was linked with some static libraries. I found that a lot of them included the __moddi3 function along with more libgcc stuff.

我试图将 foo.so 链接到一个可执行栏.bar 还链接到静态库,其中很多还包括__moddi3 函数以及更多 libgcc 内容.

I was trying to link foo.so to an executable bar. bar also linked against static libraries and a lot of them also included the __moddi3 function along with more libgcc stuff.

问题在于 foo.so 导出了它从静态库中获取的符号 - __moddi3 函数就是这些符号之一.在此处查看场景的详细封面.所以显然发生的事情是可执行文件采用了一些与 libgcc 不兼容的东西由 foo 导出的 __moddi3 函数版本,然后当链接器遇到 __moddi3 版本时 - 它引发了关于我试图链接不兼容的版本.

The problem was that foo.so exported symbols it took from the static libraries - the __moddi3 function was among those symbols. See here a detailed cover of the scenario. So apparently what happened is that the executable took some libgcc stuff that weren't compatible with the __moddi3 function version that was exported by foo, Then when the linker encountered the __moddi3 version - It raised an error about me trying to link incompatible versions.

解决方案在上一个链接中给出.处理这个问题的方法是使用一个导出列表,您可以在其中告诉编译器导出想要的符号并隐藏所有其他符号(使用通配符 *).
由于我使用的是 CMake - 我将 -Wl,--version-script,exportmap 添加到 set_target_properties(foo PROPERTIES LINK_FLAGS.'exportmap' 是我的导出列表的名称文件,格式为:

The Solution is given in the previous link. The way to deal with this is to use an export list in which you tell the compiler to export wanted symbols and hide all other symbols (using wildcard *).
Since I'm using CMake - I added -Wl,--version-script,exportmap to set_target_properties(foo PROPERTIES LINK_FLAGS. 'exportmap' is the name of my export list file. It's in the format of:

    {
    global:
         func_1;
         func_2;
         func_3;
    local:
         *;
    }

如果您不使用 CMake,请将 -Wl,--version-script,exportmap 添加到 makefile 中的 C_FLAGSCXX_FLAGS.

If you're not using CMake add -Wl,--version-script,exportmap to C_FLAGS or CXX_FLAGS in the makefile.

使用 readelf -Ws foo.so 查看您的导出符号表.

use readelf -Ws foo.so to see your export symbols table.

这是关于该主题的另一本不错的读物.

这篇关于gcc 无效版本(最大)错误添加符号:错误值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 08:12