21

It's well known that glibc (and, as far as I know, glibstd++ also) uses symbol versioning mechanism. (For the details refer: How can I link to a specific glibc version.)

The question is how to determine exact versions of GLIBC and GLIBCXX will be chosen by linker for names from libc and libstdc++? For example, how to get something like this:

time -> time@GLIBC_2_5
...
gethostbyname -> gethostbyname@GLIBC_2_3

Why do we need this? It seems to me that it can be useful if you want to minimize required versions of glibc/libstdc++.

1

3 Answers 3

36

One thing you can try is running objdump -T on your binary. For example, here's how to see that the /usr/sbin/nordvpnd binary on my system depends on GLIBC version at least 2.18:

$ objdump -T /usr/sbin/nordvpnd | grep GLIBC_ | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | sort -Vu      
2.2.5
2.3
2.3.2
2.3.3
2.3.4
2.4
2.7
2.8
2.9
2.10
2.14
2.15
2.16
2.17
2.18

If you are considering linking to older versions of symbols, be aware that these older versions may depend on older, different structures or other definitions as well. To avoid this, compile and link with older, matching header files and libraries.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, jilles. It works. One more question, how to get location in code from which dynamic symbol is called? I mean, for example, if 'objdump -T' returns some entry, say GLIBCXX_3.4.9 Insert_, how to understand which functions in sources use this symbol?
hmm, I don't really know a better solution than running objdump -t over all the .o files and checking which ones contain references to the function. It seems that this can be done better as the linker knows where an unresolved symbol was used.
I would only add that for shared libraries "objdump -T" does not work and I am using the solution "ldd -v somelibrary.so" (-v is important) which was described on askubuntu.com/questions/163138/…
7
objdump -T  bin-file | grep -Eo 'GLIBC_\S+' | sort -u

Comments

0

you can also use nm

nm -D <executable> | grep GLIBC_ |sort -t. -k2 -n

for example, the output could be

                 U pthread_mutex_unlock@GLIBC_2.2.5
                 w pthread_once@GLIBC_2.2.5
                 U pthread_self@GLIBC_2.2.5

take the maximum version number. One advantage is you can see the weak symbols (V, v, W, w, see https://www.man7.org/linux/man-pages/man1/nm.1.html ), so that if the glibc version is ≥ that of all the non-weak symbols version but < some of the weak symbols, the program may still run.

you can use readelf as well

readelf -W --syms <executable> | grep GLIBC_

this option is used by cf-nvidia-tools conda-forge package.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.