[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