microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
memory_classifier.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
11#include "address_space.hpp"
12#include <cstdint>
13#include <type_traits>
14
15namespace microfmt {
16
20enum class memory_region_type : uint8_t {
21 unknown = 0,
22 kernel_code, // Kernel text / executable code section
23 kernel_data, // Kernel initialized data (.data) and bss (.bss)
24 kernel_stack, // Kernel thread / exception stack
25 process_stack, // User-space thread stack
26 direct_map, // Physical-to-virtual direct mapping region (e.g., __va /
27 // PAGE_OFFSET)
28 struct_pages, // Array of page descriptors (e.g., Linux mem_map / page
29 // structs)
30 kernel_heap, // Kernel allocator pool (e.g., slab / slub / malloc)
31 user_code, // User-space text segment
32 user_data, // User-space data and heap
33 device_mmio, // Memory-Mapped I/O registers
34 guard_page, // Unmapped guard page for stack overflow detection
35 ns_map, // NonSecure Mapping on ARM TrustZone
36 ns_device_mmio, // NonSecure Device mapping on ARM TrustZone
37};
38
44 uintptr_t start_address{0};
45
47 uintptr_t end_address{0};
48
50 memory_region_type type{memory_region_type::unknown};
51
53 uint32_t space_id{0};
54
56 bool readable{false};
57 bool writable{false};
58 bool executable{false};
59
63 [[nodiscard]] constexpr bool contains(uintptr_t addr) const noexcept {
64 return addr >= start_address && addr < end_address;
65 }
66};
67
72template <typename Tag> struct memory_classifier_traits;
73
81class RELOCO_POINTER memory_classifier_ref {
82public:
86 struct vtable {
96 bool (*classify_address)(const void *ctx, uintptr_t virt_addr, memory_region_info &out_info) noexcept = nullptr;
97 };
98
102 constexpr memory_classifier_ref() noexcept = default;
103
107 template <typename Tag, typename Traits = memory_classifier_traits<Tag>,
108 std::enable_if_t<std::is_void_v<typename Traits::context_type>, int> = 0>
109 constexpr explicit memory_classifier_ref(Tag) noexcept : ctx_(nullptr), vtbl_(&s_vtbl<Tag>) {}
110
114 template <typename Tag, typename Context, typename Traits = memory_classifier_traits<Tag>,
115 std::enable_if_t<!std::is_void_v<typename Traits::context_type> &&
116 std::is_convertible_v<const Context *, const typename Traits::context_type *>,
117 int> = 0>
118 constexpr memory_classifier_ref(Tag, const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
119 : ctx_(&ctx), vtbl_(&s_vtbl<Tag>) {}
120
121 template <typename Tag, typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>, int> = 0>
122 constexpr memory_classifier_ref(Tag, Context &&) = delete;
123
124 template <typename Tag, typename Traits = memory_classifier_traits<Tag>,
125 std::enable_if_t<std::is_void_v<typename Traits::context_type>, int> = 0>
126 [[nodiscard]] static constexpr memory_classifier_ref make() noexcept {
127 return memory_classifier_ref(Tag{});
128 }
129
130 template <typename Tag, typename Context, typename Traits = memory_classifier_traits<Tag>,
131 std::enable_if_t<!std::is_void_v<typename Traits::context_type>, int> = 0>
132 [[nodiscard]] static constexpr memory_classifier_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept {
133 return memory_classifier_ref(Tag{}, ctx);
134 }
135
136 template <typename Tag, typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>, int> = 0>
137 static memory_classifier_ref make(Context &&) = delete;
138
145 [[nodiscard]] bool classify_address(uintptr_t virt_addr, memory_region_info &out_info) const noexcept {
146 if (vtbl_ == nullptr || vtbl_->classify_address == nullptr)
147 return false;
148 return vtbl_->classify_address(ctx_.get(), virt_addr, out_info);
149 }
150
154 [[nodiscard]] constexpr explicit operator bool() const noexcept { return vtbl_ != nullptr; }
155
156private:
157 template <typename Tag>
158 static bool classify_entry(const void *context, uintptr_t address, memory_region_info &info) noexcept {
159 using context_type = typename memory_classifier_traits<Tag>::context_type;
160 if constexpr (std::is_void_v<context_type>) {
162 } else {
163 const auto &typed_context = *static_cast<const context_type *>(context);
164 return memory_classifier_traits<Tag>::classify_address(value_ref<const context_type>(typed_context), address,
165 info);
166 }
167 }
168
169 template <typename Tag> static constexpr vtable s_vtbl{&classify_entry<Tag>};
170
171 value_ptr<const void> ctx_{};
172 const vtable *vtbl_{nullptr};
173};
174
175template <typename Tag, bool Stateless = std::is_void_v<typename memory_classifier_traits<Tag>::context_type>>
177
178template <typename Tag> class RELOCO_OWNER memory_classifier<Tag, false> {
179public:
181 using context_type = typename traits_type::context_type;
182
183 constexpr explicit memory_classifier(context_type context) noexcept : context_(std::move(context)) {}
184
185 [[nodiscard]] constexpr value_ref<context_type> context() & noexcept RELOCO_LIFETIMEBOUND {
186 return value_ref<context_type>(context_);
187 }
188
189 [[nodiscard]] constexpr value_ref<const context_type> context() const & noexcept RELOCO_LIFETIMEBOUND {
190 return value_ref<const context_type>(context_);
191 }
192
193 [[nodiscard]] constexpr memory_classifier_ref ref() const & noexcept RELOCO_LIFETIMEBOUND {
194 return memory_classifier_ref(Tag{}, context_);
195 }
196
197 value_ref<context_type> context() && = delete;
198 value_ref<const context_type> context() const && = delete;
199 memory_classifier_ref ref() const && = delete;
200
201private:
202 context_type context_;
203};
204
205template <typename Tag> class memory_classifier<Tag, true> {
206public:
207 [[nodiscard]] static constexpr memory_classifier_ref ref() noexcept { return memory_classifier_ref(Tag{}); }
208};
209
210} // namespace microfmt
Type-erased remote address-space access and remote string/object views.
constexpr memory_classifier_ref ref() const &noexcept RELOCO_LIFETIMEBOUND
Definition memory_classifier.hpp:193
constexpr value_ref< context_type > context() &noexcept RELOCO_LIFETIMEBOUND
Definition memory_classifier.hpp:185
constexpr value_ref< const context_type > context() const &noexcept RELOCO_LIFETIMEBOUND
Definition memory_classifier.hpp:189
value_ref< context_type > context() &&=delete
value_ref< const context_type > context() const &&=delete
typename traits_type::context_type context_type
Definition memory_classifier.hpp:181
constexpr memory_classifier(context_type context) noexcept
Definition memory_classifier.hpp:183
static constexpr memory_classifier_ref ref() noexcept
Definition memory_classifier.hpp:207
Type-erased, two-word handle for classifying memory regions and addresses.
Definition memory_classifier.hpp:81
constexpr memory_classifier_ref() noexcept=default
Constructs an empty (invalid) handle.
constexpr memory_classifier_ref(Tag, Context &&)=delete
bool classify_address(uintptr_t virt_addr, memory_region_info &out_info) const noexcept
Classifies a target virtual address.
Definition memory_classifier.hpp:145
static memory_classifier_ref make(Context &&)=delete
static constexpr memory_classifier_ref make() noexcept
Definition memory_classifier.hpp:126
static constexpr memory_classifier_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept
Definition memory_classifier.hpp:132
constexpr memory_classifier_ref(Tag, const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Constructs a handle for a stateful classifier tag.
Definition memory_classifier.hpp:118
Definition memory_classifier.hpp:176
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition assert.hpp:19
memory_region_type
Enumeration of classified memory region types.
Definition memory_classifier.hpp:20
Virtual table of memory classification operations.
Definition memory_classifier.hpp:86
Static customization point describing a memory classifier backend.
Definition memory_classifier.hpp:72
Detailed description of a classified memory region or address.
Definition memory_classifier.hpp:42
constexpr bool contains(uintptr_t addr) const noexcept
Checks if a given virtual address falls within this region.
Definition memory_classifier.hpp:63