================ @@ -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
