This is an archive of the discontinued LLVM Phabricator instance.

[ELF][PPC32] Support canonical PLT
ClosedPublic

Authored by MaskRay on Jan 24 2020, 6:10 PM.

Details

Summary

-fno-pie produces a pair of non-GOT-non-PLT relocations R_PPC_ADDR16_{HA,LO} (R_ABS) referencing external
functions.

lis 3, func@ha
la 3, func@l(3)

In a -no-pie/-pie link, if func is not defined in the executable, a canonical PLT entry (st_value>0, st_shndx=0) will be needed.
References to func in shared objects will be resolved to this address.
-fno-pie -pie should fail with "can't create dynamic relocation ... against ...", so we just need to think about -no-pie.

On x86, the PLT entry passes the JMP_SLOT offset to the rtld PLT resolver.
On x86-64: the PLT entry passes the JUMP_SLOT index to the rtld PLT resolver.
On ARM/AArch64: the PLT entry passes &.got.plt[n]. The PLT header passes &.got.plt[fixed-index]. The rtld PLT resolver can compute the JUMP_SLOT index from the two addresses.

For these targets, the canonical PLT entry can just reuse the regular PLT entry (in PltSection).

On PPC32: PltSection (.glink) consists of b PLTresolve instructions and PLTresolve. The rtld PLT resolver depends on r11 having been set up to the .plt (GotPltSection) entry.
On PPC64 ELFv2: PltSection (.glink) consists of __glink_PLTresolve and bl __glink_PLTresolve. The rtld PLT resolver depends on r12 having been set up to the .plt (GotPltSection) entry.

We cannot reuse a b PLTresolve/bl __glink_PLTresolve in PltSection as a canonical PLT entry. PPC64 ELFv2 avoids the problem by using TOC for any external reference, even in non-pic code, so the canonical PLT entry scenario should not happen in the first place.
For PPC32, we have to create a PLT call stub as the canonical PLT entry. The code sequence sets up r11.

Diff Detail

Event Timeline

MaskRay created this revision.Jan 24 2020, 6:10 PM
Herald added a project: Restricted Project. · View Herald Transcript

Unit tests: fail. 62190 tests passed, 1 failed and 815 were skipped.

failed: libc++.std/thread/thread_mutex/thread_mutex_requirements/thread_timedmutex_requirements/thread_timedmutex_recursive/try_lock_until.pass.cpp

clang-tidy: fail. clang-tidy found 0 errors and 2 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

MaskRay updated this revision to Diff 240391.Jan 25 2020, 11:51 AM
MaskRay retitled this revision from [ELF][PPC32] Fix st_value of canonical PLT to [ELF][PPC32] Support canonical PLT.
MaskRay edited the summary of this revision. (Show Details)
MaskRay removed subscribers: wuzish, merge_guards_bot.

.

Unit tests: pass. 62196 tests passed, 0 failed and 815 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 3 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

Excellent! This looks like it fixed the FreeBSD putchar problem for me. I will test this with a full powerpc32 buildworld and report back.

MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 12:20 PM
MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 12:23 PM
MaskRay updated this revision to Diff 240394.Jan 25 2020, 12:41 PM

Fix st_value

Unit tests: fail. 62195 tests passed, 1 failed and 815 were skipped.

failed: lld.ELF/ppc32-canonical-plt.s

clang-tidy: fail. clang-tidy found 0 errors and 5 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

MaskRay updated this revision to Diff 240396.Jan 25 2020, 2:02 PM

Move canonical PLT entries to the beginning of .glink
Otherwise Symbol::getVA is not stable

Unit tests: pass. 62196 tests passed, 0 failed and 815 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 4 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

MaskRay updated this revision to Diff 240398.Jan 25 2020, 3:12 PM

Make glibc work

MaskRay updated this revision to Diff 240399.Jan 25 2020, 3:28 PM

Fix PLTresolve comments

This version looks very promising so far. Will do a full freebsd buildworld test / boot on G4. I expect this version to have fixed the issue, but will verify.

MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 3:33 PM

Unit tests: pass. 62196 tests passed, 0 failed and 815 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 5 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

Unit tests: pass. 62196 tests passed, 0 failed and 815 were skipped.

clang-tidy: fail. clang-tidy found 0 errors and 5 warnings. 0 of them are added as review comments below (why?).

clang-format: pass.

Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml

Pre-merge checks is in beta. Report issue. Please join beta or enable it for your project.

MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 3:54 PM
MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 3:57 PM
MaskRay edited the summary of this revision. (Show Details)Jan 25 2020, 4:02 PM
Bdragon28 accepted this revision.Jan 25 2020, 5:53 PM

Working great!

Tested on a g4. this fixes top, and FreeBSD built with lld10+patch now boots multiuser without any startup programs crashing. (clang and lld crash but that's due to an unrelated issue with thunks in .init and .fini that we will discuss in another differential)

This revision is now accepted and ready to land.Jan 25 2020, 5:53 PM
This revision was automatically updated to reflect the committed changes.