This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
MaskRay marked an inline comment as done.
Closed by commit rGad31a2dcadfc: Change -fsanitize=function to place two words
before the function entry (authored by MaskRay).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148665/new/
https://reviews.llvm.org/D148665
Files:
clang/lib/CodeGen/CGExpr.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/CodeGen/TargetInfo.h
clang/test/CodeGen/ubsan-function.cpp
clang/test/CodeGenCXX/catch-undef-behavior.cpp
clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/test/CodeGen/X86/func-sanitizer.ll
llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll
Index: llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll
===================================================================
--- llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll
+++ llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll
@@ -1,6 +1,9 @@
; RUN: llc -mtriple=i686 %s -o - | FileCheck --check-prefixes=CHECK,32 %s
; RUN: llc -mtriple=x86_64 %s -o - | FileCheck --check-prefixes=CHECK,64 %s
+@_ZTIFvvE = linkonce_odr constant i32 1
+@__llvm_rtti_proxy = private unnamed_addr constant ptr @_ZTIFvvE
+
;; -fpatchable-function-entry=0 -fcf-protection=branch
define void @f0() "patchable-function-entry"="0" {
; CHECK-LABEL: f0:
@@ -83,6 +86,25 @@
ret void
}
+;; Test the interaction with -fsanitize=function.
+; CHECK: .type sanitize_function,@function
+; CHECK-NEXT: .Ltmp{{.*}}:
+; CHECK-NEXT: nop
+; CHECK-NEXT: .long 3238382334
+; CHECK-NEXT: .long .L__llvm_rtti_proxy-sanitize_function
+; CHECK-NEXT: sanitize_function:
+; CHECK-NEXT: .Lfunc_begin{{.*}}:
+; CHECK-NEXT: .cfi_startproc
+; CHECK-NEXT: # %bb.0:
+; 32-NEXT: endbr32
+; 64-NEXT: endbr64
+; CHECK-NEXT: nop
+; CHECK-NEXT: ret
+define void @sanitize_function(ptr noundef %x) "patchable-function-prefix"="1" "patchable-function-entry"="1" !func_sanitize !1 {
+ ret void
+}
+
!llvm.module.flags = !{!0}
!0 = !{i32 8, !"cf-protection-branch", i32 1}
+!1 = !{i32 3238382334, ptr @__llvm_rtti_proxy}
Index: llvm/test/CodeGen/X86/func-sanitizer.ll
===================================================================
--- llvm/test/CodeGen/X86/func-sanitizer.ll
+++ llvm/test/CodeGen/X86/func-sanitizer.ll
@@ -1,12 +1,12 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
-; CHECK: _Z3funv:
-; CHECK: .cfi_startproc
-; CHECK: .long 846595819
-; CHECK: .long .L__llvm_rtti_proxy-_Z3funv
-; CHECK: .L__llvm_rtti_proxy:
-; CHECK: .quad i
-; CHECK: .size .L__llvm_rtti_proxy, 8
+; CHECK: .type _Z3funv,@function
+; CHECK-NEXT: .long 3238382334 # 0xc105cafe
+; CHECK-NEXT: .long .L__llvm_rtti_proxy-_Z3funv
+; CHECK-NEXT: _Z3funv:
+; CHECK-NEXT: .cfi_startproc
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: retq
@i = linkonce_odr constant i32 1
@__llvm_rtti_proxy = private unnamed_addr constant ptr @i
@@ -15,4 +15,4 @@
ret void
}
-!0 = !{i32 846595819, ptr @__llvm_rtti_proxy}
+!0 = !{i32 3238382334, ptr @__llvm_rtti_proxy}
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -971,6 +971,21 @@
CurrentPatchableFunctionEntrySym = CurrentFnBegin;
}
+ // Emit the function prologue data for the indirect call sanitizer.
+ if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {
+ assert(MD->getNumOperands() == 2);
+
+ auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
+ auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1));
+ emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
+
+ const MCExpr *Proxy = lowerConstant(FTRTTIProxy);
+ const MCExpr *FnExp = MCSymbolRefExpr::create(CurrentFnSym, OutContext);
+ const MCExpr *PCRel = MCBinaryExpr::createSub(Proxy, FnExp, OutContext);
+ // Use 32 bit since only small code model is supported.
+ OutStreamer->emitValue(PCRel, 4u);
+ }
+
if (isVerbose()) {
F.printAsOperand(OutStreamer->getCommentOS(),
/*PrintType=*/false, F.getParent());
@@ -1025,24 +1040,6 @@
// Emit the prologue data.
if (F.hasPrologueData())
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
-
- // Emit the function prologue data for the indirect call sanitizer.
- if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {
- assert(TM.getTargetTriple().getArch() == Triple::x86 ||
- TM.getTargetTriple().getArch() == Triple::x86_64);
- assert(MD->getNumOperands() == 2);
-
- auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
- auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1));
- assert(PrologueSig && FTRTTIProxy);
- emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
-
- const MCExpr *Proxy = lowerConstant(FTRTTIProxy);
- const MCExpr *FnExp = MCSymbolRefExpr::create(CurrentFnSym, OutContext);
- const MCExpr *PCRel = MCBinaryExpr::createSub(Proxy, FnExp, OutContext);
- // Use 32 bit since only small code model is supported.
- OutStreamer->emitValue(PCRel, 4u);
- }
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===================================================================
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -61,7 +61,7 @@
void make_invalid_call() {
// CHECK: function.cpp:[[@LINE+4]]:3: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)'
- // CHECK-NEXT: function.cpp:[[@LINE-11]]: note: f() defined here
+ // CHECK-NEXT: function.cpp:[[@LINE-11]]:{{(11:)?}} note: f() defined here
// NOSYM: function.cpp:[[@LINE+2]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
// NOSYM-NEXT: ({{.*}}+0x{{.*}}): note: (unknown) defined here
reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42);
Index: clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
===================================================================
--- clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
+++ clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
@@ -14,4 +14,4 @@
p();
}
-// CHECK: ![[FUNCSAN]] = !{i32 846595819, ptr [[PROXY]]}
+// CHECK: ![[FUNCSAN]] = !{i32 -1056584962, ptr [[PROXY]]}
Index: clang/test/CodeGenCXX/catch-undef-behavior.cpp
===================================================================
--- clang/test/CodeGenCXX/catch-undef-behavior.cpp
+++ clang/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -402,13 +402,13 @@
// CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
// Signature check
- // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0
+ // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 -1, i32 0
// CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
- // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
+ // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], -1056584962
// CHECK-NEXT: br i1 [[SIGCMP]]
// RTTI pointer check
- // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1
+ // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 -1, i32 1
// CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
// CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64
// CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64
@@ -750,4 +750,4 @@
// CHECK: attributes [[NR_NUW]] = { noreturn nounwind }
-// CHECK-FUNCSAN: ![[FUNCSAN]] = !{i32 846595819, i8** [[PROXY]]}
+// CHECK-FUNCSAN: ![[FUNCSAN]] = !{i32 -1056584962, i8** [[PROXY]]}
Index: clang/test/CodeGen/ubsan-function.cpp
===================================================================
--- clang/test/CodeGen/ubsan-function.cpp
+++ clang/test/CodeGen/ubsan-function.cpp
@@ -5,12 +5,12 @@
void fun() {}
// CHECK-LABEL: define{{.*}} void @_Z6callerPFvvE(ptr noundef %f)
-// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 0, i32 0, !nosanitize
+// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
// CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
-// CHECK: icmp eq i32 {{.*}}, 846595819, !nosanitize
+// CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize
// CHECK: br i1 {{.*}}, label %[[LABEL1:.*]], label %[[LABEL4:.*]], !nosanitize
// CHECK: [[LABEL1]]:
-// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 0, i32 1, !nosanitize
+// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 1, !nosanitize
// CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
// CHECK: icmp eq ptr {{.*}}, @_ZTIFvvE, !nosanitize
// CHECK: br i1 {{.*}}, label %[[LABEL3:.*]], label %[[LABEL2:[^,]*]], {{.*}}!nosanitize
@@ -22,4 +22,4 @@
// CHECK: br label %[[LABEL4]], !nosanitize
void caller(void (*f)()) { f(); }
-// CHECK: ![[FUNCSAN]] = !{i32 846595819, ptr @[[PROXY]]}
+// CHECK: ![[FUNCSAN]] = !{i32 -1056584962, ptr @[[PROXY]]}
Index: clang/lib/CodeGen/TargetInfo.h
===================================================================
--- clang/lib/CodeGen/TargetInfo.h
+++ clang/lib/CodeGen/TargetInfo.h
@@ -199,9 +199,10 @@
/// Return a constant used by UBSan as a signature to identify functions
/// possessing type information, or 0 if the platform is unsupported.
+ /// This magic number is invalid instruction encoding in many targets.
virtual llvm::Constant *
getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const {
- return nullptr;
+ return llvm::ConstantInt::get(CGM.Int32Ty, 0xc105cafe);
}
/// Determine whether a call to an unprototyped functions under
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -1293,15 +1293,6 @@
std::string &AsmString,
unsigned NumOutputs) const override;
- llvm::Constant *
- getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
- unsigned Sig = (0xeb << 0) | // jmp rel8
- (0x06 << 8) | // .+0x08
- ('v' << 16) |
- ('2' << 24);
- return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
- }
-
StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
return "movl\t%ebp, %ebp"
"\t\t// marker for objc_retainAutoreleaseReturnValue";
@@ -2539,15 +2530,6 @@
return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType);
}
- llvm::Constant *
- getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
- unsigned Sig = (0xeb << 0) | // jmp rel8
- (0x06 << 8) | // .+0x08
- ('v' << 16) |
- ('2' << 24);
- return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
- }
-
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const override {
if (GV->isDeclaration())
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -5368,7 +5368,7 @@
llvm::Value *CalleePrefixStruct = Builder.CreateBitCast(
CalleePtr, llvm::PointerType::getUnqual(PrefixStructTy));
llvm::Value *CalleeSigPtr =
- Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 0);
+ Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
llvm::Value *CalleeSig =
Builder.CreateAlignedLoad(PrefixSigType, CalleeSigPtr, getIntAlign());
llvm::Value *CalleeSigMatch = Builder.CreateICmpEQ(CalleeSig, PrefixSig);
@@ -5379,7 +5379,7 @@
EmitBlock(TypeCheck);
llvm::Value *CalleeRTTIPtr =
- Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1);
+ Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1);
llvm::Value *CalleeRTTIEncoded =
Builder.CreateAlignedLoad(Int32Ty, CalleeRTTIPtr, getPointerAlign());
llvm::Value *CalleeRTTI =
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits