Search code examples
c++g++mipscross-compilinglinkage

How to solve C++ conflicts between system and library dependencies


My problem is rather specific, but bear with me. This in the end is kinda reverse engineering, but this problem in particular seems to fit more this board.

So, I have a shared object compiled for MIPS written in C++. I don't have the source code of the lib. The lib is compiled using GCC 4.3.3. I want to use functions present in this shared object in my amd64 computer running elementary OS. To do this, I used the sourcery cross compiler to cross compile some C++ code to MIPS, that would use this object.

So far I managed this except for this one compile error, which I cannot figure out. The lib is called libdvl.so, and uses as dependency libc.so.0 (and both are in the same folder as the cpp code).

mips-linux-gnu-g++ -g -L/path/to/lib -Wl,-rpath,/path/to/lib -o verifier verifier.cpp -ldvl

which gives me

(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: warning: libc.so.0, needed by /path/to/lib/libdvl.so, may conflict with libc.so.6
(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: errno@@GLIBC_PRIVATE: TLS definition in (...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6 section .tbss mismatches non-TLS definition in /path/to/lib/libc.so.0 section .bss
/path/to/lib/libc.so.0: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

So I added "-l:libc.so.0" and got this

(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: errno: TLS definition in (...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6 section .tbss mismatches non-TLS definition in libc.so.0 section .bss
(...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libc.so.6: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

Any idea how to solve this? I know I am using GCC 4.9.1, but I already downloaded the older code sourcery version which uses GCC 4.3.154 and got the exact same error.

EDIT 1: Exactly as Lol4t0 said, filtered using c++filt it gives an actual function name from stdc++. Using

mips-linux-gnu-g++ -g -L/path/to/lib -Wl,-rpath,/path/to/lib -I/path/to/lib -o verifier verifier.cpp -ldvl -l:libuClibc++.so.0 -l:libutil.so.0 -l:libc.so.0 -l:ld-uClibc.so.0 -nodefaultlibs

to give to libdvl its depencies (as I will not rewrite stdc++ :p), I get the following compile error:

(...)/mgc/embedded/codebench/bin/../lib/gcc/mips-linux-gnu/4.9.1/../../../../mips-linux-gnu/bin/ld: /tmp/cc66DLda.o: undefined reference to symbol '_Unwind_Resume@@GCC_3.0'
(...)/mgc/embedded/codebench/bin/../mips-linux-gnu/libc/lib/libgcc_s.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

I already confirmed lib dependencies and the order in which they appear. Any thoughts on this?

Thanks for all the help.


Solution

  • You are linking against GLIBC (libc.so.6) and some other libc (libc.so.0).

    That could never work: you have to have everything compiled and linked against a single, consistent libc.

    Since your libdvl.so uses as dependency libc.so.0, and assuming you can't rebuild libdvl.so, you have to use crosscompiler that targets libc.so.0 (which is possibly dietlibc, or uClibc), and compile and link everything else using that toolchain. Your crosscompiler on the other hand appears to target GLIBC, and will not do you any good.

    After a lot of trial and error, you may be able to link the final binary using inconsistent builds, and your binary may even get to main (that is very unlikely). But chances of such binary actually working correctly are minuscule.