Skip to content

Commit

Permalink
Use the ASAN API to better communicate to the sanitizer, what memory …
Browse files Browse the repository at this point in the history
…regions should actually be valid (#670)

Co-authored-by: Martin Mory <[email protected]>
  • Loading branch information
fabianbs96 and MMory authored Nov 19, 2023
1 parent 659cb8d commit ae8c161
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ class AbstractMemoryLocationFactoryBase {
Block *Next = nullptr;

static Block *create(Block *Next, size_t NumPointerEntries);
static void destroy(Block *Blck);
static void destroy(Block *Blck, size_t NumPointerEntries);

private:
Block(Block *Next);
};

Block *Root = nullptr;
void **Pos = nullptr, **End = nullptr;
size_t InitialCapacity{};

Allocator() noexcept = default;
Allocator(size_t InitialCapacity);
Expand Down
18 changes: 17 additions & 1 deletion include/phasar/Utils/StableVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PHASAR_UTILS_STABLEVECTOR_H_

#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"

Expand Down Expand Up @@ -197,6 +198,8 @@ class StableVector {
Start = Blck;
End = Blck + Cap;
Pos = Blck + (Other.Pos - Other.Start);

__asan_poison_memory_region(Pos, (End - Pos) * sizeof(T));
}

void swap(StableVector &Other) noexcept {
Expand Down Expand Up @@ -244,6 +247,7 @@ class StableVector {
std::destroy(Start, Pos);

for (size_t I = BlockIdx; I < Blocks.size(); ++I) {
__asan_unpoison_memory_region(Blocks[I], Cap * sizeof(T));
std::allocator_traits<allocator_type>::deallocate(Alloc, Blocks[I], Cap);

Cap = TotalSize;
Expand All @@ -263,6 +267,7 @@ class StableVector {
}

auto Ret = Pos;
__asan_unpoison_memory_region(Ret, sizeof(T));
std::allocator_traits<allocator_type>::construct(
Alloc, Ret, std::forward<ArgTys>(Args)...);
++Pos;
Expand Down Expand Up @@ -343,6 +348,8 @@ class StableVector {
assert(!empty() && "Do not call pop_back() on an empty StableVector!");

std::destroy_at(--Pos);
__asan_poison_memory_region(Pos, sizeof(T));

--Size;
if (Pos != Start) {
return;
Expand Down Expand Up @@ -374,11 +381,13 @@ class StableVector {

for (size_t I = 0; I < BlockIdx; ++I) {
std::destroy_n(Blocks[I], Cap);
__asan_poison_memory_region(Blocks[I], Cap * sizeof(T));
Cap = TotalSize;
TotalSize += Cap;
}

std::destroy(Start, Pos);
__asan_poison_memory_region(Start, (Pos - Start) * sizeof(T));
BlockIdx = 0;
Size = 0;
if (!Blocks.empty()) {
Expand All @@ -399,10 +408,12 @@ class StableVector {
Pos -= N;
Size -= N;
std::destroy_n(Pos, N);
__asan_poison_memory_region(Pos, N * sizeof(T));
return;
}

std::destroy(Start, Pos);
__asan_poison_memory_region(Start, (Pos - Start) * sizeof(T));
Size -= NumElementsInCurrBlock;
N -= NumElementsInCurrBlock;

Expand All @@ -429,6 +440,7 @@ class StableVector {

if (Size == 0) {
assert(BlockIdx == 0);
__asan_unpoison_memory_region(Blocks[0], InitialCapacity * sizeof(T));
std::allocator_traits<allocator_type>::deallocate(Alloc, Blocks[0],
InitialCapacity);
}
Expand All @@ -437,6 +449,7 @@ class StableVector {

for (size_t I = BlockIdx + 1, BlocksEnd = Blocks.size(); I < BlocksEnd;
++I) {
__asan_unpoison_memory_region(Blocks[I], Cap * sizeof(T));
std::allocator_traits<allocator_type>::deallocate(Alloc, Blocks[I], Cap);
Cap <<= 1;
}
Expand Down Expand Up @@ -491,7 +504,9 @@ class StableVector {
template <typename... ArgTys>
[[nodiscard]] T &growAndEmplace(ArgTys &&...Args) {
auto makeBlock = [this](size_t N) {
return std::allocator_traits<allocator_type>::allocate(Alloc, N);
auto *Ret = std::allocator_traits<allocator_type>::allocate(Alloc, N);
__asan_poison_memory_region(std::next(Ret), (N - 1) * sizeof(T));
return Ret;
};

if (Blocks.empty()) {
Expand All @@ -501,6 +516,7 @@ class StableVector {
assert(llvm::isPowerOf2_64(Size));
BlockIdx++;
End = Blocks[BlockIdx] + Size;
__asan_unpoison_memory_region(Blocks[BlockIdx], sizeof(T));
} else {
assert(llvm::isPowerOf2_64(Size));
BlockIdx++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,17 @@ auto AbstractMemoryLocationFactoryBase::Allocator::Block::create(
alignof(AbstractMemoryLocationImpl)}) size_t[1 + NumPointerEntries]);

new (Ret) Block(Next);

__asan_poison_memory_region(Ret->getTrailingObjects<void *>(),
NumPointerEntries * sizeof(void *));

return Ret;
}

void AbstractMemoryLocationFactoryBase::Allocator::Block::destroy(Block *Blck) {
void AbstractMemoryLocationFactoryBase::Allocator::Block::destroy(
Block *Blck, [[maybe_unused]] size_t NumPointerEntries) {
__asan_unpoison_memory_region(Blck->getTrailingObjects<void *>(),
NumPointerEntries * sizeof(void *));
::operator delete[](Blck,
std::align_val_t{alignof(AbstractMemoryLocationImpl)});
}
Expand All @@ -61,10 +68,13 @@ AbstractMemoryLocationFactoryBase::Allocator::Allocator(
}

AbstractMemoryLocationFactoryBase::Allocator::~Allocator() {
auto *Blck = Root;
auto *Rt = Root;
auto *Blck = Rt;
while (Blck) {
auto *Nxt = Blck->Next;
Block::destroy(Blck);
Block::destroy(Blck, Blck == Rt
? (MinNumPointersPerAML + 3) * InitialCapacity
: NumPointersPerBlock);
Blck = Nxt;
}
Root = nullptr;
Expand Down Expand Up @@ -110,6 +120,8 @@ AbstractMemoryLocationFactoryBase::Allocator::create(

Pos += NumPointersRequired;

__asan_unpoison_memory_region(Ret, NumPointersRequired * sizeof(void *));

new (Ret) AbstractMemoryLocationImpl(Baseptr, Offsets, Lifetime);

return Ret;
Expand Down

0 comments on commit ae8c161

Please sign in to comment.