aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Cheeseman <luke.cheeseman@arm.com>2018-08-17 12:55:05 +0000
committerLuke Cheeseman <luke.cheeseman@arm.com>2018-08-17 12:55:05 +0000
commit4359c1a58863640babaf51aad0b511e1b1f82f9d (patch)
treed997a88b4e0b71b2f5ffd22e5555d93a187a2337
parent55ead9f6f66545bcfda4a0f7e6dd3748a296f826 (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.td4
-rw-r--r--include/clang/Frontend/CodeGenOptions.def1
-rw-r--r--include/clang/Frontend/CodeGenOptions.h6
-rw-r--r--lib/CodeGen/TargetInfo.cpp17
-rw-r--r--lib/Driver/ToolChains/Clang.cpp5
-rw-r--r--lib/Frontend/CompilerInvocation.cpp14
-rw-r--r--test/CodeGen/aarch64-sign-return-address.c14
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() {}