[ELF] Support copy relocation on non-default version symbols
authorFangrui Song <i@maskray.me>
Thu, 5 Aug 2021 17:32:14 +0000 (10:32 -0700)
committerFangrui Song <i@maskray.me>
Thu, 5 Aug 2021 17:32:14 +0000 (10:32 -0700)
commit72d070b4db2da7216f63f09407bd96f49dc90bd1
tree1a60c1b98d86cd7f1efea8c5fab5a98dac36b897
parenta46bcc60e52fe080ee87af1788e8cdc00f9c035f
[ELF] Support copy relocation on non-default version symbols

Copy relocation on a non-default version symbol is unsupported and can crash at
runtime. Fortunately there is a one-line fix which works for most cases:
ensure `getSymbolsAt` unconditionally returns `ss`.

If two non-default version symbols are defined at the same place and both
are copy relocated, our implementation will copy relocated them into different
addresses. The pointer inequality is very unlikely an issue. In GNU ld, copy
relocating version aliases seems to create more pointer inequality problems than
us.

(
In glibc, sys_errlist@GLIBC_2.2.5 sys_errlist@GLIBC_2.3 sys_errlist@GLIBC_2.4
are defined at the same place, but it is unlikely they are all copy relocated in
one executable. Even if so, the variables are read-only and pointer inequality
should not be a problem.
)

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D107535
lld/ELF/Relocations.cpp
lld/test/ELF/Inputs/copy-rel-version.s
lld/test/ELF/copy-rel-version.s