1 //===-- bytemap.h -----------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef SCUDO_BYTEMAP_H_
10 #define SCUDO_BYTEMAP_H_
12 #include "atomic_helpers.h"
18 template <uptr Size> class FlatByteMap {
20 void initLinkerInitialized() {
21 Map = reinterpret_cast<u8 *>(map(nullptr, Size, "scudo:bytemap"));
23 void init() { initLinkerInitialized(); }
25 void unmapTestOnly() { unmap(reinterpret_cast<void *>(Map), Size); }
27 void set(uptr Index, u8 Value) {
28 DCHECK_LT(Index, Size);
29 DCHECK_EQ(0U, Map[Index]);
32 u8 operator[](uptr Index) {
33 DCHECK_LT(Index, Size);
41 template <uptr Level1Size, uptr Level2Size> class TwoLevelByteMap {
43 void initLinkerInitialized() {
44 Level1Map = reinterpret_cast<atomic_uptr *>(
45 map(nullptr, sizeof(atomic_uptr) * Level1Size, "scudo:bytemap"));
49 initLinkerInitialized();
53 for (uptr I = 0; I < Level1Size; I++) {
59 memset(Level1Map, 0, sizeof(atomic_uptr) * Level1Size);
62 void unmapTestOnly() {
64 unmap(reinterpret_cast<void *>(Level1Map),
65 sizeof(atomic_uptr) * Level1Size);
68 uptr size() const { return Level1Size * Level2Size; }
70 void set(uptr Index, u8 Value) {
71 DCHECK_LT(Index, Level1Size * Level2Size);
72 u8 *Level2Map = getOrCreate(Index / Level2Size);
73 DCHECK_EQ(0U, Level2Map[Index % Level2Size]);
74 Level2Map[Index % Level2Size] = Value;
77 u8 operator[](uptr Index) const {
78 DCHECK_LT(Index, Level1Size * Level2Size);
79 u8 *Level2Map = get(Index / Level2Size);
82 return Level2Map[Index % Level2Size];
86 u8 *get(uptr Index) const {
87 DCHECK_LT(Index, Level1Size);
88 return reinterpret_cast<u8 *>(
89 atomic_load(&Level1Map[Index], memory_order_acquire));
92 u8 *getOrCreate(uptr Index) {
96 if (!(Res = get(Index))) {
97 Res = reinterpret_cast<u8 *>(map(nullptr, Level2Size, "scudo:bytemap"));
98 atomic_store(&Level1Map[Index], reinterpret_cast<uptr>(Res),
99 memory_order_release);
105 atomic_uptr *Level1Map;
111 #endif // SCUDO_BYTEMAP_H_