Explanation of Memcpy Memmove Glibc_2.14/2.2.5

Please help to understand the following memcpy code from GLIBC_2.14

This looks like glibc's dynamic linking resolver function that returns a function pointer (in %rax) based on CPUID, e.g. selecting the AVX version on CPUs that support it.

This resolver override runs once, during dynamic linking (e.g. on the first call if you use lazy dynamic linking).

And yes, this is the code you'll find at the symbol name memcpy.

Related: perf report shows this function "__memset_avx2_unaligned_erms" has overhead. does this mean memory is unaligned? talks about that memset implementation, which the generic dispatcher selected on that asker's CPU.

Note that glibc is open source, you can look at the hand-written commented asm source like for its memcpy / memmove implementations, e.g. https://code.woboq.org/userspace/glibc/sysdeps/x86_64/multiarch/memmove-avx-unaligned-erms.S.html

Linking against older symbol version in a .so file

Just link memcpy statically - pull memcpy.o out of libc.a ar x /path/to/libc.a memcpy.o (whatever version - memcpy is pretty much a standalone function) and include it in your final link. Note that static linking may complicate licensing issues if your project is distributed to the public and not open-source.

Alternatively, you could simply implement memcpy yourself, though the hand-tuned assembly version in glibc is likely to be more efficient

Note that memcpy@GLIBC_2.2.5 is mapped to memmove (old versions of memcpy consistently copied in a predictable direction, which led to it sometimes being misused when memmove should have been used), and this is the only reason for the version bump - you could simply replace memcpy with memmove in your code for this specific case.

Or you could go to static linking, or you could ensure that all systems on your network have the same or better version than your build machine.

Upgraded to Debian 7.5; now 'memcpy@GLIBC_2.14' is undefined

You need to recompile the Boost log library against the upgraded glibc. The .so file you have now was compiled against a previous version.

How to strip symbol version information from the symbol dependency table of a shared library in Linux?

I need a way to strip (or change, if stripping is not possible) the symbol version information from the symbol dependency table of a shared library in Linux, so I can work around the memcpy@GLIBC_2.14 disaster,

Stripping symbol version info

  • is not possible without rebuilding a lot of internal ELF structures inside the linked binary (i.e. impossible in practice) and
  • (even if you succeeded) will not produce a binary that will work on older GLIBC.

so I can make my binaries work on Linuxes with glibc older than 2.14 again.

You can find approaches to "build on newer system, run on older one" here.



Related Topics



Leave a reply



Submit