diff options
| author | Vitaly Buka <vitalybuka@google.com> | 2024-09-23 00:26:22 -0700 |
|---|---|---|
| committer | Vitaly Buka <vitalybuka@google.com> | 2024-09-23 00:26:22 -0700 |
| commit | 688132f0892345b7b0a17c25f2b148ae6369a43d (patch) | |
| tree | a253dbddd2e4620e8f301f13b1895153e084b20b | |
| parent | 81c3499531c3fe03827bd8bc890e3a16db9e4c3c (diff) | |
[𝘀𝗽𝗿] changes to main this commit is based onusers/vitalybuka/spr/main.hwasan-replace-hwasan-with-ifunc-and-hwasan-with-tls-options
Created using spr 1.3.4
[skip ci]
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 83dd3e5e8f2c..b82bb353793e 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -64,6 +64,7 @@ #include "llvm/Transforms/Utils/MemoryTaggingSupport.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" +#include <cstdint> #include <optional> #include <random> @@ -83,8 +84,6 @@ const char kHwasanShadowMemoryDynamicAddress[] = static const size_t kNumberOfAccessSizes = 5; static const size_t kDefaultShadowScale = 4; -static const uint64_t kDynamicShadowSentinel = - std::numeric_limits<uint64_t>::max(); static const unsigned kShadowBaseAlignment = 32; @@ -385,25 +384,50 @@ private: std::unique_ptr<RandomNumberGenerator> Rng; /// This struct defines the shadow mapping using the rule: + /// If `kFixed`, then /// shadow = (mem >> Scale) + Offset. - /// If InGlobal is true, then + /// If `kGlobal`, then + /// extern char* __hwasan_shadow_memory_dynamic_address; + /// shadow = (mem >> Scale) + __hwasan_shadow_memory_dynamic_address + /// If `kIfunc`, then /// extern char __hwasan_shadow[]; /// shadow = (mem >> Scale) + &__hwasan_shadow - /// If InTls is true, then + /// If `kTls`, then /// extern char *__hwasan_tls; /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment) /// /// If WithFrameRecord is true, then __hwasan_tls will be used to access the /// ring buffer for storing stack allocations on targets that support it. - struct ShadowMapping { - uint8_t Scale; + class ShadowMapping { + enum class OffsetKind { + kFixed = 0, + kGlobal, + kIfunc, + kTls, + }; + OffsetKind Kind; uint64_t Offset; - bool InGlobal; - bool InTls; + uint8_t Scale; bool WithFrameRecord; + void SetFixed(uint64_t O) { + Kind = OffsetKind::kFixed; + Offset = O; + } + + public: void init(Triple &TargetTriple, bool InstrumentWithCalls); Align getObjectAlignment() const { return Align(1ULL << Scale); } + bool isInGlobal() const { return Kind == OffsetKind::kGlobal; } + bool isInifunc() const { return Kind == OffsetKind::kIfunc; } + bool isInTls() const { return Kind == OffsetKind::kTls; } + bool isFixed() const { return Kind == OffsetKind::kFixed; } + uint8_t scale() const { return Scale; }; + uint64_t offset() const { + assert(isFixed()); + return Offset; + }; + bool withFrameRecord() const { return WithFrameRecord; }; }; ShadowMapping Mapping; @@ -803,13 +827,13 @@ Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) { } Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) { - if (Mapping.Offset != kDynamicShadowSentinel) { + if (Mapping.isFixed()) { return getOpaqueNoopCast( IRB, ConstantExpr::getIntToPtr( - ConstantInt::get(IntptrTy, Mapping.Offset), PtrTy)); + ConstantInt::get(IntptrTy, Mapping.offset()), PtrTy)); } - if (Mapping.InGlobal) + if (Mapping.isInifunc()) return getDynamicShadowIfunc(IRB); Value *GlobalDynamicAddress = @@ -941,8 +965,8 @@ void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) { Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) { // Mem >> Scale - Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale); - if (Mapping.Offset == 0) + Value *Shadow = IRB.CreateLShr(Mem, Mapping.scale()); + if (Mapping.isFixed() && Mapping.offset() == 0) return IRB.CreateIntToPtr(Shadow, PtrTy); // (Mem >> Scale) + Offset return IRB.CreatePtrAdd(ShadowBase, Shadow); @@ -1008,10 +1032,10 @@ void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite, // representable. // In particular, an offset of 4TB (1024 << 32) is representable, and // ought to be good enough for anybody. - if (TargetTriple.isAArch64() && Mapping.Offset != kDynamicShadowSentinel) { - uint16_t OffsetShifted = Mapping.Offset >> 32; + if (TargetTriple.isAArch64() && Mapping.isFixed()) { + uint16_t OffsetShifted = Mapping.offset() >> 32; UseFixedShadowIntrinsic = - static_cast<uint64_t>(OffsetShifted) << 32 == Mapping.Offset; + static_cast<uint64_t>(OffsetShifted) << 32 == Mapping.offset(); } if (UseFixedShadowIntrinsic) { @@ -1021,7 +1045,7 @@ void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite, ? Intrinsic::hwasan_check_memaccess_shortgranules_fixedshadow : Intrinsic::hwasan_check_memaccess_fixedshadow), {Ptr, ConstantInt::get(Int32Ty, AccessInfo), - ConstantInt::get(Int64Ty, Mapping.Offset)}); + ConstantInt::get(Int64Ty, Mapping.offset())}); } else { IRB.CreateCall(Intrinsic::getDeclaration( M, UseShortGranules @@ -1194,7 +1218,7 @@ void HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, {IRB.CreatePointerCast(AI, PtrTy), Tag, ConstantInt::get(IntptrTy, AlignedSize)}); } else { - size_t ShadowSize = Size >> Mapping.Scale; + size_t ShadowSize = Size >> Mapping.scale(); Value *AddrLong = untagPointer(IRB, IRB.CreatePointerCast(AI, IntptrTy)); Value *ShadowPtr = memToShadow(AddrLong, IRB); // If this memset is not inlined, it will be intercepted in the hwasan @@ -1352,7 +1376,7 @@ Value *HWAddressSanitizer::getFrameRecordInfo(IRBuilder<> &IRB) { } void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) { - if (!Mapping.InTls) + if (!Mapping.isInTls()) ShadowBase = getShadowNonTls(IRB); else if (!WithFrameRecord && TargetTriple.isAndroid()) ShadowBase = getDynamicShadowIfunc(IRB); @@ -1677,7 +1701,7 @@ void HWAddressSanitizer::sanitizeFunction(Function &F, IRBuilder<> EntryIRB(&F.getEntryBlock(), InsertPt); emitPrologue(EntryIRB, /*WithFrameRecord*/ ClRecordStackHistory != none && - Mapping.WithFrameRecord && + Mapping.withFrameRecord() && !SInfo.AllocasToInstrument.empty()); if (!SInfo.AllocasToInstrument.empty()) { @@ -1901,38 +1925,27 @@ void HWAddressSanitizer::instrumentPersonalityFunctions() { void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple, bool InstrumentWithCalls) { + // Start with defaults. Scale = kDefaultShadowScale; + Kind = OffsetKind::kTls; + WithFrameRecord = true; + + // Tune for the target. if (TargetTriple.isOSFuchsia()) { // Fuchsia is always PIE, which means that the beginning of the address // space is always available. - InGlobal = false; - InTls = false; - Offset = 0; - WithFrameRecord = true; + SetFixed(0); } else if (ClMappingOffset.getNumOccurrences() > 0) { - InGlobal = false; - InTls = false; - Offset = ClMappingOffset; + SetFixed(ClMappingOffset); WithFrameRecord = false; } else if (ClEnableKhwasan || InstrumentWithCalls) { - InGlobal = false; - InTls = false; - Offset = 0; + SetFixed(0); WithFrameRecord = false; } else if (ClWithIfunc) { - InGlobal = true; - InTls = false; - Offset = kDynamicShadowSentinel; + Kind = OffsetKind::kIfunc; WithFrameRecord = false; - } else if (ClWithTls) { - InGlobal = false; - InTls = true; - Offset = kDynamicShadowSentinel; - WithFrameRecord = true; - } else { - InGlobal = false; - InTls = false; - Offset = kDynamicShadowSentinel; + } else if (!ClWithTls) { + Kind = OffsetKind::kGlobal; WithFrameRecord = false; } } |
