r313096 - [ubsan] Function Sanitizer: Don't require writable text segments
Peter Collingbourne via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 13 18:33:51 PDT 2017
On Fri, Oct 13, 2017 at 6:12 PM, Vedant Kumar <vsk at apple.com> wrote:
>
> On Oct 13, 2017, at 6:05 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
>
>
>
> On Fri, Oct 13, 2017 at 5:59 PM, Vedant Kumar <vsk at apple.com> wrote:
>
>>
>> On Oct 13, 2017, at 4:33 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
>>
>>
>>
>> On Fri, Oct 13, 2017 at 4:19 PM, Vedant Kumar <vsk at apple.com> wrote:
>>
>>>
>>> On Oct 13, 2017, at 4:08 PM, Peter Collingbourne <peter at pcc.me.uk>
>>> wrote:
>>>
>>> On Fri, Oct 13, 2017 at 4:06 PM, Peter Collingbourne <peter at 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)".
>>
>
> Right, my point was that we wouldn't get into such a situation. I'm sorry
> if I was unclear.
>
>
> Oh, in that case were you suggesting that simply storing "(@0 -_ZN1B1fEz)"
> in the prologue for _ZTv0_n24_N1B1fEz would cause the backend error
> ("Cannot represent a difference...")?
>
Yes, exactly. The basic problem is that object format relocations generally
cannot represent the difference between two arbitrary symbols, but they can
represent the difference between a symbol and the current address (i.e. in
this case, the address of the offset in the prologue data), plus a constant
addend (this is known as a PC-relative relocation). So if the RHS of the
subtraction can be resolved to the current address (or an address with an
assembler-constant offset from the current address), the reference can be
represented using a PC-relative relocation (with the offset from the start
of the prologue data being used as the addend). In this case, the
difference between the symbols _ZTv0_n24_N1B1fEz and _ZN1B1fEz is not known
to the assembler if -ffunction-sections is enabled because the symbols are
defined in different sections and the linker is free to put them at any
location relative to each other, so a constant addend cannot be computed
and the assembler errors out.
Peter
Sorry, I haven't fully worked out the root cause of that failure.
>
>
>
>> 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
>>
>> 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, I will take a look.
>
>
> Thanks for the review!
>
> vedant
>
>
> Peter
>
>
>> thanks,
>> vedant
>>
>>
>>
>> Peter
>>
>>
>>> vedant
>>>
>>>
>>> Peter
>>>>
>>>> On Fri, Oct 13, 2017 at 3:06 PM, Vedant Kumar <vsk at apple.com> wrote:
>>>>
>>>>>
>>>>> On Oct 13, 2017, at 2:52 PM, Eric Christopher <echristo at gmail.com>
>>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On Fri, Oct 13, 2017 at 2:50 PM Vedant Kumar <vsk at apple.com> wrote:
>>>>>
>>>>>> On Oct 13, 2017, at 1:44 PM, Eric Christopher <echristo at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 13, 2017 at 1:42 PM Vedant Kumar <vsk at apple.com> wrote:
>>>>>>
>>>>>>> On Oct 13, 2017, at 1:39 PM, Vedant Kumar <vsk at 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
>>>>>>
>>>>>
>>>>> *goes a looking*
>>>>>
>>>>> Thanks!
>>>>>
>>>>> -eric
>>>>>
>>>>>>
>>>>>> vedant
>>>>>>
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> -eric
>>>>>>
>>>>>>
>>>>>>> vedant
>>>>>>>
>>>>>>>
>>>>>>> vedant
>>>>>>>
>>>>>>>
>>>>>>> On Oct 13, 2017, at 1:33 PM, Eric Christopher <echristo at 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 at 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
>>>>>>>> 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
>>>>>>>>
>>>>>>>> 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/CodeG
>>>>>>>> en/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/CodeG
>>>>>>>> en/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");
>>>>>>>> + auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, "
>>>>>>>> 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/CodeG
>>>>>>>> en/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/CodeG
>>>>>>>> en/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/Code
>>>>>>>> GenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=3130
>>>>>>>> 96&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 at lists.llvm.org
>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> --
>>>> Peter
>>>>
>>>
>>>
>>>
>>> --
>>> --
>>> Peter
>>>
>>>
>>>
>>
>>
>> --
>> --
>> Peter
>>
>>
>>
>
>
> --
> --
> Peter
>
>
>
--
--
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171013/7d9e1577/attachment-0001.html>
More information about the cfe-commits
mailing list