Detecting unresolved symbols in an ELF executable

2k views Asked by At

Let's say I have two files:

// shared.c (will be compiled to 'shared.so')
#include <stdio.h>
int f() { printf("hello\n"); }

and

// exe.c (will be compiled to 'exe')
#include <stdio.h>
int f();
int main() { 
    int i;
    scanf("%d", &i);
    if (i == 5) f(); 
}

I compile both files as following:

gcc -shared shared.c -o libshared.so
gcc exe.c -o exe -lshared -L.

When I run exe and type 5, it will call f and then exit. However, if I delete f from shared.c and recompile it I will get a runtime symbol lookup error only if I type 5. Is there a way that I can check that exe has all its symbols that will work independent of user input in this case? Preferrably without running it.

2

There are 2 answers

1
Eugene Sh. On BEST ANSWER

You can use ldd -r exe command to list the shared library dependencies. Here is my output for your example without the f function:

$ LD_LIBRARY_PATH=. ldd -r ./exe
        linux-vdso.so.1 (0x00007ffcfa7c3000)
        libshared.so => ./libshared.so (0x00007f303a02e000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003e26c00000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003e26400000)
undefined symbol: f     (./exe)

(Don't mind the LD_LIBRARY_PATH=. part. It is used to tell to look for shared libraries in the current directory)

3
pavan On

@tohava When you compile the executable and link it with the shared object, ld (linker) checks if all referenced symbols are available in the list of shared objects your executable is dependent on and will throw an error if any symbol was unresolved.

So, I am not sure how you managed to get a runtime error when you removed f() from the shared library and rebuilt the executable. (I did the exercise myself and got the linker error).