> On Oct 13, 2017, at 4:33 PM, Peter Collingbourne <pe...@pcc.me.uk> wrote: > > > > On Fri, Oct 13, 2017 at 4:19 PM, Vedant Kumar <v...@apple.com > <mailto:v...@apple.com>> wrote: > >> On Oct 13, 2017, at 4:08 PM, Peter Collingbourne <pe...@pcc.me.uk >> <mailto:pe...@pcc.me.uk>> wrote: >> >> On Fri, Oct 13, 2017 at 4:06 PM, Peter Collingbourne <pe...@pcc.me.uk >> <mailto:pe...@pcc.me.uk>> wrote: >> Here's a small reproducer. >> >> struct A { >> virtual void f(...); >> }; >> >> struct B : virtual A { >> virtual void b(); >> virtual void f(...); >> }; >> >> void B::f(...) {} >> >> $ clang++ -fsanitize=function fsan.cpp -ffunction-sections -fdata-sections >> -c -o /dev/null >> fatal error: error in backend: Cannot represent a difference across sections >> >> Looking at the IR I see this function definition: >> define void @_ZTv0_n24_N1B1fEz(%struct.B* %this, ...) unnamed_addr #0 align >> 2 prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint >> (i8** @0 to i64), i64 ptrtoint (void (%struct.B*, ...)* @_ZN1B1fEz to i64)) >> to i32) }> { >> which appears to cause the error. >> >> I get basically the same IR if I use a Darwin target triple, so this isn't a >> Linux-specific issue. (On Darwin we end up successfully creating an object >> file, but the embedded offset in the text section will presumably be >> incorrect.) >> >> Note that we're emitting prologue data on virtual functions, which is >> unnecessary because -fsanitize=function only checks indirect calls via >> function pointers. So I imagine that one way to solve the problem would be >> to turn off prologue data emission on non-virtual functions. >> >> Sorry, I meant "limit prologue data emission to non-virtual functions". > > That's independently a great idea :). > > I don't see a problem in the IR you've showed above, however. Why do you > expect the embedded offset to be incorrect? This program links and runs fine > on Darwin: > > --- > struct A { > virtual void f(...) {} > }; > > struct B : virtual A { > virtual void b() {} > virtual void f(...); > }; > > void B::f(...) {} > > int main() { > A a; > a.f(); > > B b; > b.f(); > b.b(); > return 0; > } > --- > > The "Cannot represent difference..." error appears limited to ELF and Wasm, > afaik. > > In order to find the RTTI data for a function, the generated code will add > the embedded offset to the function's address in order to find the global > that contains the pointer to the RTTI data. So if we were to compute the > address of _ZTv0_n24_N1B1fEz's global, we would compute the value: > _ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz) > which, of course, will not yield the address of @0. > > I would certainly expect your program to run correctly because we do not try > to interpret the prologue data when calling a virtual function, so the > incorrectness of the offset has no effect on the program's execution.
Thanks for explaining. I am still confused on one point. Calling a function pointer to a virtual member doesn't seem to trigger a UBSan type check. I can see why "_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)" doesn't make sense, but I don't know how we'd ever get there. Consider: --- class A { public: virtual int f() = 0; }; class B : public A { int f() { return 42; } }; struct C { void g() {} static void h() {} }; int main() { auto h = &C::h; h(); // type checked C c; void (C::*g)() = &C::g; (c.*g)(); // not checked int (A::*f)() = &A::f; A *a = new B; return (a->*f)(); // not checked } --- So, I'm not sure how we would get into a situation where we compute "_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)". In the last code example I posted, there are also no calls to the function type check handler. At any rate, I implemented your idea to not emit signatures for virtual methods: https://reviews.llvm.org/D38913 <https://reviews.llvm.org/D38913> It's at least good for a code size savings, and it might fix the issue Eric and Han are seeing. I'd appreciate any feedback. thanks, vedant > > Peter > > > vedant > >> >> Peter >> >> On Fri, Oct 13, 2017 at 3:06 PM, Vedant Kumar <v...@apple.com >> <mailto:v...@apple.com>> wrote: >> >>> On Oct 13, 2017, at 2:52 PM, Eric Christopher <echri...@gmail.com >>> <mailto:echri...@gmail.com>> wrote: >>> >>> >>> >>> On Fri, Oct 13, 2017 at 2:50 PM Vedant Kumar <v...@apple.com >>> <mailto:v...@apple.com>> wrote: >>>> On Oct 13, 2017, at 1:44 PM, Eric Christopher <echri...@gmail.com >>>> <mailto:echri...@gmail.com>> wrote: >>>> >>>> >>>> >>>> On Fri, Oct 13, 2017 at 1:42 PM Vedant Kumar <v...@apple.com >>>> <mailto:v...@apple.com>> wrote: >>>>> On Oct 13, 2017, at 1:39 PM, Vedant Kumar <v...@apple.com >>>>> <mailto:v...@apple.com>> wrote: >>>>> >>>>> Hey Eric, >>>>> >>>>> I'm sorry for the breakage. I made sure to check the run-time tests in >>>>> compiler-rt but we could have missing coverage there. >>>>> >>>>> The original version of this patch restricted the prologue data changes >>>>> to Darwin only. We can switch back to that easily, just let me know. >>>> >>>> Actually I'll go ahead and work a patch up. >>>> >>>> >>>> Appreciated :) >>>> >>>> Basically we were getting an error of: >>>> >>>> error: Cannot represent a difference across sections >>>> >>>> trying to compile things with the current code. >>> >>> Oh I see.. well, we started using a difference between the address of a >>> function and the address of a global, so the error makes sense. >>> >>> I'd be interested in any factors that could narrow the problem down (e.g >>> using a specific linker, using -ffunction-sections, using data-sections, >>> etc). Basically I'm not sure why this would work on some Linux setups but >>> not others. >>> >>> >>> Definitely using the latter two options and gold as a linker. I'll see what >>> Han can come up with. >> >> Gotcha. Well, -ffunction-sections appears to be untested in >> compiler-rt/test/ubsan, at least. >> >> There's a test somewhere in there called function.cpp -- it would be great >> if we could cover the *-sections options there. I'm not sure whether that's >> what caused the failure, but the extra coverage couldn't hurt :). I would do >> it myself but I don't have a Linux machine to test on. >> >> vedant >> >>> >>> While we figure that out here's a patch to limit the impact on non-Darwin >>> platforms: >>> https://reviews.llvm.org/D38903 <https://reviews.llvm.org/D38903> >>> >>> *goes a looking* >>> >>> Thanks! >>> >>> -eric >>> >>> vedant >>> >>>> >>>> Thanks! >>>> >>>> -eric >>>> >>>> vedant >>>> >>>>> >>>>> vedant >>>>> >>>>> >>>>>> On Oct 13, 2017, at 1:33 PM, Eric Christopher <echri...@gmail.com >>>>>> <mailto:echri...@gmail.com>> wrote: >>>>>> >>>>>> Hi Vedant, >>>>>> >>>>>> So this actually broke -fsanitize=function on linux. Han is working up a >>>>>> testcase for it, but letting you know for now that we'll probably need >>>>>> some change here. >>>>>> >>>>>> -eric >>>>>> >>>>>> On Tue, Sep 12, 2017 at 5:05 PM Vedant Kumar via cfe-commits >>>>>> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote: >>>>>> Author: vedantk >>>>>> Date: Tue Sep 12 17:04:35 2017 >>>>>> New Revision: 313096 >>>>>> >>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=313096&view=rev >>>>>> <http://llvm.org/viewvc/llvm-project?rev=313096&view=rev> >>>>>> Log: >>>>>> [ubsan] Function Sanitizer: Don't require writable text segments >>>>>> >>>>>> This change will make it possible to use -fsanitize=function on Darwin >>>>>> and >>>>>> possibly on other platforms. It fixes an issue with the way RTTI is >>>>>> stored into >>>>>> function prologue data. >>>>>> >>>>>> On Darwin, 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 can lead to security issues. And absolute >>>>>> addresses are undesirable because they break PIE mode. >>>>>> >>>>>> The fix is to create a private global which points to the RTTI, and then >>>>>> to >>>>>> encode a PC-relative reference to the global into prologue data. >>>>>> >>>>>> Differential Revision: https://reviews.llvm.org/D37597 >>>>>> <https://reviews.llvm.org/D37597> >>>>>> >>>>>> Modified: >>>>>> cfe/trunk/lib/CodeGen/CGExpr.cpp >>>>>> cfe/trunk/lib/CodeGen/CodeGenFunction.cpp >>>>>> cfe/trunk/lib/CodeGen/CodeGenFunction.h >>>>>> cfe/trunk/lib/CodeGen/TargetInfo.cpp >>>>>> cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp >>>>>> >>>>>> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp >>>>>> URL: >>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>> >>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>> ============================================================================== >>>>>> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) >>>>>> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 12 17:04:35 2017 >>>>>> @@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualTyp >>>>>> SanitizerScope SanScope(this); >>>>>> llvm::Constant *FTRTTIConst = >>>>>> CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), >>>>>> /*ForEH=*/true); >>>>>> - llvm::Type *PrefixStructTyElems[] = { >>>>>> - PrefixSig->getType(), >>>>>> - FTRTTIConst->getType() >>>>>> - }; >>>>>> + llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), >>>>>> Int32Ty}; >>>>>> llvm::StructType *PrefixStructTy = llvm::StructType::get( >>>>>> CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); >>>>>> >>>>>> @@ -4433,8 +4430,10 @@ RValue CodeGenFunction::EmitCall(QualTyp >>>>>> EmitBlock(TypeCheck); >>>>>> llvm::Value *CalleeRTTIPtr = >>>>>> Builder.CreateConstGEP2_32(PrefixStructTy, >>>>>> CalleePrefixStruct, 0, 1); >>>>>> - llvm::Value *CalleeRTTI = >>>>>> + llvm::Value *CalleeRTTIEncoded = >>>>>> Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign()); >>>>>> + llvm::Value *CalleeRTTI = >>>>>> + DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded); >>>>>> llvm::Value *CalleeRTTIMatch = >>>>>> Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst); >>>>>> llvm::Constant *StaticData[] = { >>>>>> >>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp >>>>>> URL: >>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>> >>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>> ============================================================================== >>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) >>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Sep 12 17:04:35 2017 >>>>>> @@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrume >>>>>> return CGM.getCodeGenOpts().XRayInstrumentFunctions; >>>>>> } >>>>>> >>>>>> +llvm::Constant * >>>>>> +CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F, >>>>>> + llvm::Constant *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 >>>>>> + // undesirable because they break PIE mode. >>>>>> + >>>>>> + // Add a layer of indirection through a private global. Taking its >>>>>> address >>>>>> + // won't result in a run-time fixup, even if Addr has linkonce_odr >>>>>> linkage. >>>>>> + auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(), >>>>>> + /*isConstant=*/true, >>>>>> + >>>>>> llvm::GlobalValue::PrivateLinkage, Addr); >>>>>> + >>>>>> + // Create a PC-relative address. >>>>>> + auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy); >>>>>> + auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy); >>>>>> + auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt); >>>>>> + return (IntPtrTy == Int32Ty) >>>>>> + ? PCRelAsInt >>>>>> + : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty); >>>>>> +} >>>>>> + >>>>>> +llvm::Value * >>>>>> +CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F, >>>>>> + llvm::Value *EncodedAddr) { >>>>>> + // Reconstruct the address of the global. >>>>>> + auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy); >>>>>> + auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int >>>>>> <http://func_addr.int/>"); >>>>>> + auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, >>>>>> "global_addr.int <http://global_addr.int/>"); >>>>>> + auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, >>>>>> "global_addr"); >>>>>> + >>>>>> + // Load the original pointer through the global. >>>>>> + return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()), >>>>>> + "decoded_addr"); >>>>>> +} >>>>>> + >>>>>> /// EmitFunctionInstrumentation - Emit LLVM code to call the specified >>>>>> /// instrumentation function with the current function and the call >>>>>> site, if >>>>>> /// function instrumentation is enabled. >>>>>> @@ -856,7 +893,10 @@ void CodeGenFunction::StartFunction(Glob >>>>>> >>>>>> CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { >>>>>> llvm::Constant *FTRTTIConst = >>>>>> CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); >>>>>> - llvm::Constant *PrologueStructElems[] = { PrologueSig, >>>>>> FTRTTIConst }; >>>>>> + llvm::Constant *FTRTTIConstEncoded = >>>>>> + EncodeAddrForUseInPrologue(Fn, FTRTTIConst); >>>>>> + llvm::Constant *PrologueStructElems[] = {PrologueSig, >>>>>> + FTRTTIConstEncoded}; >>>>>> llvm::Constant *PrologueStructConst = >>>>>> llvm::ConstantStruct::getAnon(PrologueStructElems, >>>>>> /*Packed=*/true); >>>>>> Fn->setPrologueData(PrologueStructConst); >>>>>> >>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h >>>>>> URL: >>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff >>>>>> >>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff> >>>>>> ============================================================================== >>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) >>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 12 17:04:35 2017 >>>>>> @@ -1776,6 +1776,15 @@ public: >>>>>> /// EmitMCountInstrumentation - Emit call to .mcount. >>>>>> void EmitMCountInstrumentation(); >>>>>> >>>>>> + /// Encode an address into a form suitable for use in a function >>>>>> prologue. >>>>>> + llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F, >>>>>> + llvm::Constant *Addr); >>>>>> + >>>>>> + /// Decode an address used in a function prologue, encoded by \c >>>>>> + /// EncodeAddrForUseInPrologue. >>>>>> + llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F, >>>>>> + llvm::Value *EncodedAddr); >>>>>> + >>>>>> /// EmitFunctionProlog - Emit the target specific LLVM code to load >>>>>> the >>>>>> /// arguments for the given function. This is also responsible for >>>>>> naming the >>>>>> /// LLVM function arguments. >>>>>> >>>>>> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp >>>>>> URL: >>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>> >>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>> ============================================================================== >>>>>> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) >>>>>> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Sep 12 17:04:35 2017 >>>>>> @@ -1086,8 +1086,8 @@ public: >>>>>> getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override >>>>>> { >>>>>> unsigned Sig = (0xeb << 0) | // jmp rel8 >>>>>> (0x06 << 8) | // .+0x08 >>>>>> - ('F' << 16) | >>>>>> - ('T' << 24); >>>>>> + ('v' << 16) | >>>>>> + ('2' << 24); >>>>>> return llvm::ConstantInt::get(CGM.Int32Ty, Sig); >>>>>> } >>>>>> >>>>>> @@ -2277,17 +2277,10 @@ public: >>>>>> >>>>>> llvm::Constant * >>>>>> getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override >>>>>> { >>>>>> - unsigned Sig; >>>>>> - if (getABIInfo().has64BitPointers()) >>>>>> - Sig = (0xeb << 0) | // jmp rel8 >>>>>> - (0x0a << 8) | // .+0x0c >>>>>> - ('F' << 16) | >>>>>> - ('T' << 24); >>>>>> - else >>>>>> - Sig = (0xeb << 0) | // jmp rel8 >>>>>> - (0x06 << 8) | // .+0x08 >>>>>> - ('F' << 16) | >>>>>> - ('T' << 24); >>>>>> + unsigned Sig = (0xeb << 0) | // jmp rel8 >>>>>> + (0x06 << 8) | // .+0x08 >>>>>> + ('v' << 16) | >>>>>> + ('2' << 24); >>>>>> return llvm::ConstantInt::get(CGM.Int32Ty, Sig); >>>>>> } >>>>>> >>>>>> >>>>>> Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp >>>>>> URL: >>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff >>>>>> >>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff> >>>>>> ============================================================================== >>>>>> --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original) >>>>>> +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 12 >>>>>> 17:04:35 2017 >>>>>> @@ -16,6 +16,10 @@ struct S { >>>>>> // 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*) >>>>>> + >>>>>> struct T : S {}; >>>>>> >>>>>> // CHECK-LABEL: @_Z17reference_binding >>>>>> @@ -395,23 +399,30 @@ void downcast_reference(B &b) { >>>>>> // CHECK-NEXT: br i1 [[AND]] >>>>>> } >>>>>> >>>>>> -// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ >>>>>> i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE >>>>>> to i8*) }> >>>>>> -// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to >>>>>> i8*) }> >>>>>> -// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, >>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to >>>>>> i8*) }> >>>>>> +// >>>>>> +// 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)) }> >>>>>> void indirect_function_call(void (*p)(int)) { >>>>>> - // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>* >>>>>> + // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>* >>>>>> >>>>>> // Signature check >>>>>> - // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, >>>>>> i8* }>* [[PTR]], i32 0, i32 0 >>>>>> + // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, >>>>>> i32 }>* [[PTR]], i32 0, i32 0 >>>>>> // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] >>>>>> - // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459 >>>>>> + // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819 >>>>>> // CHECK-NEXT: br i1 [[SIGCMP]] >>>>>> >>>>>> // RTTI pointer check >>>>>> - // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* >>>>>> }>* [[PTR]], i32 0, i32 1 >>>>>> - // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]] >>>>>> + // 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-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ >>>>>> i8*, i8* }* @_ZTIFviE to i8*) >>>>>> // CHECK-NEXT: br i1 [[RTTICMP]] >>>>>> + >>>>>> p(42); >>>>>> } >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> cfe-commits mailing list >>>>>> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> >>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits> >> >> >> >> -- >> -- >> Peter >> >> >> >> -- >> -- >> Peter > > > > > -- > -- > Peter
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits