[llvm-branch-commits] [lld] [PAC][lld] Use PAC instructions in PLT header with `-z pac-plt` (PR #116334)
Daniil Kovalev via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 15 00:05:20 PST 2024
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/116334
1. Sign return address before storing into stack.
2. Treat lazy resolver address as signed.
>From 7fbca897414b538d2b528cc8ca54a89d38ba3c6d Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 21 Oct 2024 16:46:22 +0300
Subject: [PATCH] [PAC][lld] Use PAC instructions in PLT header with `-z
pac-plt`
1. Sign return address before storing into stack.
2. Treat lazy resolver address as signed.
---
lld/ELF/Arch/AArch64.cpp | 30 ++++++++++++++++++++++++---
lld/test/ELF/aarch64-feature-btipac.s | 4 ++--
lld/test/ELF/aarch64-feature-pac.s | 6 +++---
lld/test/ELF/aarch64-feature-pauth.s | 8 ++++---
4 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index c64a0dbe8bd62b..8382195f47e1f4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -1040,13 +1040,23 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
+ const uint8_t signLR[] = {0x7f, 0x23, 0x03, 0xd5}; // pacibsp
const uint8_t pltData[] = {
0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.got.plt[2]))
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.got.plt[2]))]
0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.got.plt[2]))
- 0x20, 0x02, 0x1f, 0xd6, // br x17
- 0x1f, 0x20, 0x03, 0xd5, // nop
+ };
+ const uint8_t pacHintBr[] = {
+ 0x9f, 0x21, 0x03, 0xd5, // autia1716
+ 0x20, 0x02, 0x1f, 0xd6 // br x17
+ };
+ const uint8_t pacBr[] = {
+ 0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16
+ 0x1f, 0x20, 0x03, 0xd5 // nop
+ };
+ const uint8_t stdBr[] = {
+ 0x20, 0x02, 0x1f, 0xd6, // br x17
0x1f, 0x20, 0x03, 0xd5 // nop
};
const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
@@ -1061,15 +1071,29 @@ void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
buf += sizeof(btiData);
plt += sizeof(btiData);
}
+ if (pacEntry) {
+ memcpy(buf, signLR, sizeof(signLR));
+ buf += sizeof(signLR);
+ plt += sizeof(signLR);
+ }
memcpy(buf, pltData, sizeof(pltData));
relocateNoSym(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
getAArch64Page(got + 16) - getAArch64Page(plt + 4));
relocateNoSym(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
relocateNoSym(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
+
+ if (pacEntry)
+ memcpy(buf + sizeof(pltData), (pacUseHint ? pacHintBr : pacBr),
+ sizeof(pacUseHint ? pacHintBr : pacBr));
+ else
+ memcpy(buf + sizeof(pltData), stdBr, sizeof(stdBr));
if (!btiHeader)
// We didn't add the BTI c instruction so round out size with NOP.
- memcpy(buf + sizeof(pltData), nopData, sizeof(nopData));
+ memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData));
+ if (!pacEntry)
+ // We didn't add the PACIBSP instruction so round out size with NOP.
+ memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData));
}
void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
diff --git a/lld/test/ELF/aarch64-feature-btipac.s b/lld/test/ELF/aarch64-feature-btipac.s
index 3b3c1744370362..caba4862059e8b 100644
--- a/lld/test/ELF/aarch64-feature-btipac.s
+++ b/lld/test/ELF/aarch64-feature-btipac.s
@@ -155,13 +155,13 @@ func1:
# BTIPACEX2: Disassembly of section .plt:
# BTIPACEX2: 0000000000210380 <.plt>:
# BTIPACEX2-NEXT: 210380: bti c
+# BTIPACEX2-NEXT: pacibsp
# BTIPACEX2-NEXT: stp x16, x30, [sp, #-16]!
# BTIPACEX2-NEXT: adrp x16, 0x230000
# BTIPACEX2-NEXT: ldr x17, [x16, #1208]
# BTIPACEX2-NEXT: add x16, x16, #1208
+# BTIPACEX2-NEXT: autia1716
# BTIPACEX2-NEXT: br x17
-# BTIPACEX2-NEXT: nop
-# BTIPACEX2-NEXT: nop
# BTIPACEX2: 00000000002103a0 <func2 at plt>:
# BTIPACEX2-NEXT: 2103a0: adrp x16, 0x230000
# BTIPACEX2-NEXT: ldr x17, [x16, #1216]
diff --git a/lld/test/ELF/aarch64-feature-pac.s b/lld/test/ELF/aarch64-feature-pac.s
index 4fd1fd2acea737..e2b385a61ef448 100644
--- a/lld/test/ELF/aarch64-feature-pac.s
+++ b/lld/test/ELF/aarch64-feature-pac.s
@@ -96,14 +96,14 @@
# PACPLT-NEXT: 210378: ret
# PACPLT: Disassembly of section .plt:
# PACPLT: 0000000000210380 <.plt>:
-# PACPLT-NEXT: 210380: stp x16, x30, [sp, #-16]!
+# PACPLT-NEXT: 210380: pacibsp
+# PACPLT-NEXT: stp x16, x30, [sp, #-16]!
# PACPLT-NEXT: adrp x16, 0x230000
# PACPLT-NEXT: ldr x17, [x16, #1192]
# PACPLT-NEXT: add x16, x16, #1192
+# PACPLT-NEXT: autia1716
# PACPLT-NEXT: br x17
# PACPLT-NEXT: nop
-# PACPLT-NEXT: nop
-# PACPLT-NEXT: nop
# PACPLT: 00000000002103a0 <func2 at plt>:
# PACPLT-NEXT: 2103a0: adrp x16, 0x230000
# PACPLT-NEXT: ldr x17, [x16, #1200]
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index c50f38f4a7c975..b8b0baa50051b7 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -65,13 +65,15 @@
# PACPLT-NEXT: ret
# PACPLT: Disassembly of section .plt:
# PACPLT: <.plt>:
+# PACPLT-NEXT: pacibsp
# PACPLT-NEXT: stp x16, x30, [sp, #-0x10]!
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>
# PACPLT-NEXT: ldr x17, [x16, #0x[[B]]]
# PACPLT-NEXT: add x16, x16, #0x[[B]]
-# PACPLT-NEXT: br x17
-# PACPLT-NEXT: nop
-# PACPLT-NEXT: nop
+# NOHINT-NEXT: braa x17, x16
+# NOHINT-NEXT: nop
+# HINT-NEXT: autia1716
+# HINT-NEXT: br x17
# PACPLT-NEXT: nop
# PACPLT: <func3 at plt>:
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>
More information about the llvm-branch-commits
mailing list