<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hey Eric,</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">vedant</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 13, 2017, at 1:33 PM, Eric Christopher <<a href="mailto:echristo@gmail.com" class="">echristo@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Vedant,<div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">-eric<br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Sep 12, 2017 at 5:05 PM Vedant Kumar via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: vedantk<br class="">
Date: Tue Sep 12 17:04:35 2017<br class="">
New Revision: 313096<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313096&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=313096&view=rev</a><br class="">
Log:<br class="">
[ubsan] Function Sanitizer: Don't require writable text segments<br class="">
<br class="">
This change will make it possible to use -fsanitize=function on Darwin and<br class="">
possibly on other platforms. It fixes an issue with the way RTTI is stored into<br class="">
function prologue data.<br class="">
<br class="">
On Darwin, addresses stored in prologue data can't require run-time fixups and<br class="">
must be PC-relative. Run-time fixups are undesirable because they necessitate<br class="">
writable text segments, which can lead to security issues. And absolute<br class="">
addresses are undesirable because they break PIE mode.<br class="">
<br class="">
The fix is to create a private global which points to the RTTI, and then to<br class="">
encode a PC-relative reference to the global into prologue data.<br class="">
<br class="">
Differential Revision: <a href="https://reviews.llvm.org/D37597" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/D37597</a><br class="">
<br class="">
Modified:<br class="">
    cfe/trunk/lib/CodeGen/CGExpr.cpp<br class="">
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br class="">
    cfe/trunk/lib/CodeGen/CodeGenFunction.h<br class="">
    cfe/trunk/lib/CodeGen/TargetInfo.cpp<br class="">
    cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 12 17:04:35 2017<br class="">
@@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualTyp<br class="">
       SanitizerScope SanScope(this);<br class="">
       llvm::Constant *FTRTTIConst =<br class="">
           CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true);<br class="">
-      llvm::Type *PrefixStructTyElems[] = {<br class="">
-        PrefixSig->getType(),<br class="">
-        FTRTTIConst->getType()<br class="">
-      };<br class="">
+      llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty};<br class="">
       llvm::StructType *PrefixStructTy = llvm::StructType::get(<br class="">
           CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);<br class="">
<br class="">
@@ -4433,8 +4430,10 @@ RValue CodeGenFunction::EmitCall(QualTyp<br class="">
       EmitBlock(TypeCheck);<br class="">
       llvm::Value *CalleeRTTIPtr =<br class="">
           Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1);<br class="">
-      llvm::Value *CalleeRTTI =<br class="">
+      llvm::Value *CalleeRTTIEncoded =<br class="">
           Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign());<br class="">
+      llvm::Value *CalleeRTTI =<br class="">
+          DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded);<br class="">
       llvm::Value *CalleeRTTIMatch =<br class="">
           Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);<br class="">
       llvm::Constant *StaticData[] = {<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Sep 12 17:04:35 2017<br class="">
@@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrume<br class="">
   return CGM.getCodeGenOpts().XRayInstrumentFunctions;<br class="">
 }<br class="">
<br class="">
+llvm::Constant *<br class="">
+CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F,<br class="">
+                                            llvm::Constant *Addr) {<br class="">
+  // Addresses stored in prologue data can't require run-time fixups and must<br class="">
+  // be PC-relative. Run-time fixups are undesirable because they necessitate<br class="">
+  // writable text segments, which are unsafe. And absolute addresses are<br class="">
+  // undesirable because they break PIE mode.<br class="">
+<br class="">
+  // Add a layer of indirection through a private global. Taking its address<br class="">
+  // won't result in a run-time fixup, even if Addr has linkonce_odr linkage.<br class="">
+  auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(),<br class="">
+                                      /*isConstant=*/true,<br class="">
+                                      llvm::GlobalValue::PrivateLinkage, Addr);<br class="">
+<br class="">
+  // Create a PC-relative address.<br class="">
+  auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy);<br class="">
+  auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy);<br class="">
+  auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt);<br class="">
+  return (IntPtrTy == Int32Ty)<br class="">
+             ? PCRelAsInt<br class="">
+             : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty);<br class="">
+}<br class="">
+<br class="">
+llvm::Value *<br class="">
+CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F,<br class="">
+                                          llvm::Value *EncodedAddr) {<br class="">
+  // Reconstruct the address of the global.<br class="">
+  auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy);<br class="">
+  auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "<a href="http://func_addr.int/" rel="noreferrer" target="_blank" class="">func_addr.int</a>");<br class="">
+  auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, "<a href="http://global_addr.int/" rel="noreferrer" target="_blank" class="">global_addr.int</a>");<br class="">
+  auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, "global_addr");<br class="">
+<br class="">
+  // Load the original pointer through the global.<br class="">
+  return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()),<br class="">
+                            "decoded_addr");<br class="">
+}<br class="">
+<br class="">
 /// EmitFunctionInstrumentation - Emit LLVM code to call the specified<br class="">
 /// instrumentation function with the current function and the call site, if<br class="">
 /// function instrumentation is enabled.<br class="">
@@ -856,7 +893,10 @@ void CodeGenFunction::StartFunction(Glob<br class="">
               CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {<br class="">
         llvm::Constant *FTRTTIConst =<br class="">
             CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true);<br class="">
-        llvm::Constant *PrologueStructElems[] = { PrologueSig, FTRTTIConst };<br class="">
+        llvm::Constant *FTRTTIConstEncoded =<br class="">
+            EncodeAddrForUseInPrologue(Fn, FTRTTIConst);<br class="">
+        llvm::Constant *PrologueStructElems[] = {PrologueSig,<br class="">
+                                                 FTRTTIConstEncoded};<br class="">
         llvm::Constant *PrologueStructConst =<br class="">
             llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true);<br class="">
         Fn->setPrologueData(PrologueStructConst);<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 12 17:04:35 2017<br class="">
@@ -1776,6 +1776,15 @@ public:<br class="">
   /// EmitMCountInstrumentation - Emit call to .mcount.<br class="">
   void EmitMCountInstrumentation();<br class="">
<br class="">
+  /// Encode an address into a form suitable for use in a function prologue.<br class="">
+  llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,<br class="">
+                                             llvm::Constant *Addr);<br class="">
+<br class="">
+  /// Decode an address used in a function prologue, encoded by \c<br class="">
+  /// EncodeAddrForUseInPrologue.<br class="">
+  llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F,<br class="">
+                                        llvm::Value *EncodedAddr);<br class="">
+<br class="">
   /// EmitFunctionProlog - Emit the target specific LLVM code to load the<br class="">
   /// arguments for the given function. This is also responsible for naming the<br class="">
   /// LLVM function arguments.<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Sep 12 17:04:35 2017<br class="">
@@ -1086,8 +1086,8 @@ public:<br class="">
   getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {<br class="">
     unsigned Sig = (0xeb << 0) |  // jmp rel8<br class="">
                    (0x06 << 8) |  //           .+0x08<br class="">
-                   ('F' << 16) |<br class="">
-                   ('T' << 24);<br class="">
+                   ('v' << 16) |<br class="">
+                   ('2' << 24);<br class="">
     return llvm::ConstantInt::get(CGM.Int32Ty, Sig);<br class="">
   }<br class="">
<br class="">
@@ -2277,17 +2277,10 @@ public:<br class="">
<br class="">
   llvm::Constant *<br class="">
   getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {<br class="">
-    unsigned Sig;<br class="">
-    if (getABIInfo().has64BitPointers())<br class="">
-      Sig = (0xeb << 0) |  // jmp rel8<br class="">
-            (0x0a << 8) |  //           .+0x0c<br class="">
-            ('F' << 16) |<br class="">
-            ('T' << 24);<br class="">
-    else<br class="">
-      Sig = (0xeb << 0) |  // jmp rel8<br class="">
-            (0x06 << 8) |  //           .+0x08<br class="">
-            ('F' << 16) |<br class="">
-            ('T' << 24);<br class="">
+    unsigned Sig = (0xeb << 0) | // jmp rel8<br class="">
+                   (0x06 << 8) | //           .+0x08<br class="">
+                   ('v' << 16) |<br class="">
+                   ('2' << 24);<br class="">
     return llvm::ConstantInt::get(CGM.Int32Ty, Sig);<br class="">
   }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)<br class="">
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 12 17:04:35 2017<br class="">
@@ -16,6 +16,10 @@ struct S {<br class="">
 // Check that type mismatch handler is not modified by ASan.<br class="">
 // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }<br class="">
<br class="">
+// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)<br class="">
+// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)<br class="">
+// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)<br class="">
+<br class="">
 struct T : S {};<br class="">
<br class="">
 // CHECK-LABEL: @_Z17reference_binding<br class="">
@@ -395,23 +399,30 @@ void downcast_reference(B &b) {<br class="">
   // CHECK-NEXT: br i1 [[AND]]<br class="">
 }<br class="">
<br class="">
-// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }><br class="">
-// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }><br class="">
-// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }><br class="">
+//<br class="">
+// 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) }><br class="">
+// 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)) }><br class="">
+// 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)) }><br class="">
 void indirect_function_call(void (*p)(int)) {<br class="">
-  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*<br class="">
+  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*<br class="">
<br class="">
   // Signature check<br class="">
-  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0<br class="">
+  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0<br class="">
   // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]<br class="">
-  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459<br class="">
+  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819<br class="">
   // CHECK-NEXT: br i1 [[SIGCMP]]<br class="">
<br class="">
   // RTTI pointer check<br class="">
-  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1<br class="">
-  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]]<br class="">
+  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1<br class="">
+  // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]<br class="">
+  // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64<br class="">
+  // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64<br class="">
+  // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]]<br class="">
+  // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8**<br class="">
+  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8<br class="">
   // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)<br class="">
   // CHECK-NEXT: br i1 [[RTTICMP]]<br class="">
+<br class="">
   p(42);<br class="">
 }<br class="">
<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div></div></div>
</div></blockquote></div><br class=""></body></html>