clarification first: ELF files often have two character tables. there is a bold or full one that contains all the internal characters (usually in a section named .symtab type SHT_SYMTAB ), and there is a thin one that contains only runtime information (usually in a section named .dynsym type SHT_DYNSYM ) . nm analyzes only the first, so it is often not a good indicator of runtime behavior. you want to use readelf -s instead and look at the .dynsym table to see what actually matters at runtime.
(1) I do not know why the debug symbol table does not include full version control of symbols when using gold. seems to me a mistake.
(2) as soon as you look at the runtime character table, your answer will appear on its own: pthread_cond_broadcast@GLIBC _2.3.2 will be used.
(2a) for which the library will load this symbol, which depends entirely on how ELF was linked and the runtime. let it ignore all the possibilities and focus on the general: if you are associated with -lpthread, then the version in libpthread.so will be used. if you did not, then the version in libc.so will be used.
(2b) why does one library have more than one version (for example, libc.so has pthread_cond_broadcast@ @GLIBC_2.2.5 and pthread_cond_broadcast@ @GLIBC_2.3.2 )? You correctly guessed that this is for backward compatibility. at some point in the past, the ABI was changed, so instead of breaking all existing applications, they updated the version. all programs that were associated with the old version of glibc will use the old versions of the characters, while new programs will use the new characters. as a policy, glibc provides the latest version of the character as standard, so when you use pthread_cond_broadcast , you will be associated with pthread_cond_broadcast@ @GLIBC_2.3.2 . this is a pure convention that most users use ... although it is technically possible to set any of them as the default version.
(2c) why does the symbol exist in both libc.so and libpthread.so? this allows libraries to support multi-threaded environments without penalty in a single-threaded environment or without the need to write two different libraries. one named libfoo.so and one named libfoo_thread.so. characters in libc.so are dummy characters - they always return "success". therefore, if your main program is not multithreaded, all calls to libfoo.so will be deleted. but if your main program is multi-threaded (i.e. links to -lpthread), the characters will be transparently and automatically redirected to libpthread.so, and all calls to libfoo.so will be DTRT (i.e., capture mutexes / etc ...) .
source share