[llvm] 0cfd20e - [JITLink][arm64][MachO] Apply PAC signing to __mod_init_func pointers.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 16:19:06 PST 2024


Author: Lang Hames
Date: 2024-11-22T11:18:52+11:00
New Revision: 0cfd20ed1b8561a5d4587e8f624f9b4c8efd8b6f

URL: https://github.com/llvm/llvm-project/commit/0cfd20ed1b8561a5d4587e8f624f9b4c8efd8b6f
DIFF: https://github.com/llvm/llvm-project/commit/0cfd20ed1b8561a5d4587e8f624f9b4c8efd8b6f.diff

LOG: [JITLink][arm64][MachO] Apply PAC signing to __mod_init_func pointers.

The __mod_init_func section contains pointers to static initializer functions.
In the static compilation model for MachO/arm64e these are unsigned pointers
that are signed by dyld before being called. This patch teaches JITLink's
MachO/arm64 backend to sign __mod_init_func pointers using the PAC signing
function introduced in a432f11a52d (signing is triggered by rewriting all
Pointer64 edges in the section to Pointer64Authenticated edges). This means
that unlike the static compilation model the linked __mod_init_func section
will contain signed pointers.

Note: Signing of init pointers could instead have been handled by the ORC
runtime in a manner similar to dyld, but this would have come at the cost of
adding an extra signing oracle. Using the signing function avoids this.

Testing this change requires execution. It is covered by the
trivial-cxx-constructor.cpp testcase that was added to the ORC runtime in
7c0786363e6.

Added: 
    

Modified: 
    llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
index 5607963e377432..6a947828a5e61e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
@@ -594,6 +594,35 @@ createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) {
       .buildGraph();
 }
 
+static Error applyPACSigningToModInitPointers(LinkGraph &G) {
+  assert(G.getTargetTriple().getSubArch() == Triple::AArch64SubArch_arm64e &&
+         "PAC signing only valid for arm64e");
+
+  if (auto *ModInitSec = G.findSectionByName("__DATA,__mod_init_func")) {
+    for (auto *B : ModInitSec->blocks()) {
+      for (auto &E : B->edges()) {
+        if (E.getKind() == aarch64::Pointer64) {
+
+          // Check that we have room to encode pointer signing bits.
+          if (E.getAddend() >> 32)
+            return make_error<JITLinkError>(
+                "In " + G.getName() + ", __mod_init_func pointer at " +
+                formatv("{0:x}", B->getFixupAddress(E).getValue()) +
+                " has data in high bits of addend (addend >= 2^32)");
+
+          // Change edge to Pointer64Authenticated, encode signing:
+          // key = asia, discriminator = 0, diversity = 0.
+          Edge::AddendT SigningBits = 0x1ULL << 63;
+          E.setKind(aarch64::Pointer64Authenticated);
+          E.setAddend(E.getAddend() | SigningBits);
+        }
+      }
+    }
+  }
+
+  return Error::success();
+}
+
 void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
                       std::unique_ptr<JITLinkContext> Ctx) {
 
@@ -626,6 +655,7 @@ void link_MachO_arm64(std::unique_ptr<LinkGraph> G,
 
     // If this is an arm64e graph then add pointer signing passes.
     if (G->getTargetTriple().isArm64e()) {
+      Config.PostPrunePasses.push_back(applyPACSigningToModInitPointers);
       Config.PostPrunePasses.push_back(
           aarch64::createEmptyPointerSigningFunction);
       Config.PreFixupPasses.push_back(


        


More information about the llvm-commits mailing list