Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -4388,6 +4388,13 @@ AlignmentSource::Decl); } +/// Get the type of a RTTI descriptor encoded in a function prologue. +static llvm::Type *getPrologueRTTIType(const CodeGenModule &CGM) { + if (CGM.getTriple().isOSDarwin()) + return CGM.Int32Ty; + return CGM.Int8PtrTy; +} + RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Value *Chain) { @@ -4423,7 +4430,8 @@ SanitizerScope SanScope(this); llvm::Constant *FTRTTIConst = CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true); - llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty}; + llvm::Type *FTRTTITy = getPrologueRTTIType(CGM); + llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), FTRTTITy}; llvm::StructType *PrefixStructTy = llvm::StructType::get( CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -440,6 +440,9 @@ llvm::Constant * CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F, llvm::Constant *Addr) { + if (!CGM.getTriple().isOSDarwin()) + return Addr; + // Addresses stored in prologue data can't require run-time fixups and must // be PC-relative. Run-time fixups are undesirable because they necessitate // writable text segments, which are unsafe. And absolute addresses are @@ -463,6 +466,9 @@ llvm::Value * CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F, llvm::Value *EncodedAddr) { + if (!CGM.getTriple().isOSDarwin()) + return EncodedAddr; + // Reconstruct the address of the global. auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy); auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int"); Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1087,7 +1087,7 @@ unsigned Sig = (0xeb << 0) | // jmp rel8 (0x06 << 8) | // .+0x08 ('v' << 16) | - ('2' << 24); + ('3' << 24); return llvm::ConstantInt::get(CGM.Int32Ty, Sig); } @@ -2277,10 +2277,17 @@ llvm::Constant * getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { - unsigned Sig = (0xeb << 0) | // jmp rel8 - (0x06 << 8) | // .+0x08 - ('v' << 16) | - ('2' << 24); + unsigned Sig; + if (!CGM.getTriple().isOSDarwin() && getABIInfo().has64BitPointers()) + Sig = (0xeb << 0) | // jmp rel8 + (0x0a << 8) | // .+0x0c + ('v' << 16) | + ('3' << 24); + else + Sig = (0xeb << 0) | // jmp rel8 + (0x06 << 8) | // .+0x08 + ('v' << 16) | + ('3' << 24); return llvm::ConstantInt::get(CGM.Int32Ty, Sig); } Index: test/CodeGenCXX/catch-undef-behavior.cpp =================================================================== --- test/CodeGenCXX/catch-undef-behavior.cpp +++ test/CodeGenCXX/catch-undef-behavior.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL // RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32 // RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-X86 +// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-apple-darwin | FileCheck %s --check-prefix=DARWIN64 struct S { double d; @@ -16,9 +17,7 @@ // Check that type mismatch handler is not modified by ASan. // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} } -// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) -// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) -// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) +// DARWIN64: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) struct T : S {}; @@ -399,29 +398,42 @@ // CHECK-NEXT: br i1 [[AND]] } -// -// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }> -// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }> -// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }> +// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 863374059, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> +// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 863373035, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> +// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 863373035, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> +// DARWIN64: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 863373035, i32 trunc (i64 sub (i64 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }> void indirect_function_call(void (*p)(int)) { - // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>* + // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>* + // DARWIN64: [[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, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0 // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] - // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819 + // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 863374059 // CHECK-NEXT: br i1 [[SIGCMP]] + // + // DARWIN64-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0 + // DARWIN64-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] + // DARWIN64-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 863373035 + // DARWIN64-NEXT: br i1 [[SIGCMP]] // RTTI pointer check - // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, 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 - // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]] - // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8** - // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8 + // + // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1 + // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]] // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*) // CHECK-NEXT: br i1 [[RTTICMP]] + // + // DARWIN64: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1 + // DARWIN64-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]] + // DARWIN64-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64 + // DARWIN64-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64 + // DARWIN64-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]] + // DARWIN64-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8** + // DARWIN64-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8 + // DARWIN64-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*) + // DARWIN64-NEXT: br i1 [[RTTICMP]] p(42); }