diff --git a/llvm/include/llvm/PARTS/Intrinsics.td b/llvm/include/llvm/PARTS/Intrinsics.td index c7461af4a5f5cf0e4635990e103175f6a8f904c1..9445308839a7cb449f5cbd29168a5f097d00e103 100644 --- a/llvm/include/llvm/PARTS/Intrinsics.td +++ b/llvm/include/llvm/PARTS/Intrinsics.td @@ -9,8 +9,8 @@ //===----------------------------------------------------------------------===// def int_pa_pacia : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem]>; -def int_pa_autia : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem]>; -def int_pa_autcall : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem], "", [SDNPOutGlue]>; +def int_pa_autia : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem, IntrHasSideEffects]>; +def int_pa_autcall : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem, IntrHasSideEffects], "", [SDNPOutGlue]>; def int_pa_pacda : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem]>; def int_pa_autda : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], [IntrNoMem, IntrHasSideEffects]>; def int_pa_xpacd : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>], [IntrNoMem]>; \ No newline at end of file diff --git a/llvm/include/llvm/PARTS/Parts.h b/llvm/include/llvm/PARTS/Parts.h index b4a29e88588542ac6bb3a6a31b9bcb5bddf9ab0b..4c23975f134350c455f4d92abdb7ceb7f119c55f 100644 --- a/llvm/include/llvm/PARTS/Parts.h +++ b/llvm/include/llvm/PARTS/Parts.h @@ -37,7 +37,6 @@ bool useDataPointerProtection(); bool useDataFieldTag(); bool useDataFieldProtection(); PartsBeCfiType getBeCfiType(); -Pass *createPartsPluginPass(); uint16_t getTypeIdFor(const Type *T); } } diff --git a/llvm/lib/PARTS/CMakeLists.txt b/llvm/lib/PARTS/CMakeLists.txt index aa1e5fcff913aea150c0e9f5b709d8f9c8049e41..e0ef75026b9a6c813d3517916e5dd5aef6d6943c 100644 --- a/llvm/lib/PARTS/CMakeLists.txt +++ b/llvm/lib/PARTS/CMakeLists.txt @@ -1,6 +1,5 @@ add_llvm_component_library(LLVMParts Parts.cpp - PartsPluginPass.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/PARTS diff --git a/llvm/lib/PARTS/PartsPluginPass.cpp b/llvm/lib/PARTS/PartsPluginPass.cpp deleted file mode 100644 index 97319040e10d9e0c75cad142af994ca66e91c9cf..0000000000000000000000000000000000000000 --- a/llvm/lib/PARTS/PartsPluginPass.cpp +++ /dev/null @@ -1,106 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Author: Zaheer Gauhar -// Hans Liljestrand -// Copyright (C) 2018 Secure Systems Group, Aalto University -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#include "llvm/IR/AbstractCallSite.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/InstrTypes.h" -#include "llvm/IR/Constant.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/Pass.h" -#include "llvm/PARTS/Parts.h" -#include "llvm/Support/Debug.h" -#include "llvm/IR/Attributes.h" - -using namespace llvm; -using namespace llvm::PARTS; - -#define DEBUG_TYPE "PartsPluginPass" - -namespace { - -class PartsPluginPass : public ModulePass { -public: - static char ID; - PartsPluginPass() : ModulePass(ID) {} - bool runOnModule(Module &M) override; - -private: - /* - Check the input Value V and recursively change inner parameters, or if V itself needs to be replaced - in the containint function, then uses give builder to generate PACed value and returns said value. - @param M - @param I - @param V - @return - */ - bool handleInstruction(Function &F, Instruction &I); - CallInst *handleAutCallInstruction(Function &F, Instruction &I, Value *value); -}; - -} - -char PartsPluginPass::ID = 0; -static RegisterPass X("parts-plugin", "PARTS Plugin pass"); - -Pass *llvm::PARTS::createPartsPluginPass() { return new PartsPluginPass(); } - -bool PartsPluginPass::runOnModule(Module &M) { - if (!PARTS::useFeCfi()) - return false; - - bool modified = false; - for (auto &F : M) { - for (auto &BB: F) { - for (auto &I: BB) { - modified = handleInstruction(F, I) || modified; - } - } - } - return modified; -} - -bool PartsPluginPass::handleInstruction(Function &F, Instruction &I) { - auto CI = dyn_cast(&I); - if (!CI || CI->isInlineAsm()) { - return false; - } - auto calledValue = CI->getCalledOperand(); - IntrinsicInst *II = dyn_cast(calledValue); - if (II && II->getIntrinsicID() == Intrinsic::pa_autcall) { - Value *paced = nullptr; - paced = handleAutCallInstruction(F, I, calledValue); - if (paced) { - CI->setCalledOperand(paced); - } - } - return false; -} - -CallInst *PartsPluginPass::handleAutCallInstruction(Function &F, Instruction &I, Value *value) { - Instruction *Insn = dyn_cast(value); - auto *Call_BB = I.getParent(); - auto *Insn_BB = Insn->getParent(); - - if (Call_BB == Insn_BB) { - return nullptr; - } - - auto calledValue = Insn->getOperand(0); - const auto calledValueType = calledValue->getType(); - IRBuilder<> Builder(&I); - auto autcall = Intrinsic::getDeclaration(F.getParent(), Intrinsic::pa_autcall, { calledValueType}); - auto typeIdConstant = Insn->getOperand(1); - CallInst *paced = Builder.CreateCall(autcall, { calledValue, typeIdConstant }, ""); - return paced; - } \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index 79e2dc2a2db5208d768d07bb9968400cb56bc73a..d7855c45905a42e479e6f562eb3a2a5558b3bf13 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -106,6 +106,11 @@ void initializeLDTLSCleanupPass(PassRegistry&); void initializeSVEIntrinsicOptsPass(PassRegistry&); void initializeAArch64StackTaggingPass(PassRegistry&); void initializeAArch64StackTaggingPreRAPass(PassRegistry&); +// OHOS_LOCAL begin +void initializeAArch64EarlyPartsCpiPassPass(PassRegistry&); +void initializeAArch64PartsDpiPassPass(PassRegistry&); +void initializeAArch64PartsCpiPassPass(PassRegistry&); +// OHOS_LOCAL end } // end namespace llvm #endif diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp index c590344b93bc0fa39f8a1e414663957d514fdfb2..83447bd57b3bb41cc79dc1d6b9d848e16db8d184 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp @@ -7,54 +7,26 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - -#include "AArch64.h" -#include "AArch64Subtarget.h" #include "AArch64RegisterInfo.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/PARTS/Parts.h" - -#define DEBUG_TYPE "AArch64EarlyPartsCpiPass" +#include "AArch64EarlyPartsCpiPass.h" STATISTIC(StatAutcall, DEBUG_TYPE ": inserted authenticate and branch instructions"); using namespace llvm; using namespace llvm::PARTS; -namespace { - -class AArch64EarlyPartsCpiPass : public MachineFunctionPass { -public: - static char ID; - AArch64EarlyPartsCpiPass() : MachineFunctionPass(ID) {} - StringRef getPassName() const override { return DEBUG_TYPE; } - virtual bool doInitialization(Module &M) override; - bool runOnMachineFunction(MachineFunction &) override; -private: - const AArch64Subtarget *STI = nullptr; - const AArch64InstrInfo *TII = nullptr; - inline bool handleInstruction(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi); - inline MachineInstr *findIndirectCallMachineInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineInstr *MIptr); - void triggerCompilationErrorOrphanAUTCALL(MachineBasicBlock &MBB); - inline bool isIndirectCall(const MachineInstr &MI) const; - inline bool isPartsAUTCALLIntrinsic(unsigned Opcode); - inline const MCInstrDesc &getIndirectCallAuth(MachineInstr *MI_indcall); - inline void replaceBranchByAuthenticatedBranch(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); - inline void insertCOPYInstr(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); -}; -} +INITIALIZE_PASS(AArch64EarlyPartsCpiPass, "aarch64-early-parts-cpi-pass", + "AArch64 Early Parts Cpi", false, false) FunctionPass *llvm::createAArch64EarlyPartsCpiPass() { return new AArch64EarlyPartsCpiPass(); @@ -90,13 +62,19 @@ inline bool AArch64EarlyPartsCpiPass::handleInstruction(MachineFunction &MF, Mac return false; } auto MIptr = &*MIi; - MachineInstr *MI_indcall = findIndirectCallMachineInstr(MF, MBB, MIptr); - if (MI_indcall == nullptr) { + SmallVector IndCallVec; + findIndirectCallMachineInstr(MF, MBB, MIptr, IndCallVec); + if (IndCallVec.empty()) { outs() << "MI_indcall is NULL!!!\n"; triggerCompilationErrorOrphanAUTCALL(MBB); } auto &MI = *MIi--; - replaceBranchByAuthenticatedBranch(MBB, MI_indcall, MI); + for (auto &MI_indcall : IndCallVec) { + replaceBranchByAuthenticatedBranch(MBB, MI_indcall, MI); + } + // insert a copy instruction, same dest register as MI, keep subsequent instructions do not need to modified + insertCOPYInstr(MBB, &MI, MI); + MI.removeFromParent(); ++StatAutcall; return true; } @@ -121,21 +99,63 @@ inline const MCInstrDesc& AArch64EarlyPartsCpiPass::getIndirectCallAuth(MachineI return TII->get(AArch64::TCRETURNriAA); } -inline MachineInstr* AArch64EarlyPartsCpiPass::findIndirectCallMachineInstr(MachineFunction &MF, - MachineBasicBlock &MBB, MachineInstr *MIptr) { +inline bool AArch64EarlyPartsCpiPass::handlePhi(MachineFunction &MF, MachineInstr *MIptr, unsigned AutCall) { + MachineRegisterInfo *MRI = &MF.getRegInfo(); + MachineInstr *PhiMi = MRI->getVRegDef(MIptr->getOperand(0).getReg()); + if (!PhiMi->isPHI()) { + return false; + } + for (unsigned i = 1, e = PhiMi->getNumOperands(); i < e; i += 2) { + MachineOperand &Opnd = PhiMi->getOperand(i); + // An incomming value of phi is the return value of autcall + if (Opnd.getReg() == AutCall) { + return true; + } + // An incomming value of phi is a copy of autcall return value + MachineInstr *CopyMi = MRI->getVRegDef(Opnd.getReg()); + if (CopyMi->isCopy() && (CopyMi->getOperand(1).getReg() == AutCall)) { + return true; + } + } + return false; +} + +inline void AArch64EarlyPartsCpiPass::findIndirectCallMachineInstr(MachineFunction &MF, + MachineBasicBlock &MBB, MachineInstr *MIptr, SmallVector &IndCallVec) { unsigned AUTCALLinstr_oper0 = MIptr->getOperand(0).getReg(); unsigned BLRinstr_oper0 = 0; - for (auto &MBB: MF) { + MachineRegisterInfo *MRI = &MF.getRegInfo(); + for (auto &MBB : MF) { for (auto MIi = MBB.instr_begin(), MIie = MBB.instr_end(); MIi != MIie; ++MIi) { if (isIndirectCall(*MIi)) { BLRinstr_oper0 = MIi->getOperand(0).getReg(); if (AUTCALLinstr_oper0 == BLRinstr_oper0) { - return &*MIi; + IndCallVec.push_back(&*MIi); + continue; + } + MachineInstr *CopyMi = MRI->getVRegDef(BLRinstr_oper0); + if (CopyMi->isCopy() && (CopyMi->getOperand(1).getReg() == AUTCALLinstr_oper0)) { + IndCallVec.push_back(&*MIi); + continue; + } + if (handlePhi(MF, &*MIi, AUTCALLinstr_oper0)) { + IndCallVec.push_back(&*MIi); + continue; + } + } else if (isIndirectAutCall(*MIi)) { + BLRinstr_oper0 = MIi->getOperand(0).getReg(); + if (AUTCALLinstr_oper0 == BLRinstr_oper0) { + IndCallVec.push_back(&*MIi); + continue; + } + if (handlePhi(MF, &*MIi, AUTCALLinstr_oper0)) { + IndCallVec.push_back(&*MIi); + continue; } } } } - return nullptr; + return; } inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) const { @@ -147,25 +167,58 @@ inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) con return false; } +inline bool AArch64EarlyPartsCpiPass::isIndirectAutCall(const MachineInstr &MI) const { + switch (MI.getOpcode()) { + case AArch64::BLRAA: // Normal indirect call + case AArch64::TCRETURNriAA: // Indirect tail call + return true; + } + return false; +} + void AArch64EarlyPartsCpiPass::triggerCompilationErrorOrphanAUTCALL(MachineBasicBlock &MBB) { LLVM_DEBUG(MBB.dump()); llvm_unreachable("failed to find BLR for AUTCALL"); } +inline void AArch64EarlyPartsCpiPass::addPhiForModifier(MachineInstr *Indirect, Register *ModReg) { + MachineRegisterInfo *MRI = &Indirect->getParent()->getParent()->getRegInfo(); + MachineInstr *PhiMi = MRI->getVRegDef(Indirect->getOperand(0).getReg()); + if (!PhiMi->isPHI()) { + return; + } + *ModReg = MRI->createVirtualRegister(&AArch64::GPR64spRegClass); + auto BMI = BuildMI(*PhiMi->getParent(), *PhiMi, PhiMi->getDebugLoc(), TII->get(AArch64::PHI)); + BMI.addDef(*ModReg); + for (unsigned i = 1, e = PhiMi->getNumOperands(); i < e; i += 2) { + MachineOperand &Opnd = PhiMi->getOperand(i); + MachineInstr *CopyMi = MRI->getVRegDef(Opnd.getReg()); + MachineInstr *AutCall = CopyMi->isCopy() ? MRI->getVRegDef(CopyMi->getOperand(1).getReg()) : CopyMi; + BMI.addReg(AutCall->getOperand(2).getReg()); + BMI.addMBB(AutCall->getParent()); + } + return; +} + inline void AArch64EarlyPartsCpiPass::replaceBranchByAuthenticatedBranch(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI) { - auto modOperand = MI.getOperand(2); - insertCOPYInstr(MBB, MI_indcall, MI); - auto BMI = BuildMI(MBB, *MI_indcall, MI_indcall->getDebugLoc(), getIndirectCallAuth(MI_indcall)); + + if (isIndirectAutCall(*MI_indcall)) { + return; + } + Register ModReg = MI.getOperand(2).getReg(); + + addPhiForModifier(MI_indcall, &ModReg); + + auto BMI = BuildMI(*MI_indcall->getParent(), *MI_indcall, MI_indcall->getDebugLoc(), getIndirectCallAuth(MI_indcall)); BMI.addUse(MI_indcall->getOperand(0).getReg()); if (MI_indcall->getOpcode() == AArch64::TCRETURNri) { BMI.add(MI_indcall->getOperand(1)); // Copy FPDiff from original tail call pseudo instruction } - BMI.add(modOperand); + BMI.addUse(ModReg); BMI.copyImplicitOps(*MI_indcall); MI_indcall->removeFromParent(); - MI.removeFromParent(); } inline void AArch64EarlyPartsCpiPass::insertCOPYInstr(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI) { diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.h b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.h new file mode 100644 index 0000000000000000000000000000000000000000..cab00dda41ee0b4f7ec6a711f02a1f3737740f35 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.h @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Copyright (C) 2018 Secure Systems Group, Aalto University +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64EARLYPARTSCPI_H +#define LLVM_LIB_TARGET_AARCH64_AARCH64EARLYPARTSCPI_H + +#include "AArch64.h" +#include "AArch64Subtarget.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/IR/Module.h" + +using namespace llvm; + +#define DEBUG_TYPE "AArch64EarlyPartsCpiPass" + +class AArch64EarlyPartsCpiPass : public MachineFunctionPass { +public: + static char ID; + AArch64EarlyPartsCpiPass() : MachineFunctionPass(ID) { + initializeAArch64EarlyPartsCpiPassPass(*PassRegistry::getPassRegistry()); + } + StringRef getPassName() const override { return DEBUG_TYPE; } + virtual bool doInitialization(Module &M) override; + bool runOnMachineFunction(MachineFunction &) override; +private: + const AArch64Subtarget *STI = nullptr; + const AArch64InstrInfo *TII = nullptr; + inline bool handleInstruction(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi); + inline void findIndirectCallMachineInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineInstr *MIptr, SmallVector &IndCallVec); + void triggerCompilationErrorOrphanAUTCALL(MachineBasicBlock &MBB); + inline bool isIndirectCall(const MachineInstr &MI) const; + inline bool isPartsAUTCALLIntrinsic(unsigned Opcode); + inline const MCInstrDesc &getIndirectCallAuth(MachineInstr *MI_indcall); + inline void replaceBranchByAuthenticatedBranch(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); + inline void insertCOPYInstr(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); + inline bool handlePhi(MachineFunction &MF, MachineInstr *MIptr, unsigned AutCall); + inline bool isIndirectAutCall(const MachineInstr &MI) const; + inline void addPhiForModifier(MachineInstr *Indirect, Register *ModReg); +}; + +#endif \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp index 4ea8a652ee627c9c4850ea433b2563d47191f83f..00cd257902f9e2327d0e50780f7fa8cced0b6585 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp @@ -39,7 +39,9 @@ namespace { class AArch64PartsCpiPass : public MachineFunctionPass { public: static char ID; - AArch64PartsCpiPass() : MachineFunctionPass(ID) {} + AArch64PartsCpiPass() : MachineFunctionPass(ID) { + initializeAArch64PartsCpiPassPass(*PassRegistry::getPassRegistry()); + } StringRef getPassName() const override {return DEBUG_TYPE; } bool doInitialization(Module &M) override; bool runOnMachineFunction(MachineFunction &) override; @@ -56,6 +58,9 @@ private: } +INITIALIZE_PASS(AArch64PartsCpiPass, "aarch64-parts-cpi-pass", + "AArch64 Parts Cpi", false, false) + FunctionPass *llvm::createAArch64PartsCpiPass() { return new AArch64PartsCpiPass(); } diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp index 88edb11064bc0b85079e69508e08d6b4948295cf..dc68876d73c8708999ab74bc880e47eb25970d04 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp @@ -42,13 +42,18 @@ namespace { class AArch64PartsDpiPass : public MachineFunctionPass, private AArch64PartsPassCommon { public: static char ID; - AArch64PartsDpiPass() : MachineFunctionPass(ID) {} + AArch64PartsDpiPass() : MachineFunctionPass(ID) { + initializeAArch64PartsDpiPassPass(*PassRegistry::getPassRegistry()); + } StringRef getPassName() const override {return DEBUG_TYPE; } bool runOnMachineFunction(MachineFunction &) override; bool lowerDpiIntrinsics(MachineFunction &MF); }; } +INITIALIZE_PASS(AArch64PartsDpiPass, "aarch64-parts-dpi-pass", + "AArch64 Parts Dpi", false, false) + FunctionPass *llvm::createPartsPassDpi() { return new AArch64PartsDpiPass(); } diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 1c3a7576a08f95c11c89a4240ffe1f43694a13c8..d94491d3de4d5d102550c672bb57e0375b4b05ac 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -592,11 +592,6 @@ void AArch64PassConfig::addIRPasses() { if (TM->getTargetTriple().isOSWindows()) addPass(createCFGuardCheckPass()); - // OHOS_LOCAL begin - if (PARTS::useFeCfi()) - addPass(PARTS::createPartsPluginPass()); - // OHOS_LOCAL end - if (TM->Options.JMCInstrument) addPass(createJMCInstrumenterPass()); } diff --git a/llvm/unittests/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPassTest.cpp b/llvm/unittests/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPassTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c2b3cde6da29ad5af953061d39867d06172d71f --- /dev/null +++ b/llvm/unittests/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPassTest.cpp @@ -0,0 +1,148 @@ + +#include "llvm/CodeGen/MIRParser/MIRParser.h" +#include "llvm/CodeGen/MachineDominanceFrontier.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/Twine.h" +#include "gtest/gtest.h" +#include "AArch64PARTS/AArch64EarlyPartsCpiPass.h" + +using namespace llvm; +namespace { +std::unique_ptr createTargetMachine() { + auto TT(Triple::normalize("aarch64--")); + std::string CPU(""); + std::string FS("+pauth"); + + LLVMInitializeAArch64TargetInfo(); + LLVMInitializeAArch64Target(); + LLVMInitializeAArch64TargetMC(); + + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); + + return std::unique_ptr(static_cast( + TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), None, None, + CodeGenOpt::Default))); +} + +std::unique_ptr parseMIR(LLVMContext &Context, + std::unique_ptr &MIR, + const TargetMachine &TM, StringRef MIRCode, + const char *FuncName, MachineModuleInfo &MMI) { + SMDiagnostic Diagnostic; + std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRCode); + MIR = createMIRParser(std::move(MBuffer), Context); + if (!MIR) + return nullptr; + + std::unique_ptr M = MIR->parseIRModule(); + if (!M) + return nullptr; + + M->setDataLayout(TM.createDataLayout()); + if (MIR->parseMachineFunctions(*M, MMI)) + return nullptr; + + return M; +} + +TEST(EarlyPartsCpi, PhiBlr) { + std::unique_ptr TM = createTargetMachine(); + ASSERT_TRUE(TM); + + MachineModuleInfo MMI(TM.get()); + SmallString<5000> S; + StringRef MIRString = Twine(R"MIR( +--- | + define i32 @pac_test(ptr nocapture noundef readonly %0, i64 noundef %1, ptr nocapture noundef readonly %2, ptr noundef %3) { + unreachable + } +... +--- +name: pac_test +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0, $x1, $x2, $x3 + successors: %bb.1 + %59:gpr64 = COPY $x3 + %58:gpr64 = COPY $x2 + %57:gpr64 = COPY $x1 + %56:gpr64common = COPY $x0 + %62:gpr32all = COPY $wzr + %60:gpr32all = COPY %62:gpr32all + B %bb.1 + + bb.1: + ; predecessors: %bb.0 + successors: %bb.2, %bb.3 + %99:gpr32 = MOVi32imm 22545 + %100:gpr64sp = SUBREG_TO_REG 0, killed %99:gpr32, %subreg.sub_32 + %101:gpr64 = PARTS_AUTCALL %58:gpr64(tied-def 0), killed %100:gpr64sp + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + $x0 = COPY %57:gpr64 + $x1 = COPY %59:gpr64 + BLR killed %101:gpr64 + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + CBNZX %57:gpr64, %bb.3 + B %bb.2 + + bb.2: + ; predecessors: %bb.1 + successors: %bb.4 + %131:gpr32 = MOVi32imm 22545 + %132:gpr64sp = SUBREG_TO_REG 0, killed %131:gpr32, %subreg.sub_32 + %133:gpr64 = PARTS_AUTCALL %58:gpr64(tied-def 0), killed %132:gpr64sp + %31:gpr64 = COPY %133:gpr64 + B %bb.4 + + bb.3: + ; predecessors: %bb.1 + successors: %bb.4 + %125:gpr32 = MOVi32imm 22545 + %126:gpr64sp = SUBREG_TO_REG 0, killed %125:gpr32, %subreg.sub_32 + %127:gpr64 = PARTS_AUTCALL %58:gpr64(tied-def 0), killed %126:gpr64sp + %32:gpr64 = COPY %127:gpr64 + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + $x0 = COPY %57:gpr64 + $x1 = COPY %59:gpr64 + BLR %127:gpr64 + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + B %bb.4 + + bb.4: + ; predecessors: %bb.2, %bb.3 + successors: %bb.5 + %35:gpr64 = PHI %31:gpr64, %bb.2, %32:gpr64, %bb.3 + B %bb.5 + + bb.5: + ; predecessors: %bb.4 + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + $x0 = COPY %57:gpr64 + $x1 = COPY %59:gpr64 + BLR %35:gpr64 + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + RET_ReallyLR implicit $w0 +)MIR").toNullTerminatedStringRef(S);; + + LLVMContext Context; + std::unique_ptr MIR; + std::unique_ptr M = parseMIR(Context, MIR, *TM, MIRString, "pac_test", MMI); + ASSERT_TRUE(M); + + Function *F = M->getFunction("pac_test"); + auto *MF = MMI.getMachineFunction(*F); + ASSERT_TRUE(MF); + std::unique_ptr funcPass(new AArch64EarlyPartsCpiPass()); + ASSERT_TRUE(funcPass); + + bool ret = funcPass->runOnMachineFunction(*MF); + ASSERT_TRUE(ret); +} +} \ No newline at end of file diff --git a/llvm/unittests/Target/AArch64/CMakeLists.txt b/llvm/unittests/Target/AArch64/CMakeLists.txt index 63d08db4aa97d98188c032d05c0e8e11f96eabd8..b9f35d07aaf3b51e835645551d76cdfb855bcbcf 100644 --- a/llvm/unittests/Target/AArch64/CMakeLists.txt +++ b/llvm/unittests/Target/AArch64/CMakeLists.txt @@ -21,6 +21,7 @@ add_llvm_target_unittest(AArch64Tests InstSizes.cpp DecomposeStackOffsetTest.cpp MatrixRegisterAliasing.cpp + AArch64PARTS/AArch64EarlyPartsCpiPassTest.cpp ) set_property(TARGET AArch64Tests PROPERTY FOLDER "Tests/UnitTests/TargetTests")