[ELF] Fix branch range computation when picking ThunkSection
authorFangrui Song <i@maskray.me>
Tue, 3 May 2022 15:46:15 +0000 (08:46 -0700)
committerFangrui Song <i@maskray.me>
Tue, 3 May 2022 15:46:15 +0000 (08:46 -0700)
commit3bc79808d06343f712728e1491f31a45383d9803
tree4f6bd22c71e1b1c3ea6ff50631a0ba5eb041c61f
parent2929c34da665fa83246f68d07bbefe0653e7d225
[ELF] Fix branch range computation when picking ThunkSection

Similar to D117734. Take AArch64 as an example when the branch range is +-0x8000000.

getISDThunkSec returns `ts` when `src-0x8000000-r_addend <= tsBase < src-0x8000000`
and the new thunk will be placed in `ts` (`ts->addThunk(t)`). However, the new
thunk (at the end of ts) may be unreachable from src. In the next pass,
`normalizeExistingThunk` reverts the relocation back to the original target.
Then a new thunk is created and the same `ts` is picked as before. The `ts` is
still unreachable.

I have observed it in one test with a sufficiently large r_addend (47664): there
are initially 245 Thunk's, then in each pass 14 new Thunk's are created and get
appended to the unreachable ThunkSection. After 15 passes lld fails with
`thunk creation not converged`.

The new test aarch64-thunk-reuse2.s checks the case.

Without `- pcBias`, arm-thumb-thunk-empty-pass.s and arm-thunk-multipass-plt.s
will fail.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D124653
lld/ELF/Relocations.cpp
lld/test/ELF/aarch64-thunk-reuse2.s [new file with mode: 0644]