This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Allow relative relocations to absolute symbols in PIC
Needs ReviewPublic

Authored by phosek on Oct 30 2016, 9:39 PM.

Details

Reviewers
ruiu
pcc
Summary

While these might cause an overflow at runtime on some targets, lld shouldn't reject such a case as it's clearly meaningful and supported by both BFD ld and gold.

Diff Detail

Repository
rL LLVM

Event Timeline

phosek updated this revision to Diff 76350.Oct 30 2016, 9:39 PM
phosek retitled this revision from to [ELF] Relative relocations to absolute symbols in PIC.
phosek updated this object.
phosek added a reviewer: ruiu.
phosek set the repository for this revision to rL LLVM.
phosek added a project: lld.
phosek added a subscriber: llvm-commits.
ruiu added a reviewer: pcc.Oct 30 2016, 9:46 PM

+pcc who wrote this code.

I ran into this issue while looking a linker script failure described in bug 30406. The failure was caused by the check in ELF/Relocation.cpp. While debugging the issue, I noticed that both BFD ld and gold handle this case and don't throw an error for the relocation-relative-absolute.s test case.

This is really a corner case behavior that's not document very well by the ELF specification, so I got in touch with Ian Lance Taylor and his opinion on this is:

It's an unusual case, but the only possible meaning of this is a call to the absolute address. The linker needs to either generate a dynamic PC-relative relocation to an SHN_ABS symbol (which could of course overflow at runtime on x86_64) or generate a PLT with a JMP_SLOT reference to an SHN_ABS symbol. I don't see how anything else is correct. In particular I don't see how it is correct to reject such a case, it's clearly meaningful and the technique is used on, at least, pre-VDSO GNU/Linux and AIX.

The problem is that neither BFD ld nor gold do this, instead they both generate an absolute jump. This change changes the lld behavior to match the current behavior of ld and gold. If were to implement the behavior Ian suggested, we'd have to also modify the scanRelocs function, in particular the part which handles the constant case and generate a dynamic relocation when the expression is relative relocation to an absolute symbol.

phosek retitled this revision from [ELF] Relative relocations to absolute symbols in PIC to [ELF] Allow relative relocations to absolute symbols in PIC.Oct 30 2016, 9:48 PM
phosek edited edge metadata.
pcc edited edge metadata.Oct 30 2016, 10:24 PM
pcc added a subscriber: rafael.

I don't see why we should switch from rejecting to doing the wrong thing. The right thing to do, as Ian suggested, would be to create either a PLT entry or a dynamic relocation.

Independently of that, as I and Rafael mentioned on the review thread for D25560, we need to fix the synthetic symbols we create for linker scripts.

phosek updated this revision to Diff 80617.Dec 7 2016, 9:19 AM
phosek updated this object.
phosek edited edge metadata.
phosek added a comment.Dec 7 2016, 9:36 AM

We run into this issue again in our codebase when linking the C library (based on musl) with lld. I've reduced that case into a new test case which I've added to the patch. While the solution that Ian suggested may be the "right thing", it's clearly not what BFD ld nor gold implement and it's unlikely that their implementation is going to change. Since there is code out there relying on this behavior, it'd be useful for lld to support it.

ruiu added a comment.Dec 8 2016, 12:41 PM

Sorry for the belated response. I wonder if it is hard to create a dynamic relocation for this case. Even though it is not what GNU linkers do, I don't think doing the same because they do it wrongly is the right thing, unless we really need a bug-to-bug compatibility. Is this a case that we need a bug-compatibility?

phosek updated this revision to Diff 80864.Dec 8 2016, 8:50 PM

This appears to be working, please take a look. The only question is whether we should be also generating the relocation in the weak case or keep it as a special case same as before?

phosek updated this revision to Diff 87340.Feb 6 2017, 4:52 PM
phosek updated this revision to Diff 87494.Feb 7 2017, 12:05 PM

Added tests.

phosek removed a reviewer: mcgrathr.
phosek added a subscriber: mcgrathr.
emaste added a subscriber: emaste.Jul 17 2017, 6:36 AM