This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF][AArch64] Change the semantics of -z pac-plt.
ClosedPublic

Authored by danielkiss on Feb 13 2020, 2:26 AM.

Details

Summary

Generate PAC protected plt only when "-z pac-plt" is passed to the
linker. GNU toolchain generates when it is explicitly requested[1].
When pac-plt is requested then set the GNU_PROPERTY_AARCH64_FEATURE_1_PAC
note even when not all function compiled with PAC but issue a warning.
Harmonizing the warning style for BTI/PAC/IBT.
Generate BTI protected PLT if case of "-z force-bti".

[1] https://www.sourceware.org/ml/binutils/2019-03/msg00021.html

Diff Detail

Event Timeline

danielkiss created this revision.Feb 13 2020, 2:26 AM
peter.smith accepted this revision.Feb 13 2020, 6:11 AM

One query aside, this looks good to me. The original idea for glibc was to automatically have the dynamic loader sign the .plt.got entries on the presence of AARCH64_PAC_PLT, it turns out that those patches haven't been accepted in glibc yet. Android does not use lazy binding and marks the .plt.got as RELRO so PAC isn't much use there. I've marked as approved, but please wait a day or so to see if there are any comments from other timezones.

lld/ELF/Arch/AArch64.cpp
597

Unless I missed something, the || config->forceBTI shouldn't be necessary due to forceBTI always adding GNU_PROPERTY_AARCH64_FEATURE_1_BTI to all objects if it isn't there already.

// Driver.cpp
if (config->forceBTI && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
      warn(toString(f) + ": -z force-bti: file does not have "
                         "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
      features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
    }
This revision is now accepted and ready to land.Feb 13 2020, 6:11 AM

Adding other regular reviewers.

danielkiss marked an inline comment as done.Feb 13 2020, 8:24 AM
danielkiss added inline comments.
lld/ELF/Arch/AArch64.cpp
597

lld/test/ELF/aarch64-feature-btipac.s:156 will fail without it because in that test the AArch64BtiPac::AArch64BtiPac() runs before the getAndFeatures().
I guess the PLT generation for the passed so runs before the flags are processed in the driver.

MaskRay added a comment.EditedFeb 13 2020, 8:57 PM

Unless I missed something, the || config->forceBTI shouldn't be necessary due to forceBTI always adding GNU_PROPERTY_AARCH64_FEATURE_1_BTI to all objects if it isn't there already.

Adding config->pacPlt to getTargetInfo() is problematic. getTargetInfo() is called twice.

readConfig(); // config->pacPlt is set. config->andFeatures is 0
target = getTarget();

config->andFeatures = getAndFeatures<ELFT>();
target = getTarget();

I think the following two changes should be dropped, i.e. applying

--- c/lld/ELF/Arch/AArch64.cpp
+++ w/lld/ELF/Arch/AArch64.cpp
@@ -595,4 +595,3 @@ private:
 AArch64BtiPac::AArch64BtiPac() {
-  btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ||
-              config->forceBTI;
+  btiHeader = config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
   // A BTI (Branch Target Indicator) Plt Entry is only required if the
@@ -692,4 +691,4 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
 static TargetInfo *getTargetInfo() {
-  if ((config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ||
-      config->pacPlt) {
+  if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
+                             GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
     static AArch64BtiPac t;

Committed 105a270028abb7a0237dd2af3ddba07471d8c49d to rename pacPlt to zPacPlt and forceBti to zForceBti after D71327. The patch will need a rebase.

The title needs a change. I don't think there is a bug, so fix may not be very appropriate.
The patch changes the semantics of -z pac-plt.

MaskRay accepted this revision.Feb 13 2020, 9:07 PM
MaskRay added inline comments.
lld/test/ELF/aarch64-feature-btipac.s
173

-NEXT:

MaskRay added inline comments.Feb 13 2020, 9:46 PM
lld/ELF/Arch/AArch64.cpp
597

See https://reviews.llvm.org/D74537#1875597

The change should be dropped.

693

The change should be dropped.

danielkiss retitled this revision from [LLD][ELF][AArch64] Fix plt generation for PAC/BTI. to [LLD][ELF][AArch64] Change the semantics of -z pac-plt..
danielkiss marked 4 inline comments as done.
MaskRay added inline comments.Feb 14 2020, 4:52 PM
lld/ELF/Arch/AArch64.cpp
608

Unless I missed something, this change is not needed

lld/ELF/SyntheticSections.cpp
1403

Unless I missed something, this change is not needed

danielkiss marked 2 inline comments as done.Feb 15 2020, 2:18 AM
danielkiss added inline comments.
lld/ELF/Arch/AArch64.cpp
608

If all object has GNU_PROPERTY_AARCH64_FEATURE_1_PAC then it could trigger the PAC protected PLT generation that we want to avoid.
PAC protection for PLT is only needed when explicitly requested because usually it is not needed because PLT.GOT is in a read only memory.
With this change the PAC protected PLT will be generated only in case of -z pac-plt.

lld/ELF/SyntheticSections.cpp
1403

same as above.

MaskRay accepted this revision.Feb 15 2020, 8:49 AM

LG. This needs a pacPlt -> zPacPlt rebase.

danielkiss updated this revision to Diff 244886.EditedFeb 16 2020, 9:03 AM

Rebased to 105a270028ab and rename pacPlt to zPacPlt is applied.

MaskRay accepted this revision.Feb 16 2020, 1:45 PM

Could you submit it on my behalf?

This revision was automatically updated to reflect the committed changes.