Path: blob/main/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_allocator.h
35235 views
//===-- hwasan_allocator.h --------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of HWAddressSanitizer.9//10//===----------------------------------------------------------------------===//1112#ifndef HWASAN_ALLOCATOR_H13#define HWASAN_ALLOCATOR_H1415#include "hwasan.h"16#include "hwasan_interface_internal.h"17#include "hwasan_mapping.h"18#include "hwasan_poisoning.h"19#include "lsan/lsan_common.h"20#include "sanitizer_common/sanitizer_allocator.h"21#include "sanitizer_common/sanitizer_allocator_checks.h"22#include "sanitizer_common/sanitizer_allocator_interface.h"23#include "sanitizer_common/sanitizer_allocator_report.h"24#include "sanitizer_common/sanitizer_common.h"25#include "sanitizer_common/sanitizer_ring_buffer.h"2627#if !defined(__aarch64__) && !defined(__x86_64__) && !(SANITIZER_RISCV64)28# error Unsupported platform29#endif3031namespace __hwasan {3233struct Metadata {34private:35atomic_uint64_t alloc_context_id;36u32 requested_size_low;37u16 requested_size_high;38atomic_uint8_t chunk_state;39u8 lsan_tag;4041public:42inline void SetAllocated(u32 stack, u64 size);43inline void SetUnallocated();4445inline bool IsAllocated() const;46inline u64 GetRequestedSize() const;47inline u32 GetAllocStackId() const;48inline u32 GetAllocThreadId() const;49inline void SetLsanTag(__lsan::ChunkTag tag);50inline __lsan::ChunkTag GetLsanTag() const;51};52static_assert(sizeof(Metadata) == 16);5354struct HwasanMapUnmapCallback {55void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }56void OnMapSecondary(uptr p, uptr size, uptr user_begin,57uptr user_size) const {58UpdateMemoryUsage();59}60void OnUnmap(uptr p, uptr size) const {61// We are about to unmap a chunk of user memory.62// It can return as user-requested mmap() or another thread stack.63// Make it accessible with zero-tagged pointer.64TagMemory(p, size, 0);65}66};6768static const uptr kMaxAllowedMallocSize = 1UL << 40; // 1T6970struct AP64 {71static const uptr kSpaceBeg = ~0ULL;7273#if defined(HWASAN_ALIASING_MODE)74static const uptr kSpaceSize = 1ULL << kAddressTagShift;75typedef __sanitizer::DefaultSizeClassMap SizeClassMap;76#elif SANITIZER_LINUX && !SANITIZER_ANDROID77static const uptr kSpaceSize = 0x40000000000ULL; // 4T.78typedef __sanitizer::DefaultSizeClassMap SizeClassMap;79#else80static const uptr kSpaceSize = 0x2000000000ULL; // 128G.81typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap;82#endif8384static const uptr kMetadataSize = sizeof(Metadata);85using AddressSpaceView = LocalAddressSpaceView;86typedef HwasanMapUnmapCallback MapUnmapCallback;87static const uptr kFlags = 0;88};8990typedef SizeClassAllocator64<AP64> PrimaryAllocator;91typedef CombinedAllocator<PrimaryAllocator> Allocator;92typedef Allocator::AllocatorCache AllocatorCache;9394void AllocatorThreadStart(AllocatorCache *cache);95void AllocatorThreadFinish(AllocatorCache *cache);9697class HwasanChunkView {98public:99HwasanChunkView() : block_(0), metadata_(nullptr) {}100HwasanChunkView(uptr block, Metadata *metadata)101: block_(block), metadata_(metadata) {}102bool IsAllocated() const; // Checks if the memory is currently allocated103uptr Beg() const; // First byte of user memory104uptr End() const; // Last byte of user memory105uptr UsedSize() const; // Size requested by the user106uptr ActualSize() const; // Size allocated by the allocator.107u32 GetAllocStackId() const;108u32 GetAllocThreadId() const;109bool FromSmallHeap() const;110bool AddrIsInside(uptr addr) const;111112private:113friend class __lsan::LsanMetadata;114uptr block_;115Metadata *const metadata_;116};117118HwasanChunkView FindHeapChunkByAddress(uptr address);119120// Information about one (de)allocation that happened in the past.121// These are recorded in a thread-local ring buffer.122struct HeapAllocationRecord {123uptr tagged_addr;124u32 alloc_thread_id;125u32 alloc_context_id;126u32 free_context_id;127u32 requested_size;128};129130typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;131132void GetAllocatorStats(AllocatorStatCounters s);133134} // namespace __hwasan135136#endif // HWASAN_ALLOCATOR_H137138139