================
@@ -0,0 +1,176 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "InjectPointerSigningFixups.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/Triple.h"
+
+using namespace llvm;
+
+namespace {
+
+struct PtrAuthFixup {
+  GlobalVariable *GV;
+  ConstantPtrAuth *CPA;
+  SmallVector<unsigned, 4> Indices;
+};
+
+/// Recursively walk a constant looking for ConstantPtrAuth expressions.
+/// When found, record the global variable containing it and the index path
+/// to reach it within the initializer.
+void findPtrAuth(Constant *C, GlobalVariable &GV,
+                 SmallVector<unsigned, 4> &Indices,
+                 SmallVectorImpl<PtrAuthFixup> &Fixups) {
+  if (auto *CPA = dyn_cast<ConstantPtrAuth>(C)) {
+    Fixups.push_back({&GV, CPA, Indices});
+    return;
+  }
+  for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) {
+    if (auto *COp = dyn_cast<Constant>(C->getOperand(I))) {
+      Indices.push_back(I);
+      findPtrAuth(COp, GV, Indices, Fixups);
+      Indices.pop_back();
+    }
+  }
+}
+
+} // namespace
+
+namespace lldb_private {
+
+Error InjectPointerSigningFixupCode(llvm::Module &M,
+                                    ExecutionPolicy execution_policy) {
+  // If we cannot execute fixups, don't insert them.
+  if (execution_policy == eExecutionPolicyNever)
+    return Error::success();
+
+  llvm::Triple T(M.getTargetTriple());
+
+  // Bail out if we don't need pointer signing fixups.
+  if (!T.isArm64e())
+    return Error::success();
+
+  // Collect all ConstantPtrAuth expressions in global initializers.
+  SmallVector<PtrAuthFixup, 8> Fixups;
+  for (auto &G : M.globals()) {
+    if (!G.hasInitializer())
+      continue;
+    SmallVector<unsigned, 4> Indices;
+    findPtrAuth(G.getInitializer(), G, Indices, Fixups);
+  }
+
+  if (Fixups.empty())
+    return Error::success();
+
+  // Set up types and intrinsics.
+  auto &Ctx = M.getContext();
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+  Type *IntPtrTy = Type::getInt64Ty(Ctx);
+  Function *BlendIntrinsic =
+      Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_blend);
+  Function *SignIntrinsic =
+      Intrinsic::getOrInsertDeclaration(&M, Intrinsic::ptrauth_sign);
+
+  // Create the fixup function.
+  Function *FixupFn = Function::Create(
+      FunctionType::get(Type::getVoidTy(Ctx), false),
+      GlobalValue::InternalLinkage, "lldb.arm64.sign_pointers", &M);
+  FixupFn->insert(FixupFn->end(), BasicBlock::Create(Ctx));
+  IRBuilder<> B(&FixupFn->back());
+
+  for (auto &Fixup : Fixups) {
+    GlobalVariable *GV = Fixup.GV;
+    ConstantPtrAuth *CPA = Fixup.CPA;
+
+    // Build a GEP to the location of the ConstantPtrAuth within the global.
+    Value *Loc;
+    if (Fixup.Indices.empty()) {
+      Loc = GV;
+    } else {
+      SmallVector<Value *, 4> GEPIndices;
+      GEPIndices.push_back(ConstantInt::get(Int32Ty, 0));
+      for (unsigned Idx : Fixup.Indices)
+        GEPIndices.push_back(ConstantInt::get(Int32Ty, Idx));
+      Loc = B.CreateGEP(GV->getValueType(), GV, GEPIndices);
+    }
+
+    Type *PtrTy = CPA->getType();
+
+    // Load the raw (unsigned) pointer.
+    Value *RawPtr = B.CreateLoad(PtrTy, Loc);
----------------
JDevlieghere wrote:

I added a defensive check just to be sure so we don't have to rely on 
assumptions about the generator of the IR.

https://github.com/llvm/llvm-project/pull/186001
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to