Reproducer: $ touch empty.c $ gcc -O2 -fpic -shared empty.c -lmcheck /usr/bin/ld: a.out: version node not found for symbol __malloc_initialize_hook.5 /usr/bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status This looks like a linker limitation. /* If we are building an application, we need to create a version node for this version. */ if (t == NULL && bfd_link_executable (info)) { … } else if (t == NULL) { /* We could not find the version for a symbol when generating a shared archive. Return an error. */ _bfd_error_handler /* xgettext:c-format */ (_("%B: version node not found for symbol %s"), info->output_bfd, h->root.root.string); bfd_set_error (bfd_error_bad_value); sinfo->failed = TRUE; return FALSE; } } I have no idea why it is okay to synthesize a symbol version for an executable, but not for a shared object. This doesn't really make sense.
*** Bug 1575117 has been marked as a duplicate of this bug. ***
(In reply to Florian Weimer from comment #4) Hi Florian, > $ touch empty.c > $ gcc -O2 -fpic -shared empty.c -lmcheck This completes successfully for me, without producing any errors. Do I need a specific version of glibc installed ? (I was using gcc-7.2.1-2.fc27.x86_64, binutils-2.29-13.fc27.x86_64 and glibc-2.26-27.fc27.x86_64). Also - do you know if the bug happens if you use gold instead of ld.bfd ? > This looks like a linker limitation. > I have no idea why it is okay to synthesize a symbol version for an > executable, but not for a shared object. This doesn't really make sense. My assumption - not verified with the binutils community - is that the intention is to force shared libraries to always have complete version information for all of their exported symbols and not leave any to be invented by the linker. Inventing symbol versions for applications should not matter since the application is not going to be linked against anything else. Cheers Nick
(In reply to Nick Clifton from comment #7) > (In reply to Florian Weimer from comment #4) > > Hi Florian, > > > $ touch empty.c > > $ gcc -O2 -fpic -shared empty.c -lmcheck > > This completes successfully for me, without producing any errors. > > Do I need a specific version of glibc installed ? (I was using > gcc-7.2.1-2.fc27.x86_64, binutils-2.29-13.fc27.x86_64 and > glibc-2.26-27.fc27.x86_64). You need glibc from Fedora 28 or rawhide. > Also - do you know if the bug happens if you use gold instead of ld.bfd ? $ gcc --use-ld=gold -O2 -fpic -shared empty.c -lmcheck /usr/bin/ld.gold: error: symbol __malloc_initialize_hook has undefined version GLIBC_2.2.5 collect2: error: ld returned 1 exit status > > This looks like a linker limitation. > > > I have no idea why it is okay to synthesize a symbol version for an > > executable, but not for a shared object. This doesn't really make sense. > > My assumption - not verified with the binutils community - is that the > intention is to force shared libraries to always have complete version > information for all of their exported symbols and not leave any to be > invented by the linker. Inventing symbol versions for applications should > not matter since the application is not going to be linked against anything > else. Hmm. -lmcheck is interposing a definition of __malloc_initialize_hook with an initializer, so this is really a fringe case, and it is technically an export (from both the main program and a DSO).
Hang on a sec. If __malloc_initialize_hook is deprecated, why is the libdrizzle library referencing it ? It seems to me that the problem here is that the mcheck library is exporting a deprecated symbol, which it should not be doing. The linker is getting confused because the symbol is defined, but there is no version information for it. Rather than invent a version, the linker complains and stops. To me this seems like correct behaviour.
(In reply to Nick Clifton from comment #9) > Hang on a sec. If __malloc_initialize_hook is deprecated, why is the > libdrizzle library referencing it ? We deprecated the hook without realizing that -lmcheck would stop working due to the way the interposition works with a compatibility symbol (the .symver is new, it wasn't there in the first place). > It seems to me that the problem here is that the mcheck library is exporting > a deprecated symbol, which it should not be doing. The linker is getting > confused because the symbol is defined, but there is no version information > for it. Rather than invent a version, the linker complains and stops. To > me this seems like correct behaviour. I'm not so sure, but I can see the rationale (there is no symbol version ordering, for example). We will not fix this in glibc. -lmcheck is going away anyway, in favor of a different mechanism.