GLIBC dependancy - c

I have a binary which needs some *.so files to execute.
Now when I try to execute it on some older machines it shows
/lib/libc.so.6: version `GLIBC_2.4' not found
how can I change its search path to /lib/i386-linux-gnu/libc.so.6 from /lib/libc.so.6
So I can run two different libc files on a same machine.

Are you on a 32-Bit system and maybe trying to execute a binary that uses the 64 bit glibc?
Modifying the library search path can be done by using LD_LIBRARY_PATH variable, e.g. in a subshell:
(export LD_LIBRARY_PATH=/lib/i386-linux-gnu:${LD_LIBRARY_PATH}; my_program)

You can change the search path by using the LD_LIBRARY_PATH environment variable when calling your binary.
Something along the lines of:
LD_LIBRARY_PATH=/lib/i386-linux-gnu/libc.so.6 ./your_binary
should work. Bear in mind that depending on the shell you're using you might need to call either export or env to set the variable.
You can check if it's working using the following command:
LD_LIBRARY_PATH=/lib/i386-linux-gnu/libc.so.6libc.so.6 ldd ./your_binary
linux-vdso.so.1 => (0x00007fff140e9000)
libselinux.so.1 => /lib/libselinux.so.1 (0x008f9000)
librt.so.1 => /lib/librt.so.1 (0x006f1000)
libacl.so.1 => /lib/libacl.so.1 (0x004e8000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00129000)
libdl.so.2 => /lib/libdl.so.2 (0x00f25000)
/lib/ld-linux.so.2 (0x003b3b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00d07000)
libattr.so.1 => /lib/libattr.so.1 (0x00b02000)
You just need to check if libc.so.6 is being resolved to the shared object that you want.
UPDATE: It seems that you want to load a 32 bit shared object for a 64 bit binary. As far as I know there is no way to do this since the target architectures are different and the loader will refuse to load the 32 bit so. If this is your case, this might explain why the loader loads the default libc. Depending on your case, it might be possible to compile the binary as 32 bits, in which case it should run with a 32 bit libc.

If you want to run 32-bit executables on a 64-bit machine, you'll need to install the 32 bit versions. On Fedora or other systems with yum run:
yum install glibc.i686
(note the .i686 suffix, it asks specifically for the 32 bit versions) and try again. The ldd(1) command should help identifying the needed libraries, and yum should be smart enough to find them by the name it gives.

Related

How to get library path from SONAME?

I'm developing a ldd-python script.
As far as I know, ELF binary itself has information only about library's SONAME.
How can I get library's full path by this SONAME?
I want to print like this original ldd result:
$ ldd test
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7d28000)
ldd prints this information by running ld.so in special mode (LD_TRACE_LOADED_OBJECTS). So your only options are to run ldd internally and parse it's output or try to model it's behavior in Python (but note that such model would have to be quite complex, especially once you get to setuid binaries).

Setting shared libraries prefix when compiling

I'm trying to compile a program, I need to set a prefix path on shared library path, I try using -Wl,-rpath -Wl,-dynamic-linker and what I got from ldd was:
linux-vdso.so.1 => (0x00007fff75336000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f19d55b8000)
/pathtolib/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000055d3d67e1000)
but what I expecting to get was:
linux-vdso.so.1 => (0x00007fff75336000)
libc.so.6 => /pathtolib/lib/x86_64-linux-gnu/libc.so.6 (0x00007f19d55b8000)
/pathtolib/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000055d3d67e1000)
I really need to setup this and force program to use non-default path (/pathtolib) for all shared libraries.
this is the command I used to compile:
gcc list/list.c -o bin/list -Wl,-rpath,/pathtolib -Wl,--dynamic-linker,/pathtolib/lib64/ld-linux-x86-64.so.2
what did I do wrong?!! :|
The -rpath option does not specify a prefix for individual directories in the search path; rather, it specifies a colon-delimited list of paths. The dynamic linker searches these directories first, but it continues on to the rest of the search path if it needs to do. Thus, if you want the dynamic linker to resolve libc.so.6 to /pathtolib/lib/x86_64-linux-gnu/libc.so.6, then you must specify not /pathtolib but /pathtolib/lib/x86_64-linux-gnu in your rpath.
I am not aware of a link option or ELF header field that would instruct the dynamic linker to do what you seem to be asking: to modify the standard library search path by prefixing each element. If you want to do something like that, then you probably need to provide your own dynamic linker.
Alternatively, perhaps you want to construct and use a chroot environment instead of of messing with rpaths. That requires considerably more work to set up, but it would have the effect of allowing you to use a whole different set of libraries.

How do I call or use a 64-bit Shared Library(.SO) file in Linux?

I'm relatively new to Linux and am having trouble trying to figure out the intricacies of .SO files and how (64-bit) shared libraries(and their versions, dependencies etc) work; and how to link them and use them in a basic C++ program??
The scenario is this: I have a shared library file(single physical file) called libfaidtz.so.3.0.0_debian6_64bit. I have installed Debian(latest version) 64-bit on VMWare. I have installed (I believe) all the basic C++ development tools use apt-get.
Now I wish to write a simple program in C++ that will LINK libfaidtz.so.3.0.0_debian6_64bit, and enable me to call two specific functions "exported" by this .so file. Unfortunately, the environment/system set up on my machine is preventing me from linking to this library successfully.
Can anyone guide me on this please?
I have included below, some pertinent details regarding the .SO file it self. The function I wish to use(from the .SO file) has the following function-prototype(and should work):
int32_t DEF_EXPORT TZ_FAID_Size(int64_t start_time,
int32_t roster_count,
int64_t * roster_from,
int64_t * roster_to,
int32_t * roster_ids,
int32_t & id_cnt);
I'm from a Windows background (Dynamic linking and DLLs-wise) and am struggling to get this .SO file liked and used in a basic C++ test program.
root#debian:/home/maitreya/lib# ldd libfaidtz.so.3.0.0_debian6_64bit
linux-vdso.so.1 => (0x00007fff667ff000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3300a6f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f33007ed000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3300461000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f330024b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3300f93000)
root#debian:/home/maitreya/lib# nm libfaidtz.so.3.0.0_debian6_64bit
0000000000208c70 d DW.ref.__gxx_personality_v0
0000000000006ebb T TZ_FAID_Process
0000000000006e04 T TZ_FAID_Size
0000000000007447 T TZ_FAID_Version
0000000000208028 a _DYNAMIC
0000000000208230 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
00000000000011ca T _Z15FetchExpiryDatePiS_S_
and so on..
If you look at some of the standard libraries installed on your system you will see that they are soft linked. For example: I have /lib/libgpm.so.2.1.0 with a soft link /lib/libgpm.so.
Try creating a soft link libfaidtz.so to your library and then link with -lfaidtz.

KDevelop4: Error while loading shared libraries

I am trying to use the Intel MKL libraries for the first time. I am using CMake to build a simple project in which MKL is used. I work in the KDevelop 4.6 environment.
The project is built and installed without errors. Linking the libraries is thus succesful. While executing within KDevelop, I get the following error:
Error while loading shared libraries: libmkl_intel_lp64.so: cannot open shared object file: No such file or directory
The CMakeLists file looks essentially as follows:
project(testmkl)
cmake_minimum_required(VERSION 2.6)
enable_language(Fortran)
set(CMAKE_C_FLAGS "-std=c99 -Wall -lpthread")
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# MKL
find_package(MKL REQUIRED)
include_directories(${MKL_INCLUDE_DIR})
find_package(M REQUIRED)
include_directories(${M_INCLUDES})
add_executable(testmkl ./main.c)
target_link_libraries(testmkl ${M_LIBRARIES} ${MKL_BLAS} ${MKL_LAPACK} ${MKL_INTEL} ${MKL_SEQUENTIAL} ${MKL_CORE})
install(TARGETS testmkl DESTINATION .)
libmkl_intel_lp64.so is found in the first folder of the LP_LIBRARY_PATH environment variable, so I wouldn't expect any error during the execution. Actually, when running the program from the command window, everything seems to work fine.
The ldd output for the executable is:
>> ldd ./testmkl
linux-vdso.so.1 => (0x00007fff951fe000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003061a00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003061200000)
libmkl_intel_lp64.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_intel_lp64.so (0x00007f6f65ef6000)
libmkl_sequential.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_sequential.so (0x00007f6f65846000)
libmkl_core.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_core.so (0x00007f6f64317000)
libc.so.6 => /lib64/libc.so.6 (0x0000003060e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003060600000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003061600000)
The linked libraries are thus correctly found. Why won't the program work in the KDevelop environment?
Any help is welcome, thanks!
First one short question: are you excuting your program from a terminal or trying to execute from KDE gui (e.g. by double-click)?
On many linux OS, now LD_LIBRARY_PATH is deprecated. LD finds the dependencies thanks to what is listed in /etc/ld.so.conf and /etc/ld.so.conf.d . You may have to add a script somewhere there to include your libraries. In fact you just have to add the path to your libraries in those scripts.
example from /etc/ld.so.conf/libc.conf:
# libc default configuration
/usr/local/lib
This may work for you.
edit:
you shoud also run ldconfig to update the LD database and/or use ldconfig -v, which does the same but with extended output
edit2: ldconfig may require root privileges to be understood by the GUI
I had the same problem and now it solved through configuration of environment variable in kdevelop.
Go to project->open configuration
Select make tab
Click setting icon in Active environment profile bar and add your environment variable:
LD_LIBRARY_PATH = /your/shared/library/path

Dependency resolution in Linux

Under Windows I have used a program called dependency walker to examine the libraries the application is using. I was wondering how I can achieve this on Linux for a standard binary:
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.0, stripped
Thanks.
Try:
ldd executable
For example:
[me#somebox ~]$ ldd /bin/ls
linux-gate.so.1 => (0xb7f57000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f4c000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f32000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f2b000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7ddc000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7dc4000)
/lib/ld-linux.so.2 (0xb7f58000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7dc0000)
libattr.so.1 => /lib/libattr.so.1 (0xb7dbb000)
[me#somebox ~]$
Note that this will only report shared libraries. If you need to find out what static libraries were linked in at compile time, that's a bit trickier, especially seeing as your executable is 'stripped' (no debugging symbols).
Use ldd
ldd /bin/sh
If you want something a little less raw than iteratively calling ldd and somewhat more like MSVC depends, you should try Visual-ldd. It hasn't been updated in 4 years, but it should still work given that the ELF format hasn't changed. It still won't show you individual symbols inside those libraries - for that you'll need something like nm, and I don't know of any GUI wrapper for that, unfortunately.
Use ldd. It will show the dynamic libraries the binary needs.
Note that the libraries themselves may in turn need more libraries. To get these, you can run ldd on the libraries you got from running ldd on the binary.

Resources