diff options
author | Luke Cheeseman <luke.cheeseman@arm.com> | 2018-08-17 12:55:05 +0000 |
---|---|---|
committer | Luke Cheeseman <luke.cheeseman@arm.com> | 2018-08-17 12:55:05 +0000 |
commit | 4359c1a58863640babaf51aad0b511e1b1f82f9d (patch) | |
tree | d997a88b4e0b71b2f5ffd22e5555d93a187a2337 | |
parent | 55ead9f6f66545bcfda4a0f7e6dd3748a296f826 (diff) |
[AArch64] - return address signing
- Add a command line options -msign-return-address to enable return address
signing
- Armv8.3a added instructions to sign the return address to help mitigate
against ROP attacks
- This patch adds command line options to generate function attributes that
signal to the back whether return address signing instructions should be
added
Differential revision: https://reviews.llvm.org/D49793
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340019 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Driver/Options.td | 4 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.def | 1 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 17 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 14 | ||||
-rw-r--r-- | test/CodeGen/aarch64-sign-return-address.c | 14 |
7 files changed, 61 insertions, 0 deletions
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 18781849bf..40d3d21a90 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2030,6 +2030,10 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>, def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group<m_aarch64_Features_Group>, HelpText<"Reserve the x20 register (AArch64 only)">; +def msign_return_address : Joined<["-"], "msign-return-address=">, + Flags<[CC1Option]>, Group<m_Group>, + HelpText<"Select return address signing scope">, Values<"none,all,non-leaf">; + def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>; def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>; def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index a7e71f7ac0..02997d9a16 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -339,6 +339,7 @@ CODEGENOPT(ForceEmitVTables, 1, 0) /// Whether to emit an address-significance table into the object file. CODEGENOPT(Addrsig, 1, 0) +ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None) #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index a6d061acf0..d876344a57 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -108,6 +108,12 @@ public: Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum SignReturnAddressScope { + None, // No signing for any function + NonLeaf, // Sign the return address of functions that spill LR + All // Sign the return address of all functions + }; + /// The code model to use (-mcmodel). std::string CodeModel; diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 6f6c5f50c2..9ad9674ff8 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4969,6 +4969,23 @@ public: } bool doesReturnSlotInterfereWithArgs() const override { return false; } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) + return; + llvm::Function *Fn = cast<llvm::Function>(GV); + + auto Kind = CGM.getCodeGenOpts().getSignReturnAddress(); + if (Kind == CodeGenOptions::SignReturnAddressScope::None) + return; + + Fn->addFnAttr("sign-return-address", + Kind == CodeGenOptions::SignReturnAddressScope::All + ? "all" + : "non-leaf"); + } }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 98ca6b61b2..66b9082b2a 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -1455,6 +1455,11 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, else CmdArgs.push_back("-aarch64-enable-global-merge=true"); } + + if (Arg *A = Args.getLastArg(options::OPT_msign_return_address)) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-msign-return-address=") + A->getValue())); + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index ed22c1a745..c93ff2ae2c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1125,6 +1125,20 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Addrsig = Args.hasArg(OPT_faddrsig); + if (Arg *A = Args.getLastArg(OPT_msign_return_address)) { + StringRef SignScope = A->getValue(); + if (SignScope.equals_lower("none")) + Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None); + else if (SignScope.equals_lower("all")) + Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All); + else if (SignScope.equals_lower("non-leaf")) + Opts.setSignReturnAddress( + CodeGenOptions::SignReturnAddressScope::NonLeaf); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + return Success; } diff --git a/test/CodeGen/aarch64-sign-return-address.c b/test/CodeGen/aarch64-sign-return-address.c new file mode 100644 index 0000000000..d656bc3d0c --- /dev/null +++ b/test/CodeGen/aarch64-sign-return-address.c @@ -0,0 +1,14 @@ +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-PARTIAL +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-ALL + +// CHECK-NONE: @foo() #[[ATTR:[0-9]*]] +// CHECK-NONE-NOT: attributes #[[ATTR]] = { {{.*}} "sign-return-address"={{.*}} }} + +// CHECK-PARTIAL: @foo() #[[ATTR:[0-9]*]] +// CHECK-PARTIAL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="non-leaf" {{.*}}} + +// CHECK-ALL: @foo() #[[ATTR:[0-9]*]] +// CHECK-ALL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="all" {{.*}} } + +void foo() {} |