-
Notifications
You must be signed in to change notification settings - Fork 14.5k
StackProtector: Use RuntimeLibcalls to query libcall names #147913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/arsenm/runtime-libcalls/add-openbsd-stack-protector-tests
Are you sure you want to change the base?
Conversation
The compiler should not introduce calls to arbitrary strings that aren't defined in RuntimeLibcalls. Previously OpenBSD was disabling the default __stack_chk_fail, but there was no record of the alternative __stack_smash_handler function it emits instead. This also avoids a random triple check in the pass.
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-nvptx @llvm/pr-subscribers-backend-powerpc Author: Matt Arsenault (arsenm) ChangesThe compiler should not introduce calls to arbitrary strings This also avoids a random triple check in the pass. Full diff: https://github.com/llvm/llvm-project/pull/147913.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index a954dde9fb223..f7598979ca4c5 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -334,6 +334,7 @@ defset list<RuntimeLibcall> LibCalls__OutOfLineAtomic = {
// Stack Protector Fail
def STACKPROTECTOR_CHECK_FAIL : RuntimeLibcall;
+def STACK_SMASH_HANDLER : RuntimeLibcall;
// Deoptimization
def DEOPTIMIZE : RuntimeLibcall;
@@ -918,6 +919,9 @@ def bzero : RuntimeLibcallImpl<BZERO>;
def __bzero : RuntimeLibcallImpl<BZERO>;
def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
+// Used on OpenBSD
+def __stack_smash_handler : RuntimeLibcallImpl<STACK_SMASH_HANDLER>;
+
//===----------------------------------------------------------------------===//
// F128 libm Runtime Libcalls
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 5f866eea7d4e7..3ec70083b7043 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -76,7 +76,7 @@ static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
-static BasicBlock *CreateFailBB(Function *F, const Triple &Trip);
+static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
@@ -673,7 +673,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
// merge pass will merge together all of the various BB into one including
// fail BB generated by the stack protector pseudo instruction.
if (!FailBB)
- FailBB = CreateFailBB(F, TM->getTargetTriple());
+ FailBB = CreateFailBB(F, *TLI);
IRBuilder<> B(CheckLoc);
Value *Guard = getStackGuard(TLI, M, B);
@@ -706,7 +706,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
return HasPrologue;
}
-BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
+BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI) {
auto *M = F->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
@@ -716,17 +716,25 @@ BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
DILocation::get(Context, 0, 0, F->getSubprogram()));
FunctionCallee StackChkFail;
SmallVector<Value *, 1> Args;
- if (Trip.isOSOpenBSD()) {
- StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
- Type::getVoidTy(Context),
+
+ if (const char *ChkFailName =
+ TLI.getLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL)) {
+ StackChkFail =
+ M->getOrInsertFunction(ChkFailName, Type::getVoidTy(Context));
+ } else if (const char *SSHName =
+ TLI.getLibcallName(RTLIB::STACK_SMASH_HANDLER)) {
+ StackChkFail = M->getOrInsertFunction(SSHName, Type::getVoidTy(Context),
PointerType::getUnqual(Context));
Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));
} else {
- StackChkFail =
- M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
+ Context.emitError("no libcall available for stack protector");
}
- cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
- B.CreateCall(StackChkFail, Args);
+
+ if (StackChkFail) {
+ cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
+ B.CreateCall(StackChkFail, Args);
+ }
+
B.CreateUnreachable();
return FailBB;
}
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index fdc183a6b09ce..f9bd9b6029234 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -272,6 +272,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
if (TT.isOSOpenBSD()) {
setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
+ setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler);
}
if (TT.isOSWindows() && !TT.isOSCygMing()) {
diff --git a/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
new file mode 100644
index 0000000000000..f877d95dd3769
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
@@ -0,0 +1,10 @@
+; RUN: not opt -disable-output -mtriple=nvptx64-- -enable-selectiondag-sp=0 -passes=stack-protector %s 2>&1 | FileCheck %s
+
+; CHECK: error: no libcall available for stack protector
+define void @func() sspreq nounwind {
+ %alloca = alloca i32, align 4
+ call void @capture(ptr %alloca)
+ ret void
+}
+
+declare void @capture(ptr)
|
@llvm/pr-subscribers-backend-arm Author: Matt Arsenault (arsenm) ChangesThe compiler should not introduce calls to arbitrary strings This also avoids a random triple check in the pass. Full diff: https://github.com/llvm/llvm-project/pull/147913.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index a954dde9fb223..f7598979ca4c5 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -334,6 +334,7 @@ defset list<RuntimeLibcall> LibCalls__OutOfLineAtomic = {
// Stack Protector Fail
def STACKPROTECTOR_CHECK_FAIL : RuntimeLibcall;
+def STACK_SMASH_HANDLER : RuntimeLibcall;
// Deoptimization
def DEOPTIMIZE : RuntimeLibcall;
@@ -918,6 +919,9 @@ def bzero : RuntimeLibcallImpl<BZERO>;
def __bzero : RuntimeLibcallImpl<BZERO>;
def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
+// Used on OpenBSD
+def __stack_smash_handler : RuntimeLibcallImpl<STACK_SMASH_HANDLER>;
+
//===----------------------------------------------------------------------===//
// F128 libm Runtime Libcalls
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 5f866eea7d4e7..3ec70083b7043 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -76,7 +76,7 @@ static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
-static BasicBlock *CreateFailBB(Function *F, const Triple &Trip);
+static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
@@ -673,7 +673,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
// merge pass will merge together all of the various BB into one including
// fail BB generated by the stack protector pseudo instruction.
if (!FailBB)
- FailBB = CreateFailBB(F, TM->getTargetTriple());
+ FailBB = CreateFailBB(F, *TLI);
IRBuilder<> B(CheckLoc);
Value *Guard = getStackGuard(TLI, M, B);
@@ -706,7 +706,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
return HasPrologue;
}
-BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
+BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI) {
auto *M = F->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
@@ -716,17 +716,25 @@ BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
DILocation::get(Context, 0, 0, F->getSubprogram()));
FunctionCallee StackChkFail;
SmallVector<Value *, 1> Args;
- if (Trip.isOSOpenBSD()) {
- StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
- Type::getVoidTy(Context),
+
+ if (const char *ChkFailName =
+ TLI.getLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL)) {
+ StackChkFail =
+ M->getOrInsertFunction(ChkFailName, Type::getVoidTy(Context));
+ } else if (const char *SSHName =
+ TLI.getLibcallName(RTLIB::STACK_SMASH_HANDLER)) {
+ StackChkFail = M->getOrInsertFunction(SSHName, Type::getVoidTy(Context),
PointerType::getUnqual(Context));
Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));
} else {
- StackChkFail =
- M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
+ Context.emitError("no libcall available for stack protector");
}
- cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
- B.CreateCall(StackChkFail, Args);
+
+ if (StackChkFail) {
+ cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
+ B.CreateCall(StackChkFail, Args);
+ }
+
B.CreateUnreachable();
return FailBB;
}
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index fdc183a6b09ce..f9bd9b6029234 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -272,6 +272,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
if (TT.isOSOpenBSD()) {
setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
+ setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler);
}
if (TT.isOSWindows() && !TT.isOSCygMing()) {
diff --git a/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
new file mode 100644
index 0000000000000..f877d95dd3769
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
@@ -0,0 +1,10 @@
+; RUN: not opt -disable-output -mtriple=nvptx64-- -enable-selectiondag-sp=0 -passes=stack-protector %s 2>&1 | FileCheck %s
+
+; CHECK: error: no libcall available for stack protector
+define void @func() sspreq nounwind {
+ %alloca = alloca i32, align 4
+ call void @capture(ptr %alloca)
+ ret void
+}
+
+declare void @capture(ptr)
|
@llvm/pr-subscribers-backend-x86 Author: Matt Arsenault (arsenm) ChangesThe compiler should not introduce calls to arbitrary strings This also avoids a random triple check in the pass. Full diff: https://github.com/llvm/llvm-project/pull/147913.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index a954dde9fb223..f7598979ca4c5 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -334,6 +334,7 @@ defset list<RuntimeLibcall> LibCalls__OutOfLineAtomic = {
// Stack Protector Fail
def STACKPROTECTOR_CHECK_FAIL : RuntimeLibcall;
+def STACK_SMASH_HANDLER : RuntimeLibcall;
// Deoptimization
def DEOPTIMIZE : RuntimeLibcall;
@@ -918,6 +919,9 @@ def bzero : RuntimeLibcallImpl<BZERO>;
def __bzero : RuntimeLibcallImpl<BZERO>;
def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
+// Used on OpenBSD
+def __stack_smash_handler : RuntimeLibcallImpl<STACK_SMASH_HANDLER>;
+
//===----------------------------------------------------------------------===//
// F128 libm Runtime Libcalls
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 5f866eea7d4e7..3ec70083b7043 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -76,7 +76,7 @@ static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
-static BasicBlock *CreateFailBB(Function *F, const Triple &Trip);
+static BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI);
bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
@@ -673,7 +673,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
// merge pass will merge together all of the various BB into one including
// fail BB generated by the stack protector pseudo instruction.
if (!FailBB)
- FailBB = CreateFailBB(F, TM->getTargetTriple());
+ FailBB = CreateFailBB(F, *TLI);
IRBuilder<> B(CheckLoc);
Value *Guard = getStackGuard(TLI, M, B);
@@ -706,7 +706,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
return HasPrologue;
}
-BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
+BasicBlock *CreateFailBB(Function *F, const TargetLowering &TLI) {
auto *M = F->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
@@ -716,17 +716,25 @@ BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
DILocation::get(Context, 0, 0, F->getSubprogram()));
FunctionCallee StackChkFail;
SmallVector<Value *, 1> Args;
- if (Trip.isOSOpenBSD()) {
- StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
- Type::getVoidTy(Context),
+
+ if (const char *ChkFailName =
+ TLI.getLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL)) {
+ StackChkFail =
+ M->getOrInsertFunction(ChkFailName, Type::getVoidTy(Context));
+ } else if (const char *SSHName =
+ TLI.getLibcallName(RTLIB::STACK_SMASH_HANDLER)) {
+ StackChkFail = M->getOrInsertFunction(SSHName, Type::getVoidTy(Context),
PointerType::getUnqual(Context));
Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));
} else {
- StackChkFail =
- M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
+ Context.emitError("no libcall available for stack protector");
}
- cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
- B.CreateCall(StackChkFail, Args);
+
+ if (StackChkFail) {
+ cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
+ B.CreateCall(StackChkFail, Args);
+ }
+
B.CreateUnreachable();
return FailBB;
}
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index fdc183a6b09ce..f9bd9b6029234 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -272,6 +272,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
if (TT.isOSOpenBSD()) {
setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
+ setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler);
}
if (TT.isOSWindows() && !TT.isOSCygMing()) {
diff --git a/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
new file mode 100644
index 0000000000000..f877d95dd3769
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/no-stack-protector-libcall-error.ll
@@ -0,0 +1,10 @@
+; RUN: not opt -disable-output -mtriple=nvptx64-- -enable-selectiondag-sp=0 -passes=stack-protector %s 2>&1 | FileCheck %s
+
+; CHECK: error: no libcall available for stack protector
+define void @func() sspreq nounwind {
+ %alloca = alloca i32, align 4
+ call void @capture(ptr %alloca)
+ ret void
+}
+
+declare void @capture(ptr)
|
The compiler should not introduce calls to arbitrary strings
that aren't defined in RuntimeLibcalls. Previously OpenBSD was
disabling the default __stack_chk_fail, but there was no record
of the alternative __stack_smash_handler function it emits instead.
This also avoids a random triple check in the pass.