diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 42 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 19 |
4 files changed, 60 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 2b0086d22a7..193e4f122af 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee 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(QualType CalleeType, const CGCallee &OrigCallee 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[] = { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index a9a1a53be20..1c9fc367940 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const { 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(GlobalDecl GD, 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); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index a3b9beb2988..33bf74b5d39 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -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. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 10fa2ea322c..934e155ccdf 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -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); } |