ELF patching tool that strips versioned symbol information from dynamically
linked binaries.

Use this to build a binary with a new toolchain that can run on older systems.

`objcopy --remove-section .gnu.version --remove-section .gnu.version_r` should
be used to remove symbol versioning sections from your binary.
`strip-versioned-symbols` removes the remaining references to these sections
from the .dynamic section by removing all DT_VERSYM, DT_VERNEED, and
DT_VERNEEDNUM entries.

Removing these sections without removing the .dynamic entries that point to
them will make ld.so complain with "unsupported version 0 of Verneed record" or
similar; ld.so will still follow the file offset listed in DT_VERNEED even if
there are no sections of type `SHT_GNU_verneed`.

Some symbol versioning detritus (e.g. strings that look like "GLIBC_2.2.5")
will remain in your binary's .dynstr section.

Link your binaries with `-Wl,--hash-style=both` for compatibility with really
old glibc (pre-871b91589bf4f6dfe19d5987b0a05bd7cf936ecc, around 2006-06-10)
versions that don't support DT_GNU_HASH-only binaries.

ELF symbol versioning is a misfeature. Existing workarounds for building
executables using new toolchains while maintaining compatibility with older
systems are ludicrous and labor-intensive. As far as I can tell, neither strip
nor objcopy allow you to remove DT_VERSYM, DT_VERNEED, or DT_VERNEEDNUM. And
neither ld nor lld let you opt out of using symbol versioning.

Note that, when resolving an unversioned symbol, the behavior of glibc's ld.so
is not the same as the behavior of `dlsym`. `dlsym` ostensibly finds the
"default" versioned symbol (the thing with a '@@', rather than a '@', as in
@@GLIBC_WHY_DID_THEY_DO_THIS) while ld.so is supposed find the "earliest"
versioned symbol. See 2b and 5 in
https://sourceware.org/pipermail/libc-alpha/2017-April/080127.html and see
https://sourceware.org/pipermail/libc-alpha/2017-April/080160.html. In reality
something weirder happens:
https://sourceware.org/bugzilla/show_bug.cgi?id=12977.

This means that if, for whatever reason, you're stuck using POSIX condition
variables, you won't have access to `CLOCK_MONOTONIC` timeouts via
`pthread_condattr_setclock` unless you use `dlsym` to find `pthread_cond_init`
and the related functions.

Thanks to Mark Laws (https://github.com/drvink/) for his knowledge of ELF
esoterica and for random related conversations.

Also see:
- https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html
- https://guru.multimedia.cx/ld-so-gnu-linkerloader/