4

I am trying to test the LD_LIBRARY_PATH environment variable. I have a program test.c as follows:

int main()
{
     func("hello world");
}

I have two files func1.c and func2.c:

// func1.c
#include <stdio.h>
void func(const char * str)
{
     printf("%s", str);
}

And

// func2.c
#include <stdio.h>
void func(const char * str)
{
     printf("No print");
}

I want to do the following somehow:

  • Convert func1.c and func2.c to .so files - both with same name func.so (they will be placed in different folders, say dir1 and dir2
  • Compile test.c s.t. I only mention that it has a dependency func.so, but I don't tell it where it is (I want the environment variable to be used to find this)
  • Set the environment variable, in first try to dir1 and in second try to dir2 to observe different output in each run of test program

Is the above doable ? If so, how to do step 2 ?

I did the following for step 1 (same steps for func2):

$ gcc -fPIC -g -c func1.c
$ gcc -shared -fPIC -o func.so func1.o
4

Use ld -soname:

$ mkdir dir1 dir2
$ gcc -shared -fPIC -o dir1/func.so func1.c -Wl,-soname,func.so
$ gcc -shared -fPIC -o dir2/func.so func2.c -Wl,-soname,func.so
$ gcc test.c dir1/func.so
$ ldd a.out
    linux-vdso.so.1 =>  (0x00007ffda80d7000)
    func.so => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f639079e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6390b68000)
$ LD_LIBRARY_PATH='$ORIGIN/dir1:$ORIGIN/dir2' ./a.out
hello world
$ LD_LIBRARY_PATH='$ORIGIN/dir2:$ORIGIN/dir1' ./a.out
No print

-Wl,-soname,func.so (this means -soname func.so is passed to ld) embeds SONAME attribute of func.so in the output. You can examine it by readelf -d:

$ readelf -d dir1/func.so 

Dynamic section at offset 0xe08 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [func.so]
...

Linked with this func.so with SONAME, a.out has that in its NEEDED attribute:

$ readelf -d a.out

Dynamic section at offset 0xe18 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [func.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...

Without -Wl,-soname,func.so, you'll get the following by readelf -d:

$ readelf -d dir1/func.so 

Dynamic section at offset 0xe18 contains 24 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...

$ readelf -d a.out

Dynamic section at offset 0xe18 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [dir1/func.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...
  • Why after specifying func.so in dir1, still results in not found in ldd after the gcc step ? – Jake Sep 2 '15 at 12:10
  • Updated my answer. It's because NEEDED is set to func.so` and dynamic linker (/lib64/ld-linux-x86-64.so.2) cannot find it in library search path. ld sets it to SONAME if DSO has it, otherwise the path name passed in arguments. – yaegashi Sep 2 '15 at 12:31
  • I tried a similar test, but instead to create a dummy libc.so.6 library (the library C file just has a printf() definition which is empty). When I try to run my test program (which depends on libc.so.6 and uses printf()), it displays: symbol __cxa_finalize not defined .. what does that mean ? – Jake Sep 8 '15 at 8:20
  • 1
    Executables and DSOs created by gcc depend on many symbols in libc.so.6 implicitly. Your own libc.so.6 must provide all of them as original libc.so.6 does. readelf -s (your)program | grep UND and readelf -s (your)libc.so.6 | grep UND show such symbols undefined and to be provided by others. Regarding just replacing printf() in libc.so.6, you might want to use LD_PRELOAD hook of glibc. There are many docs and resources on this topic, for example this question. – yaegashi Sep 8 '15 at 10:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.