microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
address_translator.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
23 uintptr_t physical_address{0};
24
26 uint8_t space_id{0};
27
30 bool is_secure{false};
31
33 bool readable{false};
34
36 bool writable{false};
37
39 bool executable{false};
40
42 bool user_accessible{false};
43
47 [[nodiscard]] constexpr bool is_valid() const noexcept { return readable || writable || executable; }
48};
49
55template <typename Tag> struct address_translator_traits;
56
64class RELOCO_POINTER address_translator_ref {
65public:
69 struct vtable {
80 bool (*translate)(const void *ctx, uintptr_t virt_addr, translation_attributes &out_attrs) noexcept = nullptr;
81 };
82
86 constexpr address_translator_ref() noexcept = default;
87
91 template <typename Tag, typename Traits = address_translator_traits<Tag>,
92 std::enable_if_t<std::is_void_v<typename Traits::context_type>, int> = 0>
93 constexpr explicit address_translator_ref(Tag) noexcept : ctx_(nullptr), vtbl_(&s_vtbl<Tag>) {}
94
98 template <typename Tag, typename Context, typename Traits = address_translator_traits<Tag>,
99 std::enable_if_t<!std::is_void_v<typename Traits::context_type> &&
100 std::is_convertible_v<const Context *, const typename Traits::context_type *>,
101 int> = 0>
103 const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
104 : ctx_(&ctx), vtbl_(&s_vtbl<Tag>) {}
105
106 template <typename Tag, typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>, int> = 0>
107 constexpr address_translator_ref(Tag, Context &&) = delete;
108
109 template <typename Tag, typename Traits = address_translator_traits<Tag>,
110 std::enable_if_t<std::is_void_v<typename Traits::context_type>, int> = 0>
111 [[nodiscard]] static constexpr address_translator_ref make() noexcept {
112 return address_translator_ref(Tag{});
113 }
114
115 template <typename Tag, typename Context, typename Traits = address_translator_traits<Tag>,
116 std::enable_if_t<!std::is_void_v<typename Traits::context_type>, int> = 0>
117 [[nodiscard]] static constexpr address_translator_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept {
118 return address_translator_ref(Tag{}, ctx);
119 }
120
121 template <typename Tag, typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>, int> = 0>
122 static address_translator_ref make(Context &&) = delete;
123
132 [[nodiscard]] bool translate(uintptr_t virt_addr, translation_attributes &out_attrs) const noexcept {
133 if (vtbl_ == nullptr || vtbl_->translate == nullptr)
134 return false;
135 return vtbl_->translate(ctx_.get(), virt_addr, out_attrs);
136 }
137
138 [[nodiscard]] constexpr explicit operator bool() const noexcept { return vtbl_ != nullptr; }
139
140private:
141 template <typename Tag>
142 static bool translate_entry(const void *context, uintptr_t address, translation_attributes &attributes) noexcept {
143 using context_type = typename address_translator_traits<Tag>::context_type;
144 if constexpr (std::is_void_v<context_type>) {
145 return address_translator_traits<Tag>::translate(address, attributes);
146 } else {
147 const auto &typed_context = *static_cast<const context_type *>(context);
148 return address_translator_traits<Tag>::translate(value_ref<const context_type>(typed_context), address,
149 attributes);
150 }
151 }
152
153 template <typename Tag> static constexpr vtable s_vtbl{&translate_entry<Tag>};
154
155 value_ptr<const void> ctx_{};
156 const vtable *vtbl_{nullptr};
157};
158
159template <typename Tag, bool Stateless = std::is_void_v<typename address_translator_traits<Tag>::context_type>>
161
162template <typename Tag> class RELOCO_OWNER address_translator<Tag, false> {
163public:
165 using context_type = typename traits_type::context_type;
166
167 constexpr explicit address_translator(context_type context) noexcept : context_(std::move(context)) {}
168
169 [[nodiscard]] constexpr value_ref<context_type> context() & noexcept RELOCO_LIFETIMEBOUND {
170 return value_ref<context_type>(context_);
171 }
172
173 [[nodiscard]] constexpr value_ref<const context_type> context() const & noexcept RELOCO_LIFETIMEBOUND {
174 return value_ref<const context_type>(context_);
175 }
176
177 [[nodiscard]] constexpr address_translator_ref ref() const & noexcept RELOCO_LIFETIMEBOUND {
178 return address_translator_ref(Tag{}, context_);
179 }
180
181 value_ref<context_type> context() && = delete;
182 value_ref<const context_type> context() const && = delete;
183 address_translator_ref ref() const && = delete;
184
185private:
186 context_type context_;
187};
188
189template <typename Tag> class address_translator<Tag, true> {
190public:
191 [[nodiscard]] static constexpr address_translator_ref ref() noexcept { return address_translator_ref(Tag{}); }
192};
193
194} // namespace microfmt
Type-erased remote address-space access and remote string/object views.
typename traits_type::context_type context_type
Definition address_translator.hpp:165
value_ref< context_type > context() &&=delete
constexpr address_translator(context_type context) noexcept
Definition address_translator.hpp:167
constexpr value_ref< const context_type > context() const &noexcept RELOCO_LIFETIMEBOUND
Definition address_translator.hpp:173
value_ref< const context_type > context() const &&=delete
constexpr value_ref< context_type > context() &noexcept RELOCO_LIFETIMEBOUND
Definition address_translator.hpp:169
constexpr address_translator_ref ref() const &noexcept RELOCO_LIFETIMEBOUND
Definition address_translator.hpp:177
static constexpr address_translator_ref ref() noexcept
Definition address_translator.hpp:191
Type-erased, two-word handle for virtual-to-physical address translation.
Definition address_translator.hpp:64
bool translate(uintptr_t virt_addr, translation_attributes &out_attrs) const noexcept
Translates a virtual address to physical address and populates attributes.
Definition address_translator.hpp:132
constexpr address_translator_ref(Tag, Context &&)=delete
static address_translator_ref make(Context &&)=delete
static constexpr address_translator_ref make() noexcept
Definition address_translator.hpp:111
constexpr address_translator_ref() noexcept=default
Constructs an empty (invalid) handle.
static constexpr address_translator_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept
Definition address_translator.hpp:117
constexpr address_translator_ref(Tag, const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Constructs a handle for a stateful translator tag.
Definition address_translator.hpp:102
Definition address_translator.hpp:160
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition assert.hpp:19
Virtual table of address translation operations.
Definition address_translator.hpp:69
Static customization point describing a virtual-to-physical translator backend.
Definition address_translator.hpp:55
Attributes and physical mapping details resolved for a virtual address.
Definition address_translator.hpp:21
constexpr bool is_valid() const noexcept
Reports whether the attribute record represents a valid translation.
Definition address_translator.hpp:47