From 074f8d3df2e04e28ce226ef439cdba6f43a46317 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 16 Feb 2023 17:09:52 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 1、新增前向CFI,后向CFI,数据指针和数据字段DFI的编译选项 2、在Clang Parse模块增加DFI 的解析结构体定义,根据tag识别被保护字段,修改结构体定义增加pac存储字段功能。 3、在Clang CodeGen模块增加生成被保护结构体字段的元数据功能,供DFI插件读取识别被保护字段。 4、在LLVM opt新增pass 重新生成前向CFI插件中插桩的autcall内置函数 5、在后端函数栈前言后语中增加后向CFI的指令插桩 6、在后端新增pass处理前向CFI插件插入的伪指令和伪指令降级为机器指令。 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- clang/include/clang/Basic/Attr.td | 14 ++ clang/include/clang/Basic/AttrDocs.td | 14 ++ clang/include/clang/Pac/PacDfi.h | 27 +++ 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/Pac/CMakeLists.txt | 6 + clang/lib/Pac/PacDfi.cpp | 106 ++++++++++ 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/include/llvm/PARTS/AArch64InstInfo.td | 29 +++ llvm/include/llvm/PARTS/Intrinsics.td | 13 ++ llvm/include/llvm/PARTS/Parts.h | 43 ++++ llvm/lib/CMakeLists.txt | 1 + llvm/lib/PARTS/CMakeLists.txt | 23 +++ llvm/lib/PARTS/Parts.cpp | 70 +++++++ llvm/lib/PARTS/PartsPluginPass.cpp | 106 ++++++++++ llvm/lib/Target/AArch64/AArch64.h | 2 + llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 10 +- .../Target/AArch64/AArch64FrameLowering.cpp | 4 + .../lib/Target/AArch64/AArch64InstrFormats.td | 2 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 1 + .../AArch64/AArch64MachineFunctionInfo.h | 7 +- .../AArch64PARTS/AArch64EarlyPartsCpiPass.cpp | 178 +++++++++++++++++ .../AArch64PARTS/AArch64PartsCpiPass.cpp | 142 +++++++++++++ .../AArch64PARTS/AArch64PartsPassCommon.h | 101 ++++++++++ .../AArch64PARTS/PartsFrameLowering.cpp | 188 ++++++++++++++++++ .../AArch64/AArch64PARTS/PartsFrameLowering.h | 30 +++ .../Target/AArch64/AArch64TargetMachine.cpp | 11 + llvm/lib/Target/AArch64/CMakeLists.txt | 7 + 33 files changed, 1151 insertions(+), 5 deletions(-) create mode 100644 clang/include/clang/Pac/PacDfi.h create mode 100644 clang/lib/Pac/CMakeLists.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/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/include/clang/Pac/PacDfi.h b/clang/include/clang/Pac/PacDfi.h new file mode 100644 index 000000000000..b9b8b8f1a8ef --- /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/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..a53f4220969c 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); + PacDfiEmitStructFieldsMetadata(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/Pac/CMakeLists.txt b/clang/lib/Pac/CMakeLists.txt new file mode 100644 index 000000000000..9241a8c85448 --- /dev/null +++ b/clang/lib/Pac/CMakeLists.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..a2e2303c3bd9 --- /dev/null +++ b/clang/lib/Pac/PacDfi.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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/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/ParsedTemplate.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); + } + ++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.getOrInsertNamedMetadata(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())); +} \ No newline at end of file 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..5487b8f25004 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -9093,6 +9093,14 @@ 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 fc66bdfc35e0..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" //===----------------------------------------------------------------------===// // 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 new file mode 100644 index 000000000000..62c8ad6ea154 --- /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]>; +} diff --git a/llvm/include/llvm/PARTS/Intrinsics.td b/llvm/include/llvm/PARTS/Intrinsics.td new file mode 100644 index 000000000000..eb1386873caa --- /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/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/PARTS/CMakeLists.txt b/llvm/lib/PARTS/CMakeLists.txt new file mode 100644 index 000000000000..196de8467f3e --- /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..1f0a5cde24b0 --- /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..97319040e10d --- /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 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 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..552daedc0555 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::createReg(MI->getOperand(0).getReg())); + TmpInst.addOperand(MCOperand::createReg(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/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64EarlyPartsCpiPass.cpp new file mode 100644 index 000000000000..63d38b6729f9 --- /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(MachineInstr *MI_indcall); + inline void replaceBranchByAuthenticatedBranch(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--; + replaceBranchByAuthenticatedBranch(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(MachineInstr *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->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(); + if (AUTCALLinstr_oper0 == BLRinstr_oper0) { + return &*MIi; + } + } + } + } + return nullptr; +} + +inline bool AArch64EarlyPartsCpiPass::isIndirectCall(const MachineInstr &MI) const { + 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::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)); + 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.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..4ea8a652ee62 --- /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, MachineInstr &MI); + + inline bool handleInstruction(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MIi); + inline void lowerPARTSAUTIA(MachineBasicBlock &MBB, MachineInstr &MI); + void lowerPARTSIntrinsicCommon(MachineBasicBlock &MBB, MachineInstr &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 &MF) { + 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 intrinsic!!"); + 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, MachineInstr &MI) { + lowerPARTSIntrinsicCommon(MBB, MI, TII->get(AArch64::PACIA)); + ++StatPacia; +} + +inline void AArch64PartsCpiPass::lowerPARTSAUTIA(MachineBasicBlock &MBB, MachineInstr &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, MachineInstr &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..524be5733b68 --- /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(); +} + +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..2414ddbf1bb5 --- /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-function_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().createNamedTempSymbol(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, MIi, 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, MIi, 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..9d21d8a101a6 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/PartsFrameLowering.h @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Author: Hans Liljestrand +// Zaheer Ahmed Gauhar +// 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/TargetRegisterInfo.h" +#include "llvm/IR/DebugLoc.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 diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 47e4c6589c26..e0a1530d63a6 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 f446f23aeca75b871c5d41e768ca9405683c20e5 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Fri, 3 Mar 2023 17:23:36 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 添加OHOS_LOCAL注释 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- clang/include/clang/Basic/Attr.td | 2 ++ clang/include/clang/Basic/AttrDocs.td | 34 ++++++++++--------- clang/lib/CMakeLists.txt | 2 +- clang/lib/CodeGen/CMakeLists.txt | 2 +- clang/lib/CodeGen/CodeGenModule.cpp | 4 ++- clang/lib/CodeGen/CodeGenTypes.cpp | 4 ++- clang/lib/Parse/CMakeLists.txt | 2 +- clang/lib/Parse/ParseDecl.cpp | 4 ++- clang/lib/Sema/SemaDeclAttr.cpp | 3 +- llvm/include/llvm/IR/IntrinsicsAArch64.td | 2 +- llvm/lib/CMakeLists.txt | 2 +- llvm/lib/Target/AArch64/AArch64.h | 2 ++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 2 ++ .../Target/AArch64/AArch64FrameLowering.cpp | 8 ++--- .../lib/Target/AArch64/AArch64InstrFormats.td | 2 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 2 +- .../AArch64/AArch64MachineFunctionInfo.h | 4 ++- .../Target/AArch64/AArch64TargetMachine.cpp | 9 +++-- llvm/lib/Target/AArch64/CMakeLists.txt | 6 +++- 19 files changed, 61 insertions(+), 35 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 6797519796ab..3c11f7ba85ae 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1742,6 +1742,7 @@ def NoUniqueAddress : InheritableAttr, TargetSpecificAttr { let SimpleHandler = 1; } +// OHOS_LOCAL start def PacDataTag : InheritableAttr { let Spellings = [GCC<"pac_protected_data">]; let Subjects = SubjectList<[Field], ErrorDiag>; @@ -1755,6 +1756,7 @@ def PacPtrTag : InheritableAttr { let Documentation = [PacPtrTagDocs]; let SimpleHandler = 1; } +// OHOS_LOCAL end def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index caad49026d28..ff9a7c5bc84a 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -513,16 +513,16 @@ def NoMergeDocs : Documentation { let Category = DocCatStmt; let Content = [{ If a statement is marked ``nomerge`` and contains call expressions, those call -expressions inside the statement will not be merged during optimization. This +expressions inside the statement will not be merged during optimization. This attribute can be used to prevent the optimizer from obscuring the source location of certain calls. For example, it will prevent tail merging otherwise identical code sequences that raise an exception or terminate the program. Tail merging normally reduces the precision of source location information, making stack traces less useful for debugging. This attribute gives the user control -over the tradeoff between code size and debug information precision. +over the tradeoff between code size and debug information precision. -``nomerge`` attribute can also be used as function attribute to prevent all -calls to the specified function from merging. It has no effect on indirect +``nomerge`` attribute can also be used as function attribute to prevent all +calls to the specified function from merging. It has no effect on indirect calls. }]; } @@ -1355,6 +1355,7 @@ in C++11 onwards. }]; } +// OHOS_LOCAL start def PacDataTagDocs : Documentation { let Category = DocCatField; let Content = [{ @@ -1368,6 +1369,7 @@ def PacPtrTagDocs : Documentation { The ``pac_protected_ptr`` attribute asks the compiler to protect the struct pointer type field with PA }]; } +// OHOS_LOCAL end def ObjCRequiresSuperDocs : Documentation { let Category = DocCatFunction; @@ -1569,7 +1571,7 @@ attributes are ignored. Supported platforms are: ``watchos`` Apple's watchOS operating system. The minimum deployment target is specified by the ``-mwatchos-version-min=*version*`` command-line argument. - + ``driverkit`` Apple's DriverKit userspace kernel extensions. The minimum deployment target is specified as part of the triple. @@ -3830,7 +3832,7 @@ Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null -pointers. Clang supports several kinds of nullability attributes: the +pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot @@ -4006,7 +4008,7 @@ memory is not available rather than returning a null pointer: The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner -(because it is part of the type system) and does not imply undefined behavior, +(because it is part of the type system) and does not imply undefined behavior, making it more widely applicable }]; } @@ -5907,15 +5909,15 @@ def CFGuardDocs : Documentation { let Content = [{ Code can indicate CFG checks are not wanted with the ``__declspec(guard(nocf))`` attribute. This directs the compiler to not insert any CFG checks for the entire -function. This approach is typically used only sparingly in specific situations -where the programmer has manually inserted "CFG-equivalent" protection. The -programmer knows that they are calling through some read-only function table -whose address is obtained through read-only memory references and for which the -index is masked to the function table limit. This approach may also be applied -to small wrapper functions that are not inlined and that do nothing more than -make a call through a function pointer. Since incorrect usage of this directive -can compromise the security of CFG, the programmer must be very careful using -the directive. Typically, this usage is limited to very small functions that +function. This approach is typically used only sparingly in specific situations +where the programmer has manually inserted "CFG-equivalent" protection. The +programmer knows that they are calling through some read-only function table +whose address is obtained through read-only memory references and for which the +index is masked to the function table limit. This approach may also be applied +to small wrapper functions that are not inlined and that do nothing more than +make a call through a function pointer. Since incorrect usage of this directive +can compromise the security of CFG, the programmer must be very careful using +the directive. Typically, this usage is limited to very small functions that only call one function. `Control Flow Guard documentation ` diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index f69bff2588e7..4b109748e000 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -30,4 +30,4 @@ if(CLANG_INCLUDE_TESTS) endif() add_subdirectory(Interpreter) add_subdirectory(Support) -add_subdirectory(Pac) +add_subdirectory(Pac) // OHOS_LOCAL diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 7dbf0c8f8d25..60a45250389d 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -96,5 +96,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization - pacDfi + pacDfi # OHOS_LOCAL ) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a53f4220969c..a07a8d74a956 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -47,7 +47,9 @@ #include "clang/CodeGen/BackendUtil.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/Frontend/FrontendDiagnostic.h" +// OHOS_LOCAL start #include "clang/Pac/PacDfi.h" +// OHOS_LOCAL end #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -836,7 +838,7 @@ void CodeGenModule::Release() { if (getLangOpts().OpenMPIsDevice) getModule().addModuleFlag(llvm::Module::Max, "openmp-device", LangOpts.OpenMP); - PacDfiEmitStructFieldsMetadata(getModule(), VMContext); + PacDfiEmitStructFieldsMetadata(getModule(), VMContext); // OHOS_LOCAL // 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 31ad6e33cddd..97725ccbae8c 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -22,7 +22,9 @@ #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "clang/CodeGen/CGFunctionInfo.h" +// OHOS_LOCAL start #include "clang/Pac/PacDfi.h" +// OHOS_LOCAL end #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" @@ -853,7 +855,7 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { if (!Entry) { Entry = llvm::StructType::create(getLLVMContext()); addRecordTypeName(RD, Entry, ""); - PacDfiRecordDecl2StructName(RD, Entry); + PacDfiRecordDecl2StructName(RD, Entry); // OHOS_LOCAL } llvm::StructType *Ty = Entry; diff --git a/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt index 76ca0ac97b0f..c6e17e5948bc 100644 --- a/clang/lib/Parse/CMakeLists.txt +++ b/clang/lib/Parse/CMakeLists.txt @@ -28,7 +28,7 @@ add_clang_library(clangParse clangBasic clangLex clangSema - pacDfi + pacDfi # OHOS_LOCAL DEPENDS omp_gen diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e983d65951bc..9a6ea02f42a5 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -25,7 +25,9 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" +// OHOS_LOCAL start #include "clang/Pac/PacDfi.h" +// OHOS_LOCAL end #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" @@ -4531,7 +4533,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } // find pac_tag attr fields, and insert new fields - PacDfiParseStruct(TagDecl, Actions.getASTContext()); + PacDfiParseStruct(TagDecl, Actions.getASTContext()); // OHOS_LOCAL T.consumeClose(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5487b8f25004..bac86bb767a1 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -9093,7 +9093,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_UsingIfExists: handleSimpleAttribute(S, D, AL); break; - + // OHOS_LOCAL start case ParsedAttr::AT_PacDataTag: handleSimpleAttribute(S, D, AL); break; @@ -9102,6 +9102,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleSimpleAttribute(S, D, AL); break; } + // OHOS_LOCAL end } /// 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 235c35f92cc0..c126267950e1 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" // OHOS_LOCAL //===----------------------------------------------------------------------===// // Memory Tagging Extensions (MTE) Intrinsics let TargetPrefix = "aarch64" in { diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt index 476024239441..dedbc5775990 100644 --- a/llvm/lib/CMakeLists.txt +++ b/llvm/lib/CMakeLists.txt @@ -43,7 +43,7 @@ if (LLVM_INCLUDE_TESTS) endif() add_subdirectory(WindowsDriver) add_subdirectory(WindowsManifest) -add_subdirectory(PARTS) +add_subdirectory(PARTS) # OHOS_LOCAL 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 33917b444d76..43f7c00028d1 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -68,8 +68,10 @@ FunctionPass *createAArch64PostLegalizerLowering(); FunctionPass *createAArch64PostSelectOptimize(); FunctionPass *createAArch64StackTaggingPass(bool IsOptNone); FunctionPass *createAArch64StackTaggingPreRAPass(); +// OHOS_LOCAL start FunctionPass *createAArch64EarlyPartsCpiPass(); FunctionPass *createAArch64PartsCpiPass(); +// OHOS_LOCAL end void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 552daedc0555..e786056aafdf 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1310,6 +1310,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); return; } + // OHOS_LOCAL start case AArch64::TCRETURNriAA: { MCInst TmpInst; TmpInst.setOpcode(AArch64::BRAA); @@ -1318,6 +1319,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); return; } + // OHOS_LOCAL end 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 53ad04b31929..72acfa7fc66a 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -192,7 +192,7 @@ #include "AArch64StackProtectorRetLowering.h" #include "AArch64Subtarget.h" #include "AArch64TargetMachine.h" -#include "AArch64PARTS/PartsFrameLowering.h" +#include "AArch64PARTS/PartsFrameLowering.h" // OHOS_LOCAL #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "llvm/ADT/ScopeExit.h" @@ -275,7 +275,7 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF, unsigned RetOpcode = MBBI->getOpcode(); IsTailCallReturn = RetOpcode == AArch64::TCRETURNdi || RetOpcode == AArch64::TCRETURNri || - RetOpcode == AArch64::TCRETURNriAA || + RetOpcode == AArch64::TCRETURNriAA || // OHOS_LOCAL RetOpcode == AArch64::TCRETURNriBTI; } AArch64FunctionInfo *AFI = MF.getInfo(); @@ -1431,7 +1431,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, .setMIFlags(MachineInstr::FrameSetup); } } - PartsFrameLowering::instrumentPrologue(TII, Subtarget.getRegisterInfo(), MBB, MBBI, DebugLoc()); + PartsFrameLowering::instrumentPrologue(TII, Subtarget.getRegisterInfo(), MBB, MBBI, DebugLoc()); // OHOS_LOCAL if (EmitCFI && MFnI.isMTETagged()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED)) .setMIFlag(MachineInstr::FrameSetup); @@ -1917,7 +1917,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, auto FinishingTouches = make_scope_exit([&]() { InsertReturnAddressAuth(MF, MBB); - PartsFrameLowering::instrumentEpilogue(TII, Subtarget.getRegisterInfo(), MBB); + PartsFrameLowering::instrumentEpilogue(TII, Subtarget.getRegisterInfo(), MBB); // OHOS_LOCAL 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 aabbf5079976..7a4cbab21ee8 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<[WriteBrReg]> { + : I, Sched<[WriteBrReg]> { // OHOS_LOCAL 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 772b787e4aca..5e25409d6343 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -8413,4 +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 +include "llvm/PARTS/AArch64InstInfo.td" // OHOS_LOCAL \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index 987be8a8a066..5fbf1e7e195b 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -188,7 +188,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { 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; + MCSymbol *PartsSym = nullptr; // OHOS_LOCAL public: explicit AArch64FunctionInfo(MachineFunction &MF); @@ -435,8 +435,10 @@ public: bool needsDwarfUnwindInfo() const; bool needsAsyncDwarfUnwindInfo() const; + // OHOS_LOCAL start void setPartsSym(MCSymbol *Sym) { PartsSym = Sym; } MCSymbol *getPartsSym() const { return PartsSym; } + // OHOS_LOCAL end 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 e0a1530d63a6..1619b1806065 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -42,7 +42,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/TargetRegistry.h" -#include "llvm/PARTS/Parts.h" +#include "llvm/PARTS/Parts.h" // OHOS_LOCAL #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" @@ -592,8 +592,10 @@ void AArch64PassConfig::addIRPasses() { if (TM->getTargetTriple().isOSWindows()) addPass(createCFGuardCheckPass()); + // OHOS_LOCAL start if (PARTS::useFeCfi()) addPass(PARTS::createPartsPluginPass()); + // OHOS_LOCAL end if (TM->Options.JMCInstrument) addPass(createJMCInstrumenterPass()); @@ -647,10 +649,11 @@ bool AArch64PassConfig::addInstSelector() { getOptLevel() != CodeGenOpt::None) addPass(createAArch64CleanupLocalDynamicTLSPass()); + // OHOS_LOCAL start if (PARTS::useFeCfi()) // Replace indirect jump instruction such as : BR BLR --> BRAA BLRAA addPass(createAArch64EarlyPartsCpiPass()); - + // OHOS_LOCAL end return false; } @@ -814,8 +817,10 @@ void AArch64PassConfig::addPreEmitPass() { TM->getTargetTriple().isOSBinFormatMachO()) addPass(createAArch64CollectLOHPass()); + // OHOS_LOCAL start if (PARTS::useFeCfi()) addPass(createAArch64PartsCpiPass()); + // OHOS_LOCAL end } void AArch64PassConfig::addPreEmitPass2() { diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index 54a9482ab907..25c31485738a 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -40,7 +40,7 @@ add_llvm_target(AArch64CodeGen GISel/AArch64PostLegalizerLowering.cpp GISel/AArch64PostSelectOptimize.cpp GISel/AArch64RegisterBankInfo.cpp - AArch64PARTS/PartsFrameLowering.cpp + AArch64PARTS/PartsFrameLowering.cpp # OHOS_LOCAL AArch64A57FPLoadBalancing.cpp AArch64AdvSIMDScalarPass.cpp AArch64AsmPrinter.cpp @@ -86,15 +86,19 @@ add_llvm_target(AArch64CodeGen AArch64TargetTransformInfo.cpp SVEIntrinsicOpts.cpp AArch64SIMDInstrOpt.cpp + # OHOS_LOCAL start AArch64PARTS/AArch64EarlyPartsCpiPass.cpp AArch64PARTS/AArch64PartsCpiPass.cpp + # OHOS_LOCAL end DEPENDS intrinsics_gen + # OHOS_LOCAL start Parts LINK_LIBS Parts + # OHOS_LOCAL end LINK_COMPONENTS AArch64Desc -- Gitee From 7809679939664fe5253119d233133e5ef08cc96e Mon Sep 17 00:00:00 2001 From: baojingjing Date: Mon, 6 Mar 2023 16:22:33 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 修改OHOS_LOCAL注释 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- clang/lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 4b109748e000..71fa062db523 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -30,4 +30,4 @@ if(CLANG_INCLUDE_TESTS) endif() add_subdirectory(Interpreter) add_subdirectory(Support) -add_subdirectory(Pac) // OHOS_LOCAL +add_subdirectory(Pac) # OHOS_LOCAL -- Gitee From ed149e36525dcad0e1e286870bd7f99e8d75e720 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Tue, 14 Mar 2023 17:00:25 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 增加builtin函数获取前向functionid,修复在鸿蒙上未识别到结构体名称导致的崩溃问题 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- clang/include/clang/Basic/TokenKinds.def | 2 + clang/include/clang/Pac/PacDfi.h | 3 +- clang/lib/AST/ExprConstant.cpp | 9 +++ clang/lib/AST/ItaniumMangle.cpp | 5 ++ clang/lib/CodeGen/CGExprScalar.cpp | 10 ++++ clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/Pac/CMakeLists.txt | 1 + clang/lib/Pac/PacDfi.cpp | 49 +++++++++------- clang/lib/Parse/ParseExpr.cpp | 14 ++++- llvm/include/llvm/PARTS/Parts.h | 3 +- llvm/lib/PARTS/Parts.cpp | 73 +++++++++++++++++++++++- 11 files changed, 142 insertions(+), 29 deletions(-) diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 84fc0893c8b5..47e4c2754dd0 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -434,6 +434,8 @@ KEYWORD(__builtin_LINE , KEYALL) KEYWORD(__builtin_COLUMN , KEYALL) KEYWORD(__builtin_source_location , KEYCXX) +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_get_modifier_bytype, PacModifierByType, KEYALL) // OHOS_LOCAL + // __builtin_types_compatible_p is a GNU C extension that we handle like a C++ // type trait. TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX) diff --git a/clang/include/clang/Pac/PacDfi.h b/clang/include/clang/Pac/PacDfi.h index b9b8b8f1a8ef..a0564b19a42b 100644 --- a/clang/include/clang/Pac/PacDfi.h +++ b/clang/include/clang/Pac/PacDfi.h @@ -17,10 +17,11 @@ #include "clang/AST/Decl.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" +#include "clang/CodeGen/CodeGenABITypes.h" using namespace clang; void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx); -void PacDfiEmitStructFieldsMetadata(llvm::Module &M, llvm::LLVMContext &VMContext); +void PacDfiEmitStructFieldsMetadata(llvm::Module &M, llvm::LLVMContext &VMContext, CodeGen::CodeGenModule *CGM); void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry); #endif diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 9d92c848ccb8..d22135079fa6 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13280,6 +13280,15 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( return false; return Success(Sizeof, E); } + // OHOS_LOCAL Begin + case UETT_PacModifierByType: { + QualType FuncTy = E->getTypeOfArgument(); + if (!FuncTy->isFunctionType()) { + return false; + } + return Success(0, E); + } + // OHOS_LOCAL End case UETT_OpenMPRequiredSimdAlign: assert(E->isArgumentType()); return Success( diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 91f41778ee68..b1091945d85f 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4691,6 +4691,11 @@ recurse: Diags.Report(DiagID); return; } + // OHOS_LOCAL Begin + case UETT_PacModifierByType: { + return; + } + // OHOS_LOCAL End } break; } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index b150aaa376eb..747bb00dee29 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -42,6 +42,7 @@ #include "llvm/IR/MatrixBuilder.h" #include "llvm/IR/Module.h" #include "llvm/Support/TypeSize.h" +#include "llvm/PARTS/Parts.h" // OHOS_LOCAL #include using namespace clang; @@ -2999,7 +3000,16 @@ ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( E->getTypeOfArgument()->getPointeeType())) .getQuantity(); return llvm::ConstantInt::get(CGF.SizeTy, Alignment); + // OHOS_LOCAL Begin + } else if (E->getKind() == clang::UETT_PacModifierByType) { + auto ArgTy = E->getTypeOfArgument(); + auto *FuncTy = ConvertType(ArgTy); + if (!FuncTy) { + return llvm::ConstantInt::get(CGF.Int64Ty, 0); + } + return llvm::ConstantInt::get(CGF.Int64Ty, llvm::PARTS::getTypeIdFor(FuncTy)); } + // OHOS_LOCAL End // If this isn't sizeof(vla), the result must be constant; use the constant // folding logic so we don't have to duplicate it here. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a07a8d74a956..6e61a85771d4 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -838,7 +838,7 @@ void CodeGenModule::Release() { if (getLangOpts().OpenMPIsDevice) getModule().addModuleFlag(llvm::Module::Max, "openmp-device", LangOpts.OpenMP); - PacDfiEmitStructFieldsMetadata(getModule(), VMContext); // OHOS_LOCAL + PacDfiEmitStructFieldsMetadata(getModule(), VMContext, this); // OHOS_LOCAL // Emit OpenCL specific module metadata: OpenCL/SPIR version. if (LangOpts.OpenCL || (LangOpts.CUDAIsDevice && getTriple().isSPIRV())) { diff --git a/clang/lib/Pac/CMakeLists.txt b/clang/lib/Pac/CMakeLists.txt index 9241a8c85448..bc1d3dcffaa0 100644 --- a/clang/lib/Pac/CMakeLists.txt +++ b/clang/lib/Pac/CMakeLists.txt @@ -3,4 +3,5 @@ add_clang_library(pacDfi LINK_LIBS Parts + clangCodeGen ) \ No newline at end of file diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp index a2e2303c3bd9..39ad60e39d33 100644 --- a/clang/lib/Pac/PacDfi.cpp +++ b/clang/lib/Pac/PacDfi.cpp @@ -19,27 +19,28 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Pac/PacDfi.h" +#include "llvm/IR/Metadata.h" +#include "clang/CodeGen/CodeGenABITypes.h" using namespace clang; std::map RecordDecl2StructName; -std::map> PacFieldInfos; -std::map> PacPtrInfos; - +std::map> PacPtrNameInfos; +std::map> PacFieldNameInfos; +std::map RecordDecl2StructType; 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; + std::vector PacPtrNames; + std::vector PacFieldNames; unsigned int ArraySize = 0; for (auto Field : TagDecl->fields()) { if (Field->hasAttr()) { - PacFieldIdxs.push_back(FieldIdx); + PacFieldNames.push_back(Field); if (Field->getType()->isConstantArrayType()) { auto ArrayTy = dyn_cast(Field->getType()); ArraySize += ArrayTy->getSize().getZExtValue(); @@ -47,12 +48,11 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) ++ArraySize; } } else if (Field->hasAttr()) { - PacPtrIdxs.push_back(FieldIdx); + PacPtrNames.push_back(Field); } - ++FieldIdx; } - if (!PacFieldIdxs.empty()) { + if (!PacFieldNames.empty()) { llvm::APInt ArraySizeInt(32, ArraySize); auto ArrayTy = Ctx.getConstantArrayType(Ctx.IntTy, ArraySizeInt, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/ 0); @@ -60,22 +60,26 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) ArrayTy, nullptr, nullptr, true, ICIS_NoInit); TagDecl->addDecl(PacFD); - PacFieldInfos.insert(std::make_pair(TagDecl, PacFieldIdxs)); + PacFieldNameInfos.insert(std::make_pair(TagDecl, PacFieldNames)); } - if (!PacPtrIdxs.empty()) { - PacPtrInfos.insert(std::make_pair(TagDecl, PacPtrIdxs)); + if (!PacPtrNames.empty()) { + PacPtrNameInfos.insert(std::make_pair(TagDecl, PacPtrNames)); } } -void PacDfiCreateMetaData(std::map> &fieldInfos, StringRef mdName, - llvm::Module &M, llvm::LLVMContext &VMContext) +void PacDfiCreateMetaData(std::map> &fieldInfos, StringRef mdName, + llvm::Module &M, llvm::LLVMContext &VMContext, CodeGen::CodeGenModule *CGM) { llvm::NamedMDNode *PacNMD = M.getOrInsertNamedMetadata(mdName); for (auto item : fieldInfos) { + if (RecordDecl2StructName.find(item.first) == RecordDecl2StructName.end()) { + continue; + } std::vector PacFields; auto styName = RecordDecl2StructName.find(item.first)->second; PacFields.push_back(llvm::MDString::get(VMContext, styName)); - for (auto idx : item.second) { + for (auto Field : item.second) { + unsigned idx = CodeGen::getLLVMFieldNumber(*CGM, item.first, Field); PacFields.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( llvm::Type::getInt32Ty(VMContext), idx))); } @@ -83,17 +87,17 @@ void PacDfiCreateMetaData(std::map> &fiel } } -void PacDfiEmitStructFieldsMetadata(llvm::Module &M, llvm::LLVMContext &VMContext) +void PacDfiEmitStructFieldsMetadata(llvm::Module &M, llvm::LLVMContext &VMContext, CodeGen::CodeGenModule *CGM) { 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 (!PacFieldNameInfos.empty()) { + PacDfiCreateMetaData(PacFieldNameInfos, "pa_field_info", M, VMContext, CGM); } - if (!PacPtrInfos.empty()) { - PacDfiCreateMetaData(PacPtrInfos, "pa_ptr_field_info", M, VMContext); + if (!PacPtrNameInfos.empty()) { + PacDfiCreateMetaData(PacPtrNameInfos, "pa_ptr_field_info", M, VMContext, CGM); } } @@ -102,5 +106,8 @@ void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry) if (!llvm::PARTS::useDataFieldTag()) { return; } + if (Entry->isLiteral()) { + return; + } RecordDecl2StructName.insert(std::make_pair(RD, Entry->getName())); } \ No newline at end of file diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index a6a946d7f31b..1c0e0c62a3c5 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1422,6 +1422,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' case tok::kw___builtin_omp_required_simd_align: + case tok::kw___builtin_get_modifier_bytype: // OHOS_LOCAL if (NotPrimaryExpression) *NotPrimaryExpression = true; AllowSuffix = false; @@ -2284,7 +2285,9 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, - tok::kw___builtin_omp_required_simd_align) && + tok::kw___builtin_omp_required_simd_align, + tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL + ) && "Not a typeof/sizeof/alignof/vec_step expression!"); ExprResult Operand; @@ -2294,7 +2297,9 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, // If construct allows a form without parenthesis, user may forget to put // pathenthesis around type name. if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, - tok::kw__Alignof)) { + tok::kw__Alignof, + tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL + )) { if (isTypeIdUnambiguously()) { DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); @@ -2479,7 +2484,10 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { ExprKind = UETT_VecStep; else if (OpTok.is(tok::kw___builtin_omp_required_simd_align)) ExprKind = UETT_OpenMPRequiredSimdAlign; - + // OHOS_LOCAL Begin + else if (OpTok.is(tok::kw___builtin_get_modifier_bytype)) + ExprKind = UETT_PacModifierByType; + // OHOS_LOCAL End if (isCastExpr) return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), ExprKind, diff --git a/llvm/include/llvm/PARTS/Parts.h b/llvm/include/llvm/PARTS/Parts.h index c553be38f246..b4a29e885885 100644 --- a/llvm/include/llvm/PARTS/Parts.h +++ b/llvm/include/llvm/PARTS/Parts.h @@ -32,12 +32,13 @@ enum PartsDpiType { bool useBeCfi(); bool useFeCfi(); +bool useDataPointerConfig(); bool useDataPointerProtection(); bool useDataFieldTag(); bool useDataFieldProtection(); PartsBeCfiType getBeCfiType(); Pass *createPartsPluginPass(); - +uint16_t getTypeIdFor(const Type *T); } } #endif \ No newline at end of file diff --git a/llvm/lib/PARTS/Parts.cpp b/llvm/lib/PARTS/Parts.cpp index 1f0a5cde24b0..a49b889829a6 100644 --- a/llvm/lib/PARTS/Parts.cpp +++ b/llvm/lib/PARTS/Parts.cpp @@ -13,10 +13,12 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" - +#include "llvm/Support/SHA256.h" +#include +#include using namespace llvm; using namespace PARTS; - +static std::map TypeIdCache; static cl::opt EnableFeCfi( "FECFI", cl::Hidden, cl::desc("forward-edge CFI"), @@ -50,6 +52,10 @@ bool llvm::PARTS::useBeCfi() { return EnableBeCfi; } +bool llvm::PARTS::useDataPointerConfig() { + return EnableDfiDpp; +} + bool llvm::PARTS::useDataPointerProtection() { return EnableDfiDpp || EnableDfiDppTag; } @@ -67,4 +73,67 @@ PartsBeCfiType PARTS::getBeCfiType() { return PartsBeCfiFull; } return PartsBeCfiNone; +} + +static void buildTypeString(const Type *T, llvm::raw_string_ostream &O) +{ + if (T->isPointerTy()) { + O << "ptr."; + buildTypeString(T->getNonOpaquePointerElementType(), O); + } else if (T->isStructTy()) { + if (dyn_cast(T)->isLiteral()) { + return; + } + auto Sty = dyn_cast(T)->getStructName(); + std::regex E("^(\\w+\\.\\w+)(\\.\\w+)?$"); + O << std::regex_replace(Sty.str(), E, "$1"); + } else if (T->isArrayTy()) { + O << "ptr."; + buildTypeString(T->getArrayElementType(), O); + } else if (T->isFunctionTy()) { + auto *FuncTy = dyn_cast<::llvm::FunctionType>(T); + O << "f."; + buildTypeString(FuncTy->getReturnType(), O); + for (auto *Param = FuncTy->param_begin(); Param != FuncTy->param_end(); Param++) { + buildTypeString(*Param, O); + } + } else if (T->isVectorTy()) { + O << "vec." << dyn_cast<::llvm::VectorType>(T)->getElementCount().getKnownMinValue(); + buildTypeString(dyn_cast<::llvm::VectorType>(T)->getElementType(), O); + } else if (T->isVoidTy()) { + O << "v"; + } else { + /* Make sure we've handled all cases we want to*/ + if (!(T->isIntegerTy() || T->isFloatingPointTy())) { + outs() << "buildTypeString: assert!!\n"; + } + T->print(O); + } +} + +static uint16_t getTypeId(const std::string &Context) +{ + uint16_t TheTypeId = 0; + llvm::SHA256 ALG; + auto HashCode = ALG.hash(ArrayRef(reinterpret_cast(Context.c_str()), Context.size())); + std::copy(HashCode.begin(), HashCode.begin() + 2, reinterpret_cast(&TheTypeId)); + return TheTypeId; +} + +uint16_t llvm::PARTS::getTypeIdFor(const Type *T) +{ + if (!T->isPointerTy()) { + return 0; + } + auto TypeIdIter = TypeIdCache.find(T); + if (TypeIdIter != TypeIdCache.end()) { + return TypeIdIter->second; + } + std::string Buf; + llvm::raw_string_ostream TypeIdStr(Buf); + buildTypeString(T, TypeIdStr); + TypeIdStr.flush(); + uint16_t TheTypeId = getTypeId(Buf); + TypeIdCache.emplace(T, TheTypeId); + return TheTypeId; } \ No newline at end of file -- Gitee From 7c38d4232b62403297824e352c91d42393a670f3 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Wed, 29 Mar 2023 17:36:58 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 新增DFI内置指令,增加对pac_protected_data/ptr属性不支持的类型进行告警 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- .../clang/Basic/DiagnosticParseKinds.td | 7 +- clang/include/clang/Pac/PacDfi.h | 2 +- clang/lib/Pac/PacDfi.cpp | 33 +++++-- clang/lib/Parse/ParseDecl.cpp | 2 +- llvm/include/llvm/PARTS/AArch64InstInfo.td | 13 +++ llvm/include/llvm/PARTS/Intrinsics.td | 3 + llvm/lib/Target/AArch64/AArch64.h | 1 + .../AArch64PARTS/AArch64PartsDpiPass.cpp | 92 +++++++++++++++++++ .../Target/AArch64/AArch64TargetMachine.cpp | 2 + .../InstCombineLoadStoreAlloca.cpp | 3 +- 10 files changed, 145 insertions(+), 13 deletions(-) create mode 100644 llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 18adb21e2be0..037e29a5155f 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -539,7 +539,7 @@ def err_invalid_operator_on_type : Error< def err_expected_unqualified_id : Error< "expected %select{identifier|unqualified-id}0">; def err_while_loop_outside_of_a_function : Error< - "while loop outside of a function">; + "while loop outside of a function">; def err_brackets_go_after_unqualified_id : Error< "brackets are not allowed here; to declare an array, " "place the brackets after the %select{identifier|name}0">; @@ -1610,4 +1610,9 @@ def ext_hlsl_access_specifiers : ExtWarn< "access specifiers are a clang HLSL extension">, InGroup; +// OHOS_LOCAL start +def warn_unsupported_pac_dfi_type : Warning< + "unsupported type %0 for attribute '%1'">; +// OHOS_LOCAL end + } // end of Parser diagnostics diff --git a/clang/include/clang/Pac/PacDfi.h b/clang/include/clang/Pac/PacDfi.h index a0564b19a42b..0d028417cdcc 100644 --- a/clang/include/clang/Pac/PacDfi.h +++ b/clang/include/clang/Pac/PacDfi.h @@ -20,7 +20,7 @@ #include "clang/CodeGen/CodeGenABITypes.h" using namespace clang; -void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx); +void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine &Diags); void PacDfiEmitStructFieldsMetadata(llvm::Module &M, llvm::LLVMContext &VMContext, CodeGen::CodeGenModule *CGM); void PacDfiRecordDecl2StructName(const RecordDecl *RD, llvm::StructType *Entry); diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp index 39ad60e39d33..7215f2744d59 100644 --- a/clang/lib/Pac/PacDfi.cpp +++ b/clang/lib/Pac/PacDfi.cpp @@ -21,14 +21,14 @@ #include "clang/Pac/PacDfi.h" #include "llvm/IR/Metadata.h" #include "clang/CodeGen/CodeGenABITypes.h" - +#include "clang/Basic/DiagnosticParse.h" using namespace clang; std::map RecordDecl2StructName; std::map> PacPtrNameInfos; std::map> PacFieldNameInfos; std::map RecordDecl2StructType; -void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) +void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine &Diags) { if (!llvm::PARTS::useDataFieldTag()) { return; @@ -38,16 +38,31 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx) std::vector PacFieldNames; unsigned int ArraySize = 0; - for (auto Field : TagDecl->fields()) { + for (auto *Field : TagDecl->fields()) { + auto ElemTy = Field->getType(); if (Field->hasAttr()) { - PacFieldNames.push_back(Field); + unsigned Inc = 1; + // if Field is array type ElemTy is equal to array element type. if (Field->getType()->isConstantArrayType()) { - auto ArrayTy = dyn_cast(Field->getType()); - ArraySize += ArrayTy->getSize().getZExtValue(); - } else { - ++ArraySize; + auto *ArrayTy = llvm::dyn_cast(ElemTy); + ElemTy = ArrayTy->getElementType(); + Inc = ArrayTy->getSize().getZExtValue(); + } + // pac_protected_data [not] support structure type or structure array. + if (ElemTy->isStructureOrClassType()) { + Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << Field->getType() + << Field->getAttr()->getSpelling(); + continue; } + ArraySize += Inc; + PacFieldNames.push_back(Field); } else if (Field->hasAttr()) { + // pac_protected_ptr [only] support pointer type. + if (!ElemTy->isAnyPointerType()) { + Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << Field->getType() + << Field->getAttr()->getSpelling(); + continue; + } PacPtrNames.push_back(Field); } } @@ -78,7 +93,7 @@ void PacDfiCreateMetaData(std::map> &fieldI std::vector PacFields; auto styName = RecordDecl2StructName.find(item.first)->second; PacFields.push_back(llvm::MDString::get(VMContext, styName)); - for (auto Field : item.second) { + for (auto *Field : item.second) { unsigned idx = CodeGen::getLLVMFieldNumber(*CGM, item.first, Field); PacFields.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( llvm::Type::getInt32Ty(VMContext), idx))); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 9a6ea02f42a5..92944a127fcb 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4533,7 +4533,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } // find pac_tag attr fields, and insert new fields - PacDfiParseStruct(TagDecl, Actions.getASTContext()); // OHOS_LOCAL + PacDfiParseStruct(TagDecl, Actions.getASTContext(), Diags); // OHOS_LOCAL T.consumeClose(); diff --git a/llvm/include/llvm/PARTS/AArch64InstInfo.td b/llvm/include/llvm/PARTS/AArch64InstInfo.td index 62c8ad6ea154..6e6ff0fc5615 100644 --- a/llvm/include/llvm/PARTS/AArch64InstInfo.td +++ b/llvm/include/llvm/PARTS/AArch64InstInfo.td @@ -21,6 +21,19 @@ let isPseudo = 1, hasNoSchedulingInfo = 1 in { (ins GPR64:$ptr, GPR64sp:$mod), [(set i64:$dst, (int_pa_autcall GPR64:$ptr, GPR64sp:$mod))], "$dst = $ptr">; + + def PARTS_PACDA : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr, GPR64sp:$mod), + [(set i64:$dst, (int_pa_pacda GPR64:$ptr, GPR64sp:$mod))], + "$dst = $ptr">; + def PARTS_AUTDA : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr, GPR64sp:$mod), + [(set i64:$dst, (int_pa_autda GPR64:$ptr, GPR64sp:$mod))], + "$dst = $ptr">; + def PARTS_XPACD : Pseudo<(outs GPR64:$dst), + (ins GPR64:$ptr), + [(set i64:$dst, (int_pa_xpacd GPR64:$ptr))], + "$dst = $ptr">; } let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in { diff --git a/llvm/include/llvm/PARTS/Intrinsics.td b/llvm/include/llvm/PARTS/Intrinsics.td index eb1386873caa..7acf2ff10820 100644 --- a/llvm/include/llvm/PARTS/Intrinsics.td +++ b/llvm/include/llvm/PARTS/Intrinsics.td @@ -11,3 +11,6 @@ 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_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]>; +def int_pa_xpacd : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>], [IntrNoMem]>; \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index 43f7c00028d1..0fbd926dadf2 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -71,6 +71,7 @@ FunctionPass *createAArch64StackTaggingPreRAPass(); // OHOS_LOCAL start FunctionPass *createAArch64EarlyPartsCpiPass(); FunctionPass *createAArch64PartsCpiPass(); +FunctionPass *createPartsPassDpi(); // OHOS_LOCAL end void initializeAArch64A53Fix835769Pass(PassRegistry&); diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp new file mode 100644 index 000000000000..69fc00d45c6b --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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 includes +#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" +// PARTS includes +#include "llvm/PARTS/Parts.h" +#include "AArch64PartsPassCommon.h" + +#define DEBUG_TYPE "AArch64PartsDpiPass" + +STATISTIC(StatDataStore, DEBUG_TYPE ": instrumented data stores"); +STATISTIC(StatDataLoad, DEBUG_TYPE ": instrumented data loads"); +STATISTIC(StatInsecureDataLoad, DEBUG_TYPE ": Insecure data loads"); + +using namespace llvm; +using namespace llvm::PARTS; + +namespace { +class AArch64PartsDpiPass : public MachineFunctionPass, private AArch64PartsPassCommon { +public: + static char ID; + AArch64PartsDpiPass() : MachineFunctionPass(ID) {} + StringRef getPassName() const override {return DEBUG_TYPE; } + bool runOnMachineFunction(MachineFunction &) override; + bool lowerDpiIntrinsics(MachineFunction &MF); +}; +} + +FunctionPass *llvm::createPartsPassDpi() { + return new AArch64PartsDpiPass(); +} + +char AArch64PartsDpiPass::ID = 0; + +bool AArch64PartsDpiPass::runOnMachineFunction(MachineFunction &MF) { + bool modified = false; + initRunOn(MF); + modified |= lowerDpiIntrinsics(MF); + return modified; +} + +bool AArch64PartsDpiPass::lowerDpiIntrinsics(MachineFunction &MF) { + bool modified = false; + for (auto &MBB : MF) { + for (auto MBBI = MBB.instr_begin(), end = MBB.instr_end(); MBBI != end;) { + auto &MI = *MBBI++; + switch(MI.getOpcode()) { + default: + break; + case AArch64:PARTS_PACDA: + replacePartsIntrinsic(MF, MBB, MI, TII->get(AARCH64::PACDA)); + ++StatDataStore; + modified = true; + break; + case AArch64:PARTS_AUTDA: + replacePartsIntrinsic(MF, MBB, MI, TII->get(AARCH64::AUTDA)); + ++StatDataLoad; + modified = true; + break; + case AArch64:PARTS_XPACD: + replacePartsIntrinsic(MF, MBB, MI); + ++StatInsecureDataLoad; + modified = true; + break; + } + } + } + return modified; +} \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 1619b1806065..83fe4b9b6377 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -820,6 +820,8 @@ void AArch64PassConfig::addPreEmitPass() { // OHOS_LOCAL start if (PARTS::useFeCfi()) addPass(createAArch64PartsCpiPass()); + if (PARTS::useDataPointerProtection) + addPass(createPartsPassDpi); // OHOS_LOCAL end } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index e03b7026f802..4e151a91288d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -1372,7 +1372,8 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) { // If we have a store to a location which is known constant, we can conclude // that the store must be storing the constant value (else the memory // wouldn't be constant), and this must be a noop. - if (AA->pointsToConstantMemory(Ptr)) + // OHOS_LOCAL: CFI&DFI need add pac for ptr saved in constant memory + if (AA->pointsToConstantMemory(Ptr) && (SI.getFunction()->getFnAttribute("no-parts").getValueAsString() != "true")) return eraseInstFromFunction(SI); // Do really simple DSE, to catch cases where there are several consecutive -- Gitee From 062b2b4ba7a349afedfbf11d9666632dce6d727f Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 30 Mar 2023 09:55:03 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 修改AArch64Parts模块编译问题 Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- .../AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp | 12 ++++++------ llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 4 ++-- llvm/lib/Target/AArch64/CMakeLists.txt | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp index 69fc00d45c6b..88edb11064bc 100644 --- a/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64PARTS/AArch64PartsDpiPass.cpp @@ -70,18 +70,18 @@ bool AArch64PartsDpiPass::lowerDpiIntrinsics(MachineFunction &MF) { switch(MI.getOpcode()) { default: break; - case AArch64:PARTS_PACDA: - replacePartsIntrinsic(MF, MBB, MI, TII->get(AARCH64::PACDA)); + case AArch64::PARTS_PACDA: + replacePartsIntrinsic(MF, MBB, MI, TII->get(AArch64::PACDA)); ++StatDataStore; modified = true; break; - case AArch64:PARTS_AUTDA: - replacePartsIntrinsic(MF, MBB, MI, TII->get(AARCH64::AUTDA)); + case AArch64::PARTS_AUTDA: + replacePartsIntrinsic(MF, MBB, MI, TII->get(AArch64::AUTDA)); ++StatDataLoad; modified = true; break; - case AArch64:PARTS_XPACD: - replacePartsIntrinsic(MF, MBB, MI); + case AArch64::PARTS_XPACD: + replacePartsXPACDIntrinsic(MF, MBB, MI); ++StatInsecureDataLoad; modified = true; break; diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 83fe4b9b6377..45628ae66e64 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -820,8 +820,8 @@ void AArch64PassConfig::addPreEmitPass() { // OHOS_LOCAL start if (PARTS::useFeCfi()) addPass(createAArch64PartsCpiPass()); - if (PARTS::useDataPointerProtection) - addPass(createPartsPassDpi); + if ((PARTS::useDataPointerProtection())) + addPass(createPartsPassDpi()); // OHOS_LOCAL end } diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index 25c31485738a..1bc430899572 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -89,6 +89,7 @@ add_llvm_target(AArch64CodeGen # OHOS_LOCAL start AArch64PARTS/AArch64EarlyPartsCpiPass.cpp AArch64PARTS/AArch64PartsCpiPass.cpp + AArch64PARTS/AArch64PartsDpiPass.cpp # OHOS_LOCAL end DEPENDS -- Gitee From 547616bc76e06c0808f084142747a9b60f09c8b2 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Tue, 4 Apr 2023 10:03:31 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 修改OHOS_LOCAL注释 Issue: #I6I9SX:编译器支持PAC特性 测试: 标题:编译器支持PAC特性 描述: 修改OHOS_ Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- llvm/include/llvm/PARTS/Intrinsics.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/PARTS/Intrinsics.td b/llvm/include/llvm/PARTS/Intrinsics.td index 7acf2ff10820..c7461af4a5f5 100644 --- a/llvm/include/llvm/PARTS/Intrinsics.td +++ b/llvm/include/llvm/PARTS/Intrinsics.td @@ -12,5 +12,5 @@ def int_pa_pacia : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_i64_ty], 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_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]>; +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 -- Gitee From 8f40bb3b5ee33efdd37c3f9d78d9d845e3b65d0b Mon Sep 17 00:00:00 2001 From: baojingjing Date: Fri, 7 Apr 2023 11:41:23 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=A0=87=E9=A2=98=EF=BC=9A=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E6=94=AF=E6=8C=81PAC=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 描述: 修改OHOS_LOCAL注释 Issue: #I6I9SX:编译器支持PAC特性 测试: 标题:编译器支持PAC特性 描述: 修改OHOS_ Issue: #I6I9SX:编译器支持PAC特性 测试: Signed-off-by: baojingjing --- clang/lib/Pac/PacDfi.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/Pac/PacDfi.cpp b/clang/lib/Pac/PacDfi.cpp index 7215f2744d59..4ab2b19ea069 100644 --- a/clang/lib/Pac/PacDfi.cpp +++ b/clang/lib/Pac/PacDfi.cpp @@ -49,10 +49,15 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine & Inc = ArrayTy->getSize().getZExtValue(); } // pac_protected_data [not] support structure type or structure array. + if (TagDecl->isUnion()) { + Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << "union" + << Field->getAttr()->getSpelling(); + continue; + } if (ElemTy->isStructureOrClassType()) { Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << Field->getType() << Field->getAttr()->getSpelling(); - continue; + continue; } ArraySize += Inc; PacFieldNames.push_back(Field); @@ -61,7 +66,7 @@ void PacDfiParseStruct(RecordDecl *TagDecl, ASTContext &Ctx, DiagnosticsEngine & if (!ElemTy->isAnyPointerType()) { Diags.Report(Field->getLocation(), diag::warn_unsupported_pac_dfi_type) << Field->getType() << Field->getAttr()->getSpelling(); - continue; + continue; } PacPtrNames.push_back(Field); } -- Gitee