Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do shared libraries work in a mixed 64bit/32bit system?

Good morning,

on a 64bit RedHat box we have to compile and run a 32bit application. Meanwhile I managed to compile the gcc version needed (4.0.3) and all required runtime libraries in 32bit and have set the LD_LIBRARY_PATH to point to the 32bit versions, but now during the remaining build process, a small java program needs to be executed which is installed in /usr/bin as a 64bit program, which now finds the 32bit version of libgcc_s.so first.

In general, if I set the LD_LIBRARY_PATH to the 32bit versions, I break the 64bit programs and vice versa.

How it this supposed to work at all? I am certain I am not the first person with this problem at hand. How is it solved usually?

Regards, Stefan

like image 849
struppi Avatar asked Nov 10 '09 08:11

struppi


People also ask

Will 32 bit and 64 bit combination compatible and will work together?

In short: You can't link a 32-bit app to a 64-bit library. You can run a 32-bit application, using 32-bit shared libraries on a 64-bit OS (at least all the popular 32-/64-bit processors such as AMD, Intel and Sparc). But that doesn't involve any libraries.

Can a 64 bit application use a 32 bit library?

No. You can't directly link to 32bit code inside of a 64bit program. The best option is to compile a 32bit (standalone) program that can run on your 64bit platform (using ia32), and then use a form of inter-process communication to communicate to it from your 64bit program.


3 Answers

Add both the 32-bit and 64-bit directories to the LD_LIBRARY_PATH.

If you do this, then the ld.so for 32-bit or 64-bit will use the correct libraries.

e.g. A 32-bit test app "test32" and 64-bit test app "test", with a locally-installed copy of a (newer version of) gcc and binutils in a user homedir, to avoid clobbering the system-wide install of gcc:

=> export LD_LIBRARY_PATH=/home/user1/pub/gcc+binutils/lib:/home/user1/pub/gcc+binutils/lib64

=> ldd ./test32
    libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib/libstdc++.so.6 (0x00111000)
    libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib/libgcc_s.so.1 (0x00221000)

=> ldd ./test
    libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib64/libstdc++.so.6 (0x00007ffff7cfc000)
    libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib64/libgcc_s.so.1 (0x00007ffff7ad2000)

(Less interesting library paths removed)

This shows that the loaders know to ignore the libraries of the wrong architecture, at least on this Scientific Linux 6.3 (RHEL-derived) system. I would expect other distros to work similarly, but haven't tested this.

This may have only started being the case more recently than your (unspecified) distro version, however.

like image 73
David Gardner Avatar answered Oct 19 '22 20:10

David Gardner


On Solaris one can use LD_LIBRARY32_PATH and LD_LIBRARY64_PATH, but that isn't supported on Linux.

In general, you should just never need to set LD_LIBRARY_PATH at all in the first place:

  • either install needed libraries into /usr/lib32 or /usr/lib64 as appropriate, or
  • build your 32-bit application with -Wl,-rpath=/path/to/32-bit/libs
like image 44
Employed Russian Avatar answered Oct 19 '22 21:10

Employed Russian


As a workaround, wrap the Java call in a small shell script which unsets LD_LIBRARY_PATH and then calls the executable. Alternatively, this might also work:

LD_LIBRARY_PATH= java...

Note the space between "=" and the name of the executable.

like image 33
Aaron Digulla Avatar answered Oct 19 '22 20:10

Aaron Digulla