diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -313,6 +313,9 @@ void instrumentGlobal(GlobalVariable *GV, uint8_t Tag); void instrumentGlobals(); + Value *getPC(IRBuilder<> &IRB); + Value *getSP(IRBuilder<> &IRB); + void instrumentPersonalityFunctions(); private: @@ -382,6 +385,7 @@ Value *ShadowBase = nullptr; Value *StackBaseTag = nullptr; + Value *CachedSP = nullptr; GlobalValue *ThreadPtrGlobal = nullptr; }; @@ -1031,19 +1035,10 @@ return getNextTagWithCall(IRB); if (StackBaseTag) return StackBaseTag; - // FIXME: use addressofreturnaddress (but implement it in aarch64 backend - // first). - Module *M = IRB.GetInsertBlock()->getParent()->getParent(); - auto GetStackPointerFn = Intrinsic::getDeclaration( - M, Intrinsic::frameaddress, - IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace())); - Value *StackPointer = IRB.CreateCall( - GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())}); - // Extract some entropy from the stack pointer for the tags. // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ // between functions). - Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy); + Value *StackPointerLong = getSP(IRB); Value *StackTag = applyTagMask(IRB, IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20))); @@ -1123,6 +1118,34 @@ return nullptr; } +Value *HWAddressSanitizer::getPC(IRBuilder<> &IRB) { + Value *PC; + if (TargetTriple.getArch() == Triple::aarch64) { + PC = readRegister(IRB, "pc"); + } else { + Function *F = IRB.GetInsertBlock()->getParent(); + PC = IRB.CreatePtrToInt(F, IntptrTy); + } + return PC; +} + +Value *HWAddressSanitizer::getSP(IRBuilder<> &IRB) { + if (!CachedSP) { + // FIXME: use addressofreturnaddress (but implement it in aarch64 backend + // first). + Function *F = IRB.GetInsertBlock()->getParent(); + Module *M = F->getParent(); + auto GetStackPointerFn = Intrinsic::getDeclaration( + M, Intrinsic::frameaddress, + IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace())); + CachedSP = IRB.CreatePtrToInt( + IRB.CreateCall(GetStackPointerFn, + {Constant::getNullValue(IRB.getInt32Ty())}), + IntptrTy); + } + return CachedSP; +} + void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { if (!Mapping.InTls) ShadowBase = getShadowNonTls(IRB); @@ -1141,23 +1164,12 @@ TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong); if (WithFrameRecord) { - Function *F = IRB.GetInsertBlock()->getParent(); StackBaseTag = IRB.CreateAShr(ThreadLong, 3); // Prepare ring buffer data. - Value *PC; - if (TargetTriple.getArch() == Triple::aarch64) - PC = readRegister(IRB, "pc"); - else - PC = IRB.CreatePtrToInt(F, IntptrTy); - Module *M = F->getParent(); - auto GetStackPointerFn = Intrinsic::getDeclaration( - M, Intrinsic::frameaddress, - IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace())); - Value *SP = IRB.CreatePtrToInt( - IRB.CreateCall(GetStackPointerFn, - {Constant::getNullValue(IRB.getInt32Ty())}), - IntptrTy); + Value *PC = getPC(IRB); + Value *SP = getSP(IRB); + // Mix SP and PC. // Assumptions: // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero) @@ -1444,6 +1456,7 @@ ShadowBase = nullptr; StackBaseTag = nullptr; + CachedSP = nullptr; return true; }