From ead15d3a03d4e89ea1528432974d509b70c4f389 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 16 Feb 2023 17:09:52 +0800 Subject: [PATCH 1/4] [OHOS]Add PAC CFI DFI command and processing --- clang/include/clang/Basic/Attr.td | 14 ++++++++++++++ clang/include/clang/Basic/AttrDocs.td | 14 ++++++++++++++ clang/lib/CMakeLists.txt | 1 + clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 2 ++ clang/lib/CodeGen/CodeGenTypes.cpp | 2 ++ clang/lib/Parse/CMakeLists.txt | 1 + clang/lib/Parse/ParseDecl.cpp | 4 ++++ clang/lib/Sema/SemaDeclAttr.cpp | 8 ++++++++ llvm/include/llvm/IR/IntrinsicsAArch64.td | 2 +- llvm/lib/CMakeLists.txt | 1 + llvm/lib/Target/AArch64/AArch64.h | 2 ++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 10 +++++++++- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp | 4 ++++ llvm/lib/Target/AArch64/AArch64InstrFormats.td | 2 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 1 + .../Target/AArch64/AArch64MachineFunctionInfo.h | 7 +++++-- llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 11 +++++++++++ llvm/lib/Target/AArch64/CMakeLists.txt | 7 +++++++ 19 files changed, 89 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 68f0841c51bd..6797519796ab 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1742,6 +1742,20 @@ def NoUniqueAddress : InheritableAttr, TargetSpecificAttr { let SimpleHandler = 1; } +def PacDataTag : InheritableAttr { + let Spellings = [GCC<"pac_protected_data">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Documentation = [PacDataTagDocs]; + let SimpleHandler = 1; +} + +def PacPtrTag : InheritableAttr { + let Spellings = [GCC<"pac_protected_ptr">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Documentation = [PacPtrTagDocs]; + let SimpleHandler = 1; +} + def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5c84e2fc5b77..caad49026d28 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1355,6 +1355,20 @@ in C++11 onwards. }]; } +def PacDataTagDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``pac_protected_data`` attribute asks the compiler to protect the struct field with PA + }]; +} + +def PacPtrTagDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``pac_protected_ptr`` attribute asks the compiler to protect the struct pointer type field with PA + }]; +} + def ObjCRequiresSuperDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 1526d65795f8..f69bff2588e7 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -30,3 +30,4 @@ if(CLANG_INCLUDE_TESTS) endif() add_subdirectory(Interpreter) add_subdirectory(Support) +add_subdirectory(Pac) diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 0bb5abcf6045..7dbf0c8f8d25 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -96,4 +96,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + pacDfi ) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c67643c43a7d..7e60c49ad585 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -47,6 +47,7 @@ #include "clang/CodeGen/BackendUtil.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Pac/PacDfi.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -835,6 +836,7 @@ void CodeGenModule::Release() { if (getLangOpts().OpenMPIsDevice) getModule().addModuleFlag(llvm::Module::Max, "openmp-device", LangOpts.OpenMP); + PacDfiEmitStructFieldMetadata(getModule(), VMContext); // Emit OpenCL specific module metadata: OpenCL/SPIR version. if (LangOpts.OpenCL || (LangOpts.CUDAIsDevice && getTriple().isSPIRV())) { diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index fcce424747f1..31ad6e33cddd 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "clang/Pac/PacDfi.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" @@ -852,6 +853,7 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { if (!Entry) { Entry = llvm::StructType::create(getLLVMContext()); addRecordTypeName(RD, Entry, ""); + PacDfiRecordDecl2StructName(RD, Entry); } llvm::StructType *Ty = Entry; diff --git a/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt index 7e90b37386f9..76ca0ac97b0f 100644 --- a/clang/lib/Parse/CMakeLists.txt +++ b/clang/lib/Parse/CMakeLists.txt @@ -28,6 +28,7 @@ add_clang_library(clangParse clangBasic clangLex clangSema + pacDfi DEPENDS omp_gen diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index aef9909a7c97..e983d65951bc 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" +#include "clang/Pac/PacDfi.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" @@ -4529,6 +4530,9 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, TryConsumeToken(tok::semi); } + // find pac_tag attr fields, and insert new fields + PacDfiParseStruct(TagDecl, Actions.getASTContext()); + T.consumeClose(); ParsedAttributes attrs(AttrFactory); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 838fd48357fb..3eadbce0a987 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -9094,6 +9094,14 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleSimpleAttribute(S, D, AL); break; } + case ParsedAttr::AT_PacDataTag: + handleSimpleAttribute(S, D, AL); + break; + } + case ParsedAttr::AT_PacPtrTag: + handleSimpleAttribute(S, D, AL); + break; + } } /// ProcessDeclAttributeList - Apply all the decl attributes in the specified diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index fc66bdfc35e0..f2bbefeacc3d 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -848,7 +848,7 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; } - +#include "llvm/PARTS/Intrinsics.td" //===----------------------------------------------------------------------===// // Memory Tagging Extensions (MTE) Intrinsics let TargetPrefix = "aarch64" in { diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt index 5ecdf5af956a..476024239441 100644 --- a/llvm/lib/CMakeLists.txt +++ b/llvm/lib/CMakeLists.txt @@ -43,6 +43,7 @@ if (LLVM_INCLUDE_TESTS) endif() add_subdirectory(WindowsDriver) add_subdirectory(WindowsManifest) +add_subdirectory(PARTS) set(LLVMCONFIGLIBRARYDEPENDENCIESINC "${LLVM_BINARY_DIR}/tools/llvm-config/LibraryDependencies.inc") diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index a6065d4ed9ec..33917b444d76 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -68,6 +68,8 @@ FunctionPass *createAArch64PostLegalizerLowering(); FunctionPass *createAArch64PostSelectOptimize(); FunctionPass *createAArch64StackTaggingPass(bool IsOptNone); FunctionPass *createAArch64StackTaggingPreRAPass(); +FunctionPass *createAArch64EarlyPartsCpiPass(); +FunctionPass *createAArch64PartsCpiPass(); void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 8ed54a6703cf..3e168d06fade 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -579,7 +579,7 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - + // Emit stack and fault map information. emitStackMaps(SM); FM.serializeToFaultMapSection(); @@ -1310,6 +1310,14 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); return; } + case AArch64::TCRETURNriAA: { + MCInst TmpInst; + TmpInst.setOpcode(AArch64::BRAA); + TmpInst.addOperand(MCOperand::createRet(MI->getOperand(0).getReg())); + TmpInst.addOperand(MCOperand::createRet(MI->getOperand(2).getReg())); + EmitToStreamer(*OutStreamer, TmpInst); + return; + } case AArch64::TCRETURNdi: { MCOperand Dest; MCInstLowering.lowerOperand(MI->getOperand(0), Dest); diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index a7a1c969faf5..53ad04b31929 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -192,6 +192,7 @@ #include "AArch64StackProtectorRetLowering.h" #include "AArch64Subtarget.h" #include "AArch64TargetMachine.h" +#include "AArch64PARTS/PartsFrameLowering.h" #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "llvm/ADT/ScopeExit.h" @@ -274,6 +275,7 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF, unsigned RetOpcode = MBBI->getOpcode(); IsTailCallReturn = RetOpcode == AArch64::TCRETURNdi || RetOpcode == AArch64::TCRETURNri || + RetOpcode == AArch64::TCRETURNriAA || RetOpcode == AArch64::TCRETURNriBTI; } AArch64FunctionInfo *AFI = MF.getInfo(); @@ -1429,6 +1431,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, .setMIFlags(MachineInstr::FrameSetup); } } + PartsFrameLowering::instrumentPrologue(TII, Subtarget.getRegisterInfo(), MBB, MBBI, DebugLoc()); if (EmitCFI && MFnI.isMTETagged()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED)) .setMIFlag(MachineInstr::FrameSetup); @@ -1914,6 +1917,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, auto FinishingTouches = make_scope_exit([&]() { InsertReturnAddressAuth(MF, MBB); + PartsFrameLowering::instrumentEpilogue(TII, Subtarget.getRegisterInfo(), MBB); if (needsShadowCallStackPrologueEpilogue(MF)) emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL); if (EmitCFI) diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index e70d304f37b9..aabbf5079976 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1747,7 +1747,7 @@ class RCPCLoad sz, string asm, RegisterClass RC> class AuthBase M, dag oops, dag iops, string asm, string operands, list pattern> - : I, Sched<[]> { + : I, Sched<[WriteBrReg]> { let isAuthenticated = 1; let Inst{31-25} = 0b1101011; let Inst{20-11} = 0b1111100001; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 4976f51b82e1..772b787e4aca 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -8413,3 +8413,4 @@ include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" include "AArch64SMEInstrInfo.td" include "AArch64InstrGISel.td" +include "llvm/PARTS/AArch64InstInfo.td" \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index f070f989a5b7..987be8a8a066 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -186,7 +186,9 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { /// True if the function need asynchronous unwind information. mutable Optional NeedsAsyncDwarfUnwindInfo; - + /// Temporary symbol used by PARTS to generate a runtime dependent modifier based on + /// the position of function. Epilogue emission relys on this value beging set. + MCSymbol *PartsSym = nullptr; public: explicit AArch64FunctionInfo(MachineFunction &MF); @@ -433,7 +435,8 @@ public: bool needsDwarfUnwindInfo() const; bool needsAsyncDwarfUnwindInfo() const; - + void setPartsSym(MCSymbol *Sym) { PartsSym = Sym; } + MCSymbol *getPartsSym() const { return PartsSym; } private: // Hold the lists of LOHs. MILOHContainer LOHContainerSet; diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 47e4c6589c26..3b06c1b0f90b 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -42,6 +42,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/PARTS/Parts.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" @@ -591,6 +592,9 @@ void AArch64PassConfig::addIRPasses() { if (TM->getTargetTriple().isOSWindows()) addPass(createCFGuardCheckPass()); + if (PARTS::useFeCfi) + addPass(PARTS::createPartsPluginPass()); + if (TM->Options.JMCInstrument) addPass(createJMCInstrumenterPass()); } @@ -643,6 +647,10 @@ bool AArch64PassConfig::addInstSelector() { getOptLevel() != CodeGenOpt::None) addPass(createAArch64CleanupLocalDynamicTLSPass()); + if (PARTS::useFeCfi()) + // Replace indirect jump instruction such as : BR BLR --> BRAA BLRAA + addPass(createAArch64EarlyPartsCpiPass()); + return false; } @@ -805,6 +813,9 @@ void AArch64PassConfig::addPreEmitPass() { if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH && TM->getTargetTriple().isOSBinFormatMachO()) addPass(createAArch64CollectLOHPass()); + + if (PARTS::useFeCfi()) + addPass(createAArch64PartsCpiPass()); } void AArch64PassConfig::addPreEmitPass2() { diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index e7aba115d6a6..54a9482ab907 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -40,6 +40,7 @@ add_llvm_target(AArch64CodeGen GISel/AArch64PostLegalizerLowering.cpp GISel/AArch64PostSelectOptimize.cpp GISel/AArch64RegisterBankInfo.cpp + AArch64PARTS/PartsFrameLowering.cpp AArch64A57FPLoadBalancing.cpp AArch64AdvSIMDScalarPass.cpp AArch64AsmPrinter.cpp @@ -85,9 +86,15 @@ add_llvm_target(AArch64CodeGen AArch64TargetTransformInfo.cpp SVEIntrinsicOpts.cpp AArch64SIMDInstrOpt.cpp + AArch64PARTS/AArch64EarlyPartsCpiPass.cpp + AArch64PARTS/AArch64PartsCpiPass.cpp DEPENDS intrinsics_gen + Parts + + LINK_LIBS + Parts LINK_COMPONENTS AArch64Desc -- Gitee From fa30a55e8cc90e224fb07b90b7d4b5cb841cb308 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 16 Feb 2023 17:10:52 +0800 Subject: [PATCH 2/4] [OHOS]Add PAC CFI DFI command and processing --- clang/include/clang/Pac/PacDfi.h | 27 +++ clang/lib/Pac/CMakelist.txt | 6 + clang/lib/Pac/PacDfi.cpp | 105 ++++++++++ llvm/include/llvm/PARTS/AArch64InstInfo.td | 29 +++ llvm/include/llvm/PARTS/Intrinsics.td | 13 ++ llvm/include/llvm/PARTS/Parts.h | 43 ++++ llvm/lib/PARTS/CMakeLists.txt | 23 +++ llvm/lib/PARTS/Parts.cpp | 70 +++++++ llvm/lib/PARTS/PartsPluginPass.cpp | 106 ++++++++++ .../AArch64PARTS/AArch64EarlyPartsCpiPass.cpp | 178 +++++++++++++++++ .../AArch64PARTS/AArch64PartsCpiPass.cpp | 142 +++++++++++++ .../AArch64PARTS/AArch64PartsPassCommon.h | 101 ++++++++++ .../AArch64PARTS/PartsFrameLowering.cpp | 188 ++++++++++++++++++ .../AArch64/AArch64PARTS/PartsFrameLowering.h | 30 +++ 14 files changed, 1061 insertions(+) create mode 100644 clang/include/clang/Pac/PacDfi.h create mode 100644 clang/lib/Pac/CMakelist.txt create mode 100644 clang/lib/Pac/PacDfi.cpp create mode 100644 llvm/include/llvm/PARTS/AArch64InstInfo.td create mode 100644 llvm/include/llvm/PARTS/Intrinsics.td create mode 100644 llvm/include/llvm/PARTS/Parts.h create mode 100644 llvm/lib/PARTS/CMakeLists.txt create mode 100644 llvm/lib/PARTS/Parts.cpp create mode 100644 llvm/lib/PARTS/PartsPluginPass.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h diff --git a/clang/include/clang/Pac/PacDfi.h b/clang/include/clang/Pac/PacDfi.h new file mode 100644 index 000000000000..c2c73a8390cb --- /dev/null +++ b/clang/include/clang/Pac/PacDfi.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Zaheer Gauhar +// Gilang Mentari Hamidy +// 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 PAC_DFI_H +#define PAC_DFI_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Decl.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" +using namespace clang; + +void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx); +void PacDfiEmitStructFieldsMetadata(llvm::module &M, llvm::LLVMContext &VMContext); +void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry); + +#endif + diff --git a/clang/lib/Pac/CMakelist.txt b/clang/lib/Pac/CMakelist.txt new file mode 100644 index 000000000000..9241a8c85448 --- /dev/null +++ b/clang/lib/Pac/CMakelist.txt @@ -0,0 +1,6 @@ +add_clang_library(pacDfi + PacDfi.cpp + + LINK_LIBS + Parts +) \ No newline at end of file diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp new file mode 100644 index 000000000000..dfcaa2be950f --- /dev/null +++ b/clang/lib/Pac/PacDfi.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Zaheer Gauhar +// Gilang Mentari Hamidy +// 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/Constrants.h" +#include "llvm/PARTS/Parts.h" +#include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Basic/Attributes.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/ParseTemplate.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/SemaDiagnostic.h" +#include "clang/Pac/PacDfi.h" + +using namespace clang; + +std::map RecordDecl2StructName; +std::map> PacFieldInfos; +std::map> PacPtrInfos; + +void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) +{ + if (!llvm::PARTS::useDataFieldTag()) { + return; + } + // find pac_tag attr fields, and insert new fields + std::vector PacFieldIdxs; + std::vector PacPtrIdxs; + unsigned int FieldIdx = 0; + unsigned int ArraySize = 0; + + for (auto Field : TagDecl->fields()) { + if(Field->hasAttr()) { + PacFieldIdxs.push_back(FieldIdx); + if (Field->getType()->isConstantArrayType()) { + auto ArrayTy = dyn_cast(Field->getType()); + ArraySize += ArrayTy->getSize().getZExtValue(); + } else ( + ++ArraySize; + ) + } else if (Field->hasAttr()) { + PacPtrIdxs.push_back(FieldIdx); + } + } + + if (!PacFieldIdxs.empty()) { + llvm::APInt ArraySizeInt(32, ArraySize); + auto ArrayTy = Ctx.getConstantArrayType(Ctx.IntTy, ArraySizeInt, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/ 0); + FieldDecl *PacFD = FieldDecl::Create(Ctx, TagDecl, SourceLocation(), SourceLocation(), nullptr, + ArrayTy, nullptr, nullptr, true, ICIS_NoInit); + + TagDecl->addDecl(PacFD); + PacFieldInfos.insert(std::make_pair(TagDecl, PacFieldIdxs)); + } + if (!PacPtrIdxs.empty()) { + PacPtrInfos.insert(std::make_pair(TagDecl, PacPtrIdxs)); + } +} + +void PacDfiCreateMetaData(std::map> &fieldInfos, StringRef mdName, + llvm::Module &M, llvm::LLVMContext &VMContext) +{ + llvm::NamedMDNode *PacNMD = M.getOrInsertNameMetadata(mdName); + for (auto item : fieldInfos) { + std::vector PacFields; + auto styName = RecordDecl2StructName.find(item.first)->second; + PacFields.push_back(llvm::MDString::get(VMContext, styName)); + for (auto idx : item.second) { + PacFields.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + llvm::Type::getInt32Ty(VMContext), idx))); + } + PacNMD->addOperand(llvm::MDNode::get(VMContext, PacFields)); + } +} + +void PacDfiEmitStructFieldsMetadata(llvm::module &M, llvm::LLVMContext &VMContext) +{ + if (!llvm::PARTS::useDataFieldTag()) { + return; + } + // emit struct fields that need to protect with PA + if (!PacFieldInfos.empty()) { + PacDfiCreateMetaData(PacFieldInfos, "pa_field_info", M, VMContext); + } + if (!PacPtrInfos.empty()) { + PacDfiCreateMetaData(PacPtrInfos, "pa_ptr_field_info", M, VMContext); + } +} +void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry) +{ + if (!llvm::PARTS::useDataFieldTag) { + return; + } + RecordDecl2StructName.insert(std::make_pair(RD, Entry->getName())); +} + diff --git a/llvm/include/llvm/PARTS/AArch64InstInfo.td b/llvm/include/llvm/PARTS/AArch64InstInfo.td new file mode 100644 index 000000000000..a41d13bddc8a --- /dev/null +++ b/llvm/include/llvm/PARTS/AArch64InstInfo.td @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +let isPseudo = 1, hasNoSchedulingInfo = 1 in { + def PARTS_PACIA : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr, GPR64sp:$mod), + [(set i64:$dst, (int_pa_pacia GPR64:$ptr, GPR64sp:$mod))], + "$dst = $ptr">; + def PARTS_AUTIA : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr, GPR64sp:$mod), + [(set i64:$dst, (int_pa_autia GPR64:$ptr, GPR64sp:$mod))], + "$dst = $ptr">; + def PARTS_AUTCALL : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr, GPR64sp:$mod), + [(set i64:$dst, (int_pa_autcall GPR64:$ptr, GPR64sp:$mod))], + "$dst = $ptr">; +} + +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { + def TCRETURNriAA : Pseudo<(outs), (ins tcGPR64:$dst, i32imm:$FPDiff, GPR64sp:$mod), []>, + Sched<[WriteBrReg]>; +} \ No newline at end of file diff --git a/llvm/include/llvm/PARTS/Intrinsics.td b/llvm/include/llvm/PARTS/Intrinsics.td new file mode 100644 index 000000000000..7c780d5af2ef --- /dev/null +++ b/llvm/include/llvm/PARTS/Intrinsics.td @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +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]>; diff --git a/llvm/include/llvm/PARTS/Parts.h b/llvm/include/llvm/PARTS/Parts.h new file mode 100644 index 000000000000..c553be38f246 --- /dev/null +++ b/llvm/include/llvm/PARTS/Parts.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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_PARTS_H +#define LLVM_PARTS_H + +#include "llvm/IR/Constant.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" + +namespace llvm { +namespace PARTS { + +enum PartsBeCfiType { + PartsBeCfiNone, + PartsBeCfiFull, + PartsBeCfiNgFull +}; + +enum PartsDpiType { + PartsDpiNone, + PartsDpiFull, + PartsDpiFullNoType +}; + +bool useBeCfi(); +bool useFeCfi(); +bool useDataPointerProtection(); +bool useDataFieldTag(); +bool useDataFieldProtection(); +PartsBeCfiType getBeCfiType(); +Pass *createPartsPluginPass(); + +} +} +#endif \ No newline at end of file diff --git a/llvm/lib/PARTS/CMakeLists.txt b/llvm/lib/PARTS/CMakeLists.txt new file mode 100644 index 000000000000..a2dd16b0f927 --- /dev/null +++ b/llvm/lib/PARTS/CMakeLists.txt @@ -0,0 +1,23 @@ +add_llvm_component_library(Parts + Parts.cpp + PartsPluginPass.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/PARTS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/Support + ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR + + DEPENDS + intrinsics_gen + LLVMCore + LLVMSupport + LLVMTransformUtils + LLVMCodeGen + + LINK_LIBS + LLVMCore + LLVMSupport + LLVMTransformUtils + LLVMCodeGen + ) +set_property(TARGET Parts PROPERTY LLVM_SYSTEM_LIBS) \ No newline at end of file diff --git a/llvm/lib/PARTS/Parts.cpp b/llvm/lib/PARTS/Parts.cpp new file mode 100644 index 000000000000..f57f4ef84c6a --- /dev/null +++ b/llvm/lib/PARTS/Parts.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + + +#include "llvm/PARTS/Parts.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; +using namespace PARTS; + +static cl::opt EnableFeCfi ( + "FECFI", cl::Hidden, + cl::desc("forward-edge CFI"), + cl::init(false)); + +static cl::opt EnableBeCfi ( + "FGBECFI", cl::Hidden, + cl::desc("backward-edge CFI"), + cl::init(false)); + +static cl::opt EnableDfiDpTag ( + "DFIDPTAG", cl::Hidden, + cl::desc("Data field DFI identify by tag"), + cl::init(false)); + +static cl::opt EnableDfiDppTag ( + "DFIDPPTAG", cl::Hidden, + cl::desc("Data pointer DFI identify by tag"), + cl::init(false)); + +static cl::opt EnableDfiDpp ( + "DFIDPP", cl::Hidden, + cl::desc("Data pointer DFI identify by config"), + cl::init(false)); + +bool llvm::PARTS::useFeCfi() { + return EnableFeCfi; +} + +bool llvm::PARTS::useBeCfi() { + return EnableBeCfi; +} + +bool llvm::PARTS::useDataPointerProtection() { + return EnableDfiDpp || EnableDfiDppTag; +} + +bool llvm::PARTS::useDataFieldTag() { + return EnableDfiDpTag || EnableDfiDppTag; +} + +bool llvm::PARTS::useDataFieldProtection() { + return EnableDfiDpTag; +} + +PartsBeCfiType PARTS::getBeCfiType() { + if (EnableBeCfi) { + return PartsBeCfiFull; + } + return PartsBeCfiNone; +} \ No newline at end of file diff --git a/llvm/lib/PARTS/PartsPluginPass.cpp b/llvm/lib/PARTS/PartsPluginPass.cpp new file mode 100644 index 000000000000..7434f6f392a9 --- /dev/null +++ b/llvm/lib/PARTS/PartsPluginPass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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 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 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 *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/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp new file mode 100644 index 000000000000..7ec8d95b4ede --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp @@ -0,0 +1,178 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#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" + +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(MachieInstr *MI_indcall); + inline void replaceBranchByAuthenticatedBrance(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); + inline void insertCOPYInstr(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); +}; +} + +FunctionPass *llvm::createAArch64EarlyPartsCpiPass() { + return new AArch64EarlyPartsCpiPass(); +} + +char AArch64EarlyPartsCpiPass::ID = 0; +bool AArch64EarlyPartsCpiPass::doInitialization(Module &M) { + return true; +} + +bool AArch64EarlyPartsCpiPass::runOnMachineFunction(MachineFunction &MF) { + bool found = false; + STI = &MF.getSubtarget(); + TII = STI->getInstrInfo(); + + for (auto &MBB : MF) { + for (auto MIi = MBB.instr_begin(), MIie = MBB.instr_end(); MIi != MIiE; ++MIi) { + found= handleInstruction(MF, MBB, MIi) || found; + } + } + return found; +} + +/** +* @param MF +* @param MBB +* @param MIi +* @return return true when changing something, otherwise false +**/ +inline bool AArch64EarlyPartsCpiPass::handleInstruction(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi) { + const auto MIOpcode = MIi->getOpcode(); + if (!isPartsAUTCALLIntrinsic(MIOpcode)) { + return false; + } + auto MIptr = &*MIi; + MachineInstr *MI_indcall = findIndirectCallMachineInstr(MF, MBB, MIptr); + if (MI_indcall == nullptr) { + outs() << "MI_indcall is NULL!!!\n"; + triggerCompilationErrorOrphanAUTCALL(MBB); + } + auto &MI = *MIi--; + replaceBranchByAuthenticatedBrance(MBB, MI_indcall, MI); + ++StatAutcall; + return true; +} + +inline bool AArch64EarlyPartsCpiPass::isPartsAUTCALLIntrinsic(unsigned Opcode) { + switch (Opcode) { + case AArch64::PARTS_AUTCALL; + return true; + } + return false; +} + +inline const MCInstrDesc& AArch64EarlyPartsCpiPass::getIndirectCallAuth(MachieInstr *MI_indcall) { + if (MI_indcall->getOpcode() == AArch64::BLR) { + return TII->get(AArch64::BLRAA); + } + // This is a tail call return, and we need to use BRAA + // (tail-call: ~optimation where a tail-call is coverted to a direct call so that + // the tail-called function can return immediately to the current callee, without + // going through the currently active function.) + + return TII->get(AArch64::TCRETURNriAA); +} + +inline MachineInstr* AArch64EarlyPartsCpiPass::findIndirectCallMachineInstr(MachineFunction &MF, + MachineBasicBlock &MBB, MachineInstr *MIptr) { + unsigned AUTCALLinstr_oper0 = MIptr->getOpcode(0).getReg(); + unsigned BLRinstr_oper0 = 0; + for (auto &MBB: MF) { + for (auto MIi = MBB.instr_begin(), MIie = MBB.instr_end(); MIi != MIie; ++MIi) { + if (&*MIi != nullptr && isIndirectCall(*MIi)) { + BLRinstr_oper0 = MIi->getOperand(0).getReg; + if (AUTCALLinstr_oper0 == BLRinstr_oper0) { + return &*MIi; + } + } + } + } + return nullptr; +} + +inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) { + switch(MI.getOpcode()) { + case AArch64::BLR: // Normal indirect call + case AArch64::TCRETURNri: // 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::replaceBranchByAuthenticatedBrance(MachineBasicBlock &MBB, + MachineInstr *MI_indcall, MachineInstr &MI) { + auto modOperand = MI.getOprand(2); + insertCOPYInstr(MBB, MI_indcall, MI); + auto BMI = BuildMI(MBB, *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 instrution + } + BMI.add(modOperand); + BMI.copyImplicitOps(*MI_indcall); + + MI_indcall->removeFromParent(); + MI.removeFromParent(); +} +inline void AArch64EarlyPartsCpiPass::insertCOPYInstr(MachineBasicBlock &MBB, MachineInstr *MI_indcall, + MachineInstr &MI) { + auto dstOperand = MI.getOperand(0); + auto srcOperand = MI.getOperand(1); + + auto COPYMI = BuildMI(MBB. * MI_indcall, MI_indcall->getDebugLoc(), TII->get(AArch64::COPY)); + COPYMI.add(dstOperand); + COPYMI.add(srcOperand); +} \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp new file mode 100644 index 000000000000..56a4d87728c0 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include +#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/CodeGen/RegisterScavenging.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 "AArch64PartsCpiPass" + +STATISTIC(StatAutia, DEBUG_TYPE ": code pointers authenticated and unPACed"); +STATISTIC(StatPacia, DEBUG_TYPE ": code pointers signed"); + +using namespace llvm; +using namespace llvm::PARTS; + +namespace { +class AArch64PartsCpiPass : public MachineFunctionPass { +public: + static char ID; + AArch64PartsCpiPass() : MachineFunctionPass(ID) {} + StringRef getPassName() const override {return DEBUG_TYPE; } + bool doInitialization(Module &M) override; + bool runOnMachineFunction(MachineFunction &) override; +private: + const AArch64InstrInfo *TII = nullptr; + void lowerPARTSAUTCALL(MachineBasicBlock &MBB, MachineInstr &MI); + void lowerPARTSPACIA(MachineBasicBlock &MBB, MachieInstr &MI); + + inline bool handleInstruction(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi); + inline void lowerPARTSAUTIA(MachineBasicBlock &MBB, MachieInstr *MI); + void lowerPARTSIntrinsicCommon(MachineBasicBlock &MBB, MachieInstr &MI, const MCInstrDesc &InstrDesc); + inline bool isPartsIntrinsic(unsigned Opcode); +}; + +} + +FunctionPass *llvm::createAArch64PartsCpiPass() { + return new AArch64PartsCpiPass(); +} + +char AArch64PartsCpiPass::ID = 0; + +bool AArch64PartsCpiPass::doInitialization(Module &M) { + return true; +} + +bool AArch64PartsCpiPass::runOnMachineFunction(MachineFunction &) { + bool found = false; + TII = MF.getSubtarget().getInstrInfo(); + + for (auto &MBB : MF) { + for (auto MIi = MBB.instr_begin(), MIie = MBB.instr_end(); MIi != MIie; ++ MIi) { + found = handleInstruction(MBB, MIi) || found; + } + } + return found; +} + +/** +* @param MBB +* @param MIi +* @return return true when changing something, otherwise false +**/ +inline bool AArch64PartsCpiPass::handleInstruction(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi) { + const auto MIOpcode = MIi->getOpcode(); + if (!isPartsIntrinsic(MIOpcode)) + return false; + + auto &MI = *MIi--; + switch (MIOpcode) { + default: + llvm_unreachable("Unhandled PARTS insrinsic!!"); + case AArch64::PARTS_PACIA: + lowerPARTSPACIA(MBB, MI); + break; + case AArch64::PARTS_AUTIA: + lowerPARTSAUTIA(MBB, MI); + break; + case AArch64::PARTS_AUTCALL: + lowerPARTSAUTCALL(MBB, MI); + break; + } + MI.removeFromParent(); // Remove the PARTS intrinsic! + return true; +} + +inline bool AArch64PartsCpiPass::isPartsIntrinsic(unsigned Opcode) { + switch (Opcode) { + case AArch64::PARTS_PACIA: + case AArch64::PARTS_AUTIA: + case AArch64::PARTS_AUTCALL: + return true; + } + return false; +} + +void AArch64PartsCpiPass::lowerPARTSPACIA(MachineBasicBlock &MBB, MachieInstr &MI) { + lowerPARTSIntrinsicCommon(MBB, MI, TII->get(AArch64::PACIA)); + ++StatPacia; +} + +inline void AArch64PartsCpiPass::lowerPARTSAUTIA(MachineBasicBlock &MBB, MachieInstr *MI) { + lowerPARTSIntrinsicCommon(MBB, MI, TII->get(AArch64::AUTIA)); + ++StatAutia; +} + +void AArch64PartsCpiPass::lowerPARTSAUTCALL(MachineBasicBlock &MBB, MachineInstr &MI) { + LLVM_DEBUG(MBB.dump()); + llvm_unreachable("Unexpected PARTSAUTCALL found!!!!"); +} + +void AArch64PartsCpiPass::lowerPARTSIntrinsicCommon(MachineBasicBlock &MBB, MachieInstr &MI, + const MCInstrDesc &InstrDesc) { + auto &mod = MI.getOperand(2); + auto &dst = MI.getOperand(0); + auto BMI = BuildMI(MBB, MI, MI.getDebugLoc(), InstrDesc); + BMI.add(dst); + BMI.add(dst); + BMI.add(mod); +} \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h new file mode 100644 index 000000000000..4bced25553c8 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// 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 __AARCH64PARTSOPTPASS_H__ +#define __AARCH64PARTSOPTPASS_H__ + +#include "AArch64InstrInfo.h" +#include "AArch64Subtarget.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/PARTS/Parts.h" + +using namespace llvm; +using namespace llvm::PARTS; + +namespace llvm { +namespace PARTS { + +class AArch64PartsPassCommon { +protected: + inline void initRunOn(MachineFunction &MF); + inline bool hasNoPartsAttribute(MachineFunction &MF); + inline void lowerPartsIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, + const MCInstrDesc &InstrDesc); + inline void insertMovInstr(MachineBasicBlock &MBB, MachineInstr *MI, unsigned dstReg, unsigned srcReg); + inline void replacePartsIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, + const MCInstrDesc &InstrDesc); + inline void replacePartsXPACDIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI); + + const TargetMachine *TM = nullptr; + const AArch64Subtarget *STI = nullptr; + const AArch64InstrInfo *TII = nullptr; + const AArch64RegisterInfo *TRI = nullptr; + +public: + static inline void insertPACInstr(MachineBasicBlock &MBB, MachineInstr *MI, unsigned dstReg, + unsigned modReg, const MCInstrDesc &InstrDesc); +}; +} +} + +inline void AArch64PartsPassCommon::initRunOn(MachineFunction &MF) { + TM = &MF.getTarget(); + STI = &MF.getSubtarget(); + TII = STI->getInstrInfo(); + TRI = STI->getRegisterInfo(); +} + +inline bool AArch64PartsPassCommon::hasNoPartsAttribute(MachineFunction &MF) { + return MF.getFunction().getFnAttribute("no-parts").getValueAsString() == "true"; +} + +inline void AArch64PartsPassCommon::lowerPartsIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, + const MCInstrDesc &InstrDesc) { + const unsigned mod = MI.getOperand(2).getReg(); + const unsigned dst = MI.getOperand(0).getReg(); + insertPACInstr(MBB, &MI, dst, mod, InstrDesc); +} + +inline void AArch64PartsPassCommon::replacePartsIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, + const MCInstrDesc &InstrDesc) { + lowerPartsIntrinsic(MF, MBB, MI, InstrDesc); + MI.removeFromParent(); +} + +static inline void AArch64PartsPassCommon::insertPACInstr(MachineBasicBlock &MBB, MachineInstr *MI, unsigned dstReg, + unsigned modReg, const MCInstrDesc &InstrDesc) { + if (MI != nullptr) { + BuildMI(MBB, MI, MI->getDebugLoc(), InstrDesc, dstReg) + .addReg(dstReg) + .addReg(modReg, RegState::InternalRead); + } else { + BuildMI(MBB, DebugLoc(), InstrDesc, dstReg) + .addReg(dstReg) + .addReg(modReg, RegState::InternalRead); + } +} + +inline void AArch64PartsPassCommon::insertMovInstr(MachineBasicBlock &MBB, MachineInstr *MI, unsigned dstReg, + unsigned srcReg) { + BuildMI(MBB, MI, MI->getDebugLoc(), TII->get(AArch64::ORRXrs), dstReg) + .addUse(AArch64::XZR) + .addUse(srcReg) + .addImm(0); +} + +inline void AArch64PartsPassCommon::replacePartsXPACDIntrinsic(MachineFunction &MF, MachineBasicBlock &MBB, + MachineInstr &MI) { + const unsigned dst = MI.getOperand(0).getReg(); + BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(AArch64::XPACD), dst); + MI.removeFromParent(); +} + +#endif + diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp new file mode 100644 index 000000000000..d3a630efe14e --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp @@ -0,0 +1,188 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Zaheer Gauhar +// Gilang Mentari Hamidy +// 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 "PartsFrameLowering.h" +#include "AArch64PartsPassCommon.h" +#include "AArch64InstrInfo.h" +#include "AArch64MachineFunctionInfo.h" +#include "AArch64RegisterInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Support/Debug.h" +#include "llvm/PARTS/Parts.h" +#include + +using namespace llvm; +using namespace llvm::PARTS; +#define DEBUG_TYPE "PartsOptRasPass" + +static constexpr const unsigned modReg = AArch64::X16; +static constexpr const unsigned modScratchReg = AArch64::X17; + +static bool doInstrument(const MachineFunction &MF) { + static const auto becfi = PARTS::getBeCfiType(); + + // Just skip if we're not even using backward-edge CFI + if (becfi == PartsBeCfiNone) return false; + + const Function &F = MF.getFunction(); + // Ignore function with the no-parts attribute + if (F.hasFnAttribute(no-parts)) return false; + // Ignore function without function-id (if we need it) + if (becfi == PartsBeCfiFull && !F.hasFnAttribute("parts-function_id")) return false; + + // Skip if we don't spill LR + for (const auto &Info : MF.getFrameInfo().getCalleeSavedInfo()) { + if (Info.getReg() != AArch64::LR) { + return true; + } + } + return false; +} + +static void createBeCfiModifier(const TargetInstrInfo *TII, MachineBasicBlock &MBB, MachineInstr *MIi, + const DebugLoc &DL) { + auto &F = MBB.getParent()->getFunction(); + + assert(F.hasFnAttribute("parts-function_id")) && "missing parts-functio_id attribute"); + + uint64_t type_id; + std::istringstream iss(F.getFnAttribute("parts-function_id").getValueAsString().str()); + iss >> type_id; + + const auto t1 = ((type_id)) % UINT16_MAX; + const auto t2 = ((type_id << 16)) % UINT16_MAX; + const auto t3 = ((type_id << 32)) % UINT16_MAX; + + if (MIi == nullptr) { + BuildMI(&MBB, DL, TII->get(AArch64::ADDXri), modReg).addReg(AArch64::SP).addImm(0).addImm(0); + BuildMI(&MBB, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t1).addImm(16); + BuildMI(&MBB, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t2).addImm(32); + BuildMI(&MBB, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t3).addImm(48); + } else{ + BuildMI(MBB, MIi, DL, TII->get(AArch64::ADDXri), modReg).addReg(AArch64::SP).addImm(0).addImm(0); + BuildMI(MBB, MIi, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t1).addImm(16); + BuildMI(MBB, MIi, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t2).addImm(32); + BuildMI(MBB, MIi, DL, TII->get(AArch64::MOVKXi), modReg).addReg(modReg).addImm(t3).addImm(48); + } +} + +static MachineInstr *insertFastModifierInstructions(const TargetInstrInfo *TII, MachineBasicBlock &MBB, + MachineInstr *MI, MCSymbol *Sym, const DebugLoc &DL) { + LLVM_DEBUG(dbgs() << "insertFastModifierInstructions with MI begin.\n"); + + auto FirstModifierMI = BuildMI(MBB, MI, DL, TII->get(AArch64::ADR), modReg) + .addSym(Sym); + BuildMI(MBB, MI, DL, TII->get(AArch64::ADDXri), modScratchReg) + .addReg(AArch64::SP) + .addImm(0) + .addImm(0); + BuildMI(MBB, MI, DL, TII->get(AArch64::BFMXri), modReg) + .addUse(modReg) + .addReg(modScratchReg) + .addImm(32) + .addImm(31); + LLVM_DEBUG(dbgs() << "insertFastModifierInstructions with MI end.\n"); + return FirstModifierMI; +} + +static void insertFastModifierInstructions(const TargetInstrInfo *TII, MachineBasicBlock &MBB, + MCSymbol *Sym, const DebugLoc &DL) { + LLVM_DEBUG(dbgs() << "insertFastModifierInstructions begin.\n"); + + BuildMI(&MBB, DL, TII->get(AArch64::ADR), modReg) + .addSym(Sym); + BuildMI(&MBB, DL, TII->get(AArch64::ADDXri), modScratchReg) + .addReg(AArch64::SP) + .addImm(0) + .addImm(0); + BuildMI(&MBB, DL, TII->get(AArch64::BFMXri), modReg) + .addUse(modReg) + .addReg(modScratchReg) + .addImm(32) + .addImm(31); + LLVM_DEBUG(dbgs() << "insertFastModifierInstructions end.\n"); +} + +#define PARTS_SYMBOL "parts_becfi" + +static MCSymbol *createBeCfiPrologueSymbol(MachineBasicBlock &MBB) { + LLVM_DEBUG(dbgs() << "createBeCfiPrologueSymbol.\n"); + + auto &MF = *MBB.getParent(); + AArch64FunctionInfo *AFI = MF.getInfo(); + auto Sym = MF.getContext().createNameTempSymbol(PARTS_SYMBOL); + AFI->setPartsSym(Sym); + return Sym; +} + +static MCSymbol *getBeCfiPrologueSymbol(MachineBasicBlock &MBB) { + auto &MF = *MBB.getParent(); + AArch64FunctionInfo *AFI = MF.getInfo(); + return AFI->getPartsSym(); +} + +static void insertPrologueFastBeCfiModifier(const TargetInstrInfo *TII, MachineBasicBlock &MBB, + MachineInstr *MIi, const DebugLoc &DL) { + assert(PARTS::getBeCfiType() == PartsBeCfiNgFull); + LLVM_DEBUG(dbgs() << "insertPrologueFastBeCfiModifier.\n"); + + auto Sym = createBeCfiPrologueSymbol(MBB); + auto MI = insertFastModifierInstructions(TII, MBB, MTi, Sym, DL); + MI->setPreInstrSymbol(*MBB.getParent(), Sym); +} + +static void insertEpilogueFastBeCfiModifier(const TargetInstrInfo *TII, MachineBasicBlock &MBB, + MachineInstr *MIi, const DebugLoc &DL) { + assert(PARTS::getBeCfiType() == PartsBeCfiNgFull); + + auto Sym = getBeCfiPrologueSymbol(MBB); + assert(Sym && "Missing PARTS prologue instruction symbol/label\n"); + LLVM_DEBUG(dbgs() << "insertEpilogueFastBeCfiModifier.\n"); + if (MIi == nullptr) { + insertFastModifierInstructions(TII, MBB, Sym, DL); + } else { + (void)insertFastModifierInstructions(TII, MBB, MTi, Sym, DL); + } +} + +void PartsFrameLowering::instrumentEpilogue(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + MachineBasicBlock &MBB) { + if (!doInstrument(*MBB.getParent())) + return; + + const auto loc = MBB.getFirstTerminator(); + auto *MI = (loc != MBB.end() ? &*loc : nullptr); + LLVM_DEBUG(dbgs() << "instrumentEpilogue.\n"); + + if (PARTS::getBeCfiType == PartsBeCfiFull) + createBeCfiModifier(TII, MBB, MI, DebugLoc()); + else + insertEpilogueFastBeCfiModifier(TII, MBB, MI, DebugLoc()); + + AArch64PartsPassCommon::insertPACInstr(MBB, MI, AArch64::LR, modReg, TII->get(AArch64::AUTIB)); +} + +void PartsFrameLowering::instrumentPrologue(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL) { + if (!doInstrument(*MBB.getParent())) + return; + + LLVM_DEBUG(dbgs() << "instrumentPrologue.\n"); + + if (PARTS::getBeCfiType == PartsBeCfiFull) + createBeCfiModifier(TII, MBB, &*MBBI, DebugLoc()); + else + insertPrologueFastBeCfiModifier(TII, MBB, &*MBBI, DebugLoc()); + + AArch64PartsPassCommon::insertPACInstr(MBB, &*MBBI, AArch64::LR, modReg, TII->get(AArch64::PACIB)); +} \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h new file mode 100644 index 000000000000..2a8ce2a13e78 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Zaheer Gauhar +// Gilang Mentari Hamidy +// 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_PARTSFRAMELOWERING_H +#define LLVM_PARTSFRAMELOWERING_H + +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetRegiserInfo.h" + +namespace llvm { +namespace PartsFrameLowering { + +void instrumentEpilogue(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + MachineBasicBlock &MBB); +void instrumentPrologue(const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL); +} +} + +#endif -- Gitee From 0257e143e3b5caa8b366220f655d434a8b859bc2 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 16 Feb 2023 19:08:08 +0800 Subject: [PATCH 3/4] [OHOS]Add PAC CFI DFI command and processing --- .../lib/Pac/{CMakelist.txt => CMakeLists.txt} | 0 clang/lib/Pac/PacDfi.cpp | 21 ++++++++++--------- clang/lib/Sema/SemaDeclAttr.cpp | 4 ++-- llvm/include/llvm/IR/IntrinsicsAArch64.td | 2 +- llvm/include/llvm/PARTS/AArch64InstInfo.td | 2 +- llvm/lib/PARTS/Parts.cpp | 10 ++++----- llvm/lib/PARTS/PartsPluginPass.cpp | 6 +++--- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 4 ++-- .../AArch64PARTS/AArch64EarlyPartsCpiPass.cpp | 20 +++++++++--------- .../AArch64PARTS/AArch64PartsCpiPass.cpp | 10 ++++----- .../AArch64PARTS/AArch64PartsPassCommon.h | 2 +- .../AArch64PARTS/PartsFrameLowering.cpp | 18 ++++++++-------- .../AArch64/AArch64PARTS/PartsFrameLowering.h | 6 +++--- .../Target/AArch64/AArch64TargetMachine.cpp | 2 +- 14 files changed, 54 insertions(+), 53 deletions(-) rename clang/lib/Pac/{CMakelist.txt => CMakeLists.txt} (100%) diff --git a/clang/lib/Pac/CMakelist.txt b/clang/lib/Pac/CMakeLists.txt similarity index 100% rename from clang/lib/Pac/CMakelist.txt rename to clang/lib/Pac/CMakeLists.txt diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp index dfcaa2be950f..0f89cb84a240 100644 --- a/clang/lib/Pac/PacDfi.cpp +++ b/clang/lib/Pac/PacDfi.cpp @@ -10,12 +10,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/Constrants.h" +#include "llvm/IR/Constants.h" #include "llvm/PARTS/Parts.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Attributes.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/ParseTemplate.h" +#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Pac/PacDfi.h" @@ -38,17 +38,18 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) unsigned int ArraySize = 0; for (auto Field : TagDecl->fields()) { - if(Field->hasAttr()) { + if (Field->hasAttr()) { PacFieldIdxs.push_back(FieldIdx); if (Field->getType()->isConstantArrayType()) { - auto ArrayTy = dyn_cast(Field->getType()); + auto ArrayTy = dyn_cast(Field->getType()); ArraySize += ArrayTy->getSize().getZExtValue(); - } else ( + } else { ++ArraySize; - ) + } } else if (Field->hasAttr()) { PacPtrIdxs.push_back(FieldIdx); } + ++FieldIdx; } if (!PacFieldIdxs.empty()) { @@ -69,7 +70,7 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) void PacDfiCreateMetaData(std::map> &fieldInfos, StringRef mdName, llvm::Module &M, llvm::LLVMContext &VMContext) { - llvm::NamedMDNode *PacNMD = M.getOrInsertNameMetadata(mdName); + llvm::NamedMDNode *PacNMD = M.getOrInsertNamedMetadata(mdName); for (auto item : fieldInfos) { std::vector PacFields; auto styName = RecordDecl2StructName.find(item.first)->second; @@ -95,11 +96,11 @@ void PacDfiEmitStructFieldsMetadata(llvm::module &M, llvm::LLVMContext &VMContex PacDfiCreateMetaData(PacPtrInfos, "pa_ptr_field_info", M, VMContext); } } + void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry) { - if (!llvm::PARTS::useDataFieldTag) { + if (!llvm::PARTS::useDataFieldTag()) { return; } RecordDecl2StructName.insert(std::make_pair(RD, Entry->getName())); -} - +} \ No newline at end of file diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 3eadbce0a987..5487b8f25004 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -9093,11 +9093,11 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_UsingIfExists: handleSimpleAttribute(S, D, AL); break; - } + case ParsedAttr::AT_PacDataTag: handleSimpleAttribute(S, D, AL); break; - } + case ParsedAttr::AT_PacPtrTag: handleSimpleAttribute(S, D, AL); break; diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index f2bbefeacc3d..235c35f92cc0 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -848,7 +848,7 @@ def int_aarch64_crc32x : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llv def int_aarch64_crc32cx : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; } -#include "llvm/PARTS/Intrinsics.td" +include "llvm/PARTS/Intrinsics.td" //===----------------------------------------------------------------------===// // Memory Tagging Extensions (MTE) Intrinsics let TargetPrefix = "aarch64" in { diff --git a/llvm/include/llvm/PARTS/AArch64InstInfo.td b/llvm/include/llvm/PARTS/AArch64InstInfo.td index a41d13bddc8a..62c8ad6ea154 100644 --- a/llvm/include/llvm/PARTS/AArch64InstInfo.td +++ b/llvm/include/llvm/PARTS/AArch64InstInfo.td @@ -26,4 +26,4 @@ let isPseudo = 1, hasNoSchedulingInfo = 1 in { let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { def TCRETURNriAA : Pseudo<(outs), (ins tcGPR64:$dst, i32imm:$FPDiff, GPR64sp:$mod), []>, Sched<[WriteBrReg]>; -} \ No newline at end of file +} diff --git a/llvm/lib/PARTS/Parts.cpp b/llvm/lib/PARTS/Parts.cpp index f57f4ef84c6a..1f0a5cde24b0 100644 --- a/llvm/lib/PARTS/Parts.cpp +++ b/llvm/lib/PARTS/Parts.cpp @@ -17,27 +17,27 @@ using namespace llvm; using namespace PARTS; -static cl::opt EnableFeCfi ( +static cl::opt EnableFeCfi( "FECFI", cl::Hidden, cl::desc("forward-edge CFI"), cl::init(false)); -static cl::opt EnableBeCfi ( +static cl::opt EnableBeCfi( "FGBECFI", cl::Hidden, cl::desc("backward-edge CFI"), cl::init(false)); -static cl::opt EnableDfiDpTag ( +static cl::opt EnableDfiDpTag( "DFIDPTAG", cl::Hidden, cl::desc("Data field DFI identify by tag"), cl::init(false)); -static cl::opt EnableDfiDppTag ( +static cl::opt EnableDfiDppTag( "DFIDPPTAG", cl::Hidden, cl::desc("Data pointer DFI identify by tag"), cl::init(false)); -static cl::opt EnableDfiDpp ( +static cl::opt EnableDfiDpp( "DFIDPP", cl::Hidden, cl::desc("Data pointer DFI identify by config"), cl::init(false)); diff --git a/llvm/lib/PARTS/PartsPluginPass.cpp b/llvm/lib/PARTS/PartsPluginPass.cpp index 7434f6f392a9..97319040e10d 100644 --- a/llvm/lib/PARTS/PartsPluginPass.cpp +++ b/llvm/lib/PARTS/PartsPluginPass.cpp @@ -55,7 +55,7 @@ static RegisterPass X("parts-plugin", "PARTS Plugin pass"); Pass *llvm::PARTS::createPartsPluginPass() { return new PartsPluginPass(); } -bool runOnModule(Module &M) { +bool PartsPluginPass::runOnModule(Module &M) { if (!PARTS::useFeCfi()) return false; @@ -70,7 +70,7 @@ bool runOnModule(Module &M) { return modified; } -bool handleInstruction(Function &F, Instruction &I) { +bool PartsPluginPass::handleInstruction(Function &F, Instruction &I) { auto CI = dyn_cast(&I); if (!CI || CI->isInlineAsm()) { return false; @@ -87,7 +87,7 @@ bool handleInstruction(Function &F, Instruction &I) { return false; } - CallInst *handleAutCallInstruction(Function &F, Instruction &I, Value *value) { +CallInst *PartsPluginPass::handleAutCallInstruction(Function &F, Instruction &I, Value *value) { Instruction *Insn = dyn_cast(value); auto *Call_BB = I.getParent(); auto *Insn_BB = Insn->getParent(); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 3e168d06fade..552daedc0555 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1313,8 +1313,8 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { case AArch64::TCRETURNriAA: { MCInst TmpInst; TmpInst.setOpcode(AArch64::BRAA); - TmpInst.addOperand(MCOperand::createRet(MI->getOperand(0).getReg())); - TmpInst.addOperand(MCOperand::createRet(MI->getOperand(2).getReg())); + TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg())); + TmpInst.addOperand(MCOperand::createReg(MI->getOperand(2).getReg())); EmitToStreamer(*OutStreamer, TmpInst); return; } diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp index 7ec8d95b4ede..4c31b0e30e01 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp @@ -50,8 +50,8 @@ private: void triggerCompilationErrorOrphanAUTCALL(MachineBasicBlock &MBB); inline bool isIndirectCall(const MachineInstr &MI) const; inline bool isPartsAUTCALLIntrinsic(unsigned Opcode); - inline const MCInstrDesc &getIndirectCallAuth(MachieInstr *MI_indcall); - inline void replaceBranchByAuthenticatedBrance(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI); + 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); }; } @@ -96,20 +96,20 @@ inline bool AArch64EarlyPartsCpiPass::handleInstruction(MachineFunction &MF, Mac triggerCompilationErrorOrphanAUTCALL(MBB); } auto &MI = *MIi--; - replaceBranchByAuthenticatedBrance(MBB, MI_indcall, MI); + replaceBranchByAuthenticatedBranch(MBB, MI_indcall, MI); ++StatAutcall; return true; } inline bool AArch64EarlyPartsCpiPass::isPartsAUTCALLIntrinsic(unsigned Opcode) { switch (Opcode) { - case AArch64::PARTS_AUTCALL; + case AArch64::PARTS_AUTCALL: return true; } return false; } -inline const MCInstrDesc& AArch64EarlyPartsCpiPass::getIndirectCallAuth(MachieInstr *MI_indcall) { +inline const MCInstrDesc& AArch64EarlyPartsCpiPass::getIndirectCallAuth(MachineInstr *MI_indcall) { if (MI_indcall->getOpcode() == AArch64::BLR) { return TII->get(AArch64::BLRAA); } @@ -123,12 +123,12 @@ inline const MCInstrDesc& AArch64EarlyPartsCpiPass::getIndirectCallAuth(MachieIn inline MachineInstr* AArch64EarlyPartsCpiPass::findIndirectCallMachineInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr *MIptr) { - unsigned AUTCALLinstr_oper0 = MIptr->getOpcode(0).getReg(); + unsigned AUTCALLinstr_oper0 = MIptr->getOperand(0).getReg(); unsigned BLRinstr_oper0 = 0; for (auto &MBB: MF) { for (auto MIi = MBB.instr_begin(), MIie = MBB.instr_end(); MIi != MIie; ++MIi) { if (&*MIi != nullptr && isIndirectCall(*MIi)) { - BLRinstr_oper0 = MIi->getOperand(0).getReg; + BLRinstr_oper0 = MIi->getOperand(0).getReg(); if (AUTCALLinstr_oper0 == BLRinstr_oper0) { return &*MIi; } @@ -138,7 +138,7 @@ inline MachineInstr* AArch64EarlyPartsCpiPass::findIndirectCallMachineInstr(Mach return nullptr; } -inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) { +inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) const { switch(MI.getOpcode()) { case AArch64::BLR: // Normal indirect call case AArch64::TCRETURNri: // Indirect tail call @@ -152,7 +152,7 @@ void AArch64EarlyPartsCpiPass::triggerCompilationErrorOrphanAUTCALL(MachineBasic llvm_unreachable("failed to find BLR for AUTCALL"); } -inline void AArch64EarlyPartsCpiPass::replaceBranchByAuthenticatedBrance(MachineBasicBlock &MBB, +inline void AArch64EarlyPartsCpiPass::replaceBranchByAuthenticatedBranch(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI) { auto modOperand = MI.getOprand(2); insertCOPYInstr(MBB, MI_indcall, MI); @@ -172,7 +172,7 @@ inline void AArch64EarlyPartsCpiPass::insertCOPYInstr(MachineBasicBlock &MBB, Ma auto dstOperand = MI.getOperand(0); auto srcOperand = MI.getOperand(1); - auto COPYMI = BuildMI(MBB. * MI_indcall, MI_indcall->getDebugLoc(), TII->get(AArch64::COPY)); + auto COPYMI = BuildMI(MBB, *MI_indcall, MI_indcall->getDebugLoc(), TII->get(AArch64::COPY)); COPYMI.add(dstOperand); COPYMI.add(srcOperand); } \ 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 56a4d87728c0..3b8033775f6a 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsCpiPass.cpp @@ -46,11 +46,11 @@ public: private: const AArch64InstrInfo *TII = nullptr; void lowerPARTSAUTCALL(MachineBasicBlock &MBB, MachineInstr &MI); - void lowerPARTSPACIA(MachineBasicBlock &MBB, MachieInstr &MI); + void lowerPARTSPACIA(MachineBasicBlock &MBB, MachineInstr &MI); inline bool handleInstruction(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi); - inline void lowerPARTSAUTIA(MachineBasicBlock &MBB, MachieInstr *MI); - void lowerPARTSIntrinsicCommon(MachineBasicBlock &MBB, MachieInstr &MI, const MCInstrDesc &InstrDesc); + inline void lowerPARTSAUTIA(MachineBasicBlock &MBB, MachineInstr &MI); + void lowerPARTSIntrinsicCommon(MachineBasicBlock &MBB, MachineInstr &MI, const MCInstrDesc &InstrDesc); inline bool isPartsIntrinsic(unsigned Opcode); }; @@ -66,7 +66,7 @@ bool AArch64PartsCpiPass::doInitialization(Module &M) { return true; } -bool AArch64PartsCpiPass::runOnMachineFunction(MachineFunction &) { +bool AArch64PartsCpiPass::runOnMachineFunction(MachineFunction &MF) { bool found = false; TII = MF.getSubtarget().getInstrInfo(); @@ -91,7 +91,7 @@ inline bool AArch64PartsCpiPass::handleInstruction(MachineBasicBlock &MBB, Machi auto &MI = *MIi--; switch (MIOpcode) { default: - llvm_unreachable("Unhandled PARTS insrinsic!!"); + llvm_unreachable("Unhandled PARTS intrinsic!!"); case AArch64::PARTS_PACIA: lowerPARTSPACIA(MBB, MI); break; diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h index 4bced25553c8..7531d55181bd 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsPassCommon.h @@ -76,7 +76,7 @@ static inline void AArch64PartsPassCommon::insertPACInstr(MachineBasicBlock &MBB .addReg(dstReg) .addReg(modReg, RegState::InternalRead); } else { - BuildMI(MBB, DebugLoc(), InstrDesc, dstReg) + BuildMI(&MBB, DebugLoc(), InstrDesc, dstReg) .addReg(dstReg) .addReg(modReg, RegState::InternalRead); } diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp index d3a630efe14e..103bacdb22f5 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.cpp @@ -36,7 +36,7 @@ static bool doInstrument(const MachineFunction &MF) { const Function &F = MF.getFunction(); // Ignore function with the no-parts attribute - if (F.hasFnAttribute(no-parts)) return false; + if (F.hasFnAttribute("no-parts")) return false; // Ignore function without function-id (if we need it) if (becfi == PartsBeCfiFull && !F.hasFnAttribute("parts-function_id")) return false; @@ -59,9 +59,9 @@ static void createBeCfiModifier(const TargetInstrInfo *TII, MachineBasicBlock &M std::istringstream iss(F.getFnAttribute("parts-function_id").getValueAsString().str()); iss >> type_id; - const auto t1 = ((type_id)) % UINT16_MAX; - const auto t2 = ((type_id << 16)) % UINT16_MAX; - const auto t3 = ((type_id << 32)) % UINT16_MAX; + const auto t1 = ((type_id) % UINT16_MAX); + const auto t2 = ((type_id << 16) % UINT16_MAX); + const auto t3 = ((type_id << 32) % UINT16_MAX); if (MIi == nullptr) { BuildMI(&MBB, DL, TII->get(AArch64::ADDXri), modReg).addReg(AArch64::SP).addImm(0).addImm(0); @@ -120,7 +120,7 @@ static MCSymbol *createBeCfiPrologueSymbol(MachineBasicBlock &MBB) { auto &MF = *MBB.getParent(); AArch64FunctionInfo *AFI = MF.getInfo(); - auto Sym = MF.getContext().createNameTempSymbol(PARTS_SYMBOL); + auto Sym = MF.getContext().createNamedTempSymbol(PARTS_SYMBOL); AFI->setPartsSym(Sym); return Sym; } @@ -137,7 +137,7 @@ static void insertPrologueFastBeCfiModifier(const TargetInstrInfo *TII, MachineB LLVM_DEBUG(dbgs() << "insertPrologueFastBeCfiModifier.\n"); auto Sym = createBeCfiPrologueSymbol(MBB); - auto MI = insertFastModifierInstructions(TII, MBB, MTi, Sym, DL); + auto MI = insertFastModifierInstructions(TII, MBB, MIi, Sym, DL); MI->setPreInstrSymbol(*MBB.getParent(), Sym); } @@ -151,7 +151,7 @@ static void insertEpilogueFastBeCfiModifier(const TargetInstrInfo *TII, MachineB if (MIi == nullptr) { insertFastModifierInstructions(TII, MBB, Sym, DL); } else { - (void)insertFastModifierInstructions(TII, MBB, MTi, Sym, DL); + (void)insertFastModifierInstructions(TII, MBB, MIi, Sym, DL); } } @@ -164,7 +164,7 @@ void PartsFrameLowering::instrumentEpilogue(const TargetInstrInfo *TII, const Ta auto *MI = (loc != MBB.end() ? &*loc : nullptr); LLVM_DEBUG(dbgs() << "instrumentEpilogue.\n"); - if (PARTS::getBeCfiType == PartsBeCfiFull) + if (PARTS::getBeCfiType() == PartsBeCfiFull) createBeCfiModifier(TII, MBB, MI, DebugLoc()); else insertEpilogueFastBeCfiModifier(TII, MBB, MI, DebugLoc()); @@ -179,7 +179,7 @@ void PartsFrameLowering::instrumentPrologue(const TargetInstrInfo *TII, const Ta LLVM_DEBUG(dbgs() << "instrumentPrologue.\n"); - if (PARTS::getBeCfiType == PartsBeCfiFull) + if (PARTS::getBeCfiType() == PartsBeCfiFull) createBeCfiModifier(TII, MBB, &*MBBI, DebugLoc()); else insertPrologueFastBeCfiModifier(TII, MBB, &*MBBI, DebugLoc()); diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h index 2a8ce2a13e78..9d21d8a101a6 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h @@ -1,8 +1,7 @@ //===----------------------------------------------------------------------===// // // Author: Hans Liljestrand -// Zaheer Gauhar -// Gilang Mentari Hamidy +// Zaheer Ahmed Gauhar // Copyright (C) 2018 Secure Systems Group, Aalto University // // This file is distributed under the University of Illinois Open Source @@ -15,7 +14,8 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetRegiserInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/IR/DebugLoc.h" namespace llvm { namespace PartsFrameLowering { diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 3b06c1b0f90b..e0a1530d63a6 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -592,7 +592,7 @@ void AArch64PassConfig::addIRPasses() { if (TM->getTargetTriple().isOSWindows()) addPass(createCFGuardCheckPass()); - if (PARTS::useFeCfi) + if (PARTS::useFeCfi()) addPass(PARTS::createPartsPluginPass()); if (TM->Options.JMCInstrument) -- Gitee From f27c01bbda3fd27de0a0fd5fcbf29b6924c1d28b Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 16 Feb 2023 19:18:04 +0800 Subject: [PATCH 4/4] [OHOS]Add PAC CFI DFI command and processing --- llvm/lib/PARTS/CMakeLists.txt | 2 +- .../Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/PARTS/CMakeLists.txt b/llvm/lib/PARTS/CMakeLists.txt index a2dd16b0f927..196de8467f3e 100644 --- a/llvm/lib/PARTS/CMakeLists.txt +++ b/llvm/lib/PARTS/CMakeLists.txt @@ -9,7 +9,7 @@ add_llvm_component_library(Parts DEPENDS intrinsics_gen - LLVMCore + LLVMCore LLVMSupport LLVMTransformUtils LLVMCodeGen diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp index 4c31b0e30e01..2cb5449d4986 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp @@ -154,7 +154,7 @@ void AArch64EarlyPartsCpiPass::triggerCompilationErrorOrphanAUTCALL(MachineBasic inline void AArch64EarlyPartsCpiPass::replaceBranchByAuthenticatedBranch(MachineBasicBlock &MBB, MachineInstr *MI_indcall, MachineInstr &MI) { - auto modOperand = MI.getOprand(2); + auto modOperand = MI.getOperand(2); insertCOPYInstr(MBB, MI_indcall, MI); auto BMI = BuildMI(MBB, *MI_indcall, MI_indcall->getDebugLoc(), getIndirectCallAuth(MI_indcall)); BMI.addUse(MI_indcall->getOperand(0).getReg()); -- Gitee