summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2024-09-23 00:26:22 -0700
committerVitaly Buka <vitalybuka@google.com>2024-09-23 00:26:22 -0700
commit688132f0892345b7b0a17c25f2b148ae6369a43d (patch)
treea253dbddd2e4620e8f301f13b1895153e084b20b
parent81c3499531c3fe03827bd8bc890e3a16db9e4c3c (diff)
Created using spr 1.3.4 [skip ci]
-rw-r--r--llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp97
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;
}
}