10#include "../microfmt.hpp"
29 const sink &out)
noexcept;
52 RELOCO_BEGIN_UNSAFE_CODE
54 const auto &val = *
static_cast<const T *
>(field_ptr);
86 constexpr explicit string_ptr(uintptr_t addr) noexcept : addr_(addr) {}
89 RELOCO_BEGIN_UNSAFE_CODE
90 explicit string_ptr(
const char *ptr) noexcept : addr_(
reinterpret_cast<uintptr_t
>(ptr)) {}
93 [[nodiscard]]
constexpr uintptr_t
address() const noexcept {
return addr_; }
94 [[nodiscard]]
constexpr bool is_null() const noexcept {
return addr_ == 0; }
95 [[nodiscard]]
constexpr explicit operator bool() const noexcept {
return addr_ != 0; }
104 size_t max_limit = 4096) const & noexcept RELOCO_LIFETIMEBOUND {
109 size_t max_limit = 4096) const && = delete;
118RELOCO_BEGIN_UNSAFE_CODE
120 const sink &out)
noexcept {
121 const auto &sptr = *
static_cast<const string_ptr *
>(field_ptr);
122 if (sptr.is_null()) {
128 fmt.format(fsv, out);
132static_assert(
sizeof(
string_ptr) ==
sizeof(
void *),
"string_ptr must have correct size");
133static_assert(
alignof(
string_ptr) ==
sizeof(
void *),
"string32_ptr must be naturally aligned");
143 constexpr string32_ptr() noexcept : addr_(0) {}
144 constexpr explicit string32_ptr(uint32_t addr) noexcept : addr_(addr) {}
146 [[nodiscard]]
constexpr uint32_t raw_value()
const noexcept {
return addr_; }
147 [[nodiscard]]
constexpr uintptr_t address()
const noexcept {
return static_cast<uintptr_t
>(addr_); }
148 [[nodiscard]]
constexpr bool is_null()
const noexcept {
return addr_ == 0; }
149 [[nodiscard]]
constexpr explicit operator bool()
const noexcept {
return addr_ != 0; }
158 size_t max_limit = 4096)
const &
noexcept RELOCO_LIFETIMEBOUND {
163 size_t max_limit = 4096)
const && =
delete;
171RELOCO_BEGIN_UNSAFE_CODE
173 span<char> work_buf,
const sink &out)
noexcept {
174 const auto &sptr = *
static_cast<const string32_ptr *
>(field_ptr);
175 if (sptr.is_null()) {
181 fmt.format(fsv, out);
185static_assert(
sizeof(string32_ptr) == 4,
"string32_ptr must be exactly 4 bytes");
186static_assert(
alignof(string32_ptr) == 4,
"string32_ptr must be 4-byte aligned");
205 void format(
const string32_ptr &ptr,
const sink &out)
const noexcept {
219 static constexpr span<const remote_field_desc>
fields() noexcept {
return {}; }
233 template <
typename T>
235 span<std::byte> scratch RELOCO_LIFETIMEBOUND) noexcept
243 span<const remote_field_desc> fields RELOCO_LIFETIMEBOUND,
size_t struct_size,
244 size_t struct_align, span<std::byte> scratch RELOCO_LIFETIMEBOUND) noexcept
245 : addr_(addr), space_(space), fields_(fields), struct_size_(struct_size), struct_align_(struct_align),
248 [[nodiscard]]
constexpr uintptr_t
address() const noexcept {
return addr_; }
250 [[nodiscard]]
constexpr span<const remote_field_desc>
fields() const noexcept RELOCO_LIFETIMEBOUND {
return fields_; }
251 [[nodiscard]]
constexpr size_t struct_size() const noexcept {
return struct_size_; }
252 [[nodiscard]]
constexpr span<std::byte>
scratch() const noexcept RELOCO_LIFETIMEBOUND {
return scratch_; }
253 [[nodiscard]]
constexpr bool is_null() const noexcept {
return addr_ == 0; }
257 RELOCO_BEGIN_UNSAFE_CODE
258 [[nodiscard]] expected<const void *, remote_load_error>
load_raw() const noexcept {
260 return unexpected(remote_load_error::null_address);
261 if (scratch_.size() < struct_size_)
262 return unexpected(remote_load_error::scratch_too_small);
263 if (struct_align_ > 0 &&
reinterpret_cast<uintptr_t
>(scratch_.data()) % struct_align_ != 0)
264 return unexpected(remote_load_error::scratch_misaligned);
266 return unexpected(remote_load_error::invalid_address_space);
268 if (!space_.read_bytes(addr_, scratch_.data(), struct_size_))
269 return unexpected(remote_load_error::read_failed);
270 return static_cast<const void *
>(scratch_.data());
276 address_space_ref space_{};
277 span<const remote_field_desc> fields_{};
278 size_t struct_size_{0};
279 size_t struct_align_{1};
280 span<std::byte> scratch_{};
292 RELOCO_BEGIN_UNSAFE_CODE
294 if (view.is_null()) {
299 auto obj = view.load_raw();
306 const auto fields = view.fields();
308 const auto scratch = view.scratch();
310 if (scratch.size() > view.struct_size()) {
311 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
313 work_buf = span<char>(
reinterpret_cast<char *
>(scratch.data() + view.struct_size()),
314 scratch.size() - view.struct_size());
316 RELOCO_END_UNSAFE_BUFFER_USAGE;
319 for (
size_t i = 0; i < fields.size(); ++i) {
323 out.write(fields[i].name);
326 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
328 const void *field_ptr =
reinterpret_cast<const char *
>(*obj) + fields[i].offset;
330 RELOCO_END_UNSAFE_BUFFER_USAGE;
332 fields[i].format_fn(view.space(), field_ptr, work_buf, out);
345#define MICROFMT_REMOTE_STRUCT_BEGIN(StructName) \
346 template <> struct microfmt::remote_object_traits<StructName> { \
347 static constexpr size_t struct_size = sizeof(StructName); \
348 static constexpr size_t struct_align = alignof(StructName); \
349 static constexpr bool is_registered = true; \
350 static microfmt::span<const remote_field_desc> fields() noexcept { \
351 using CurrentStruct = StructName; \
352 static constexpr microfmt::remote_field_desc static_fields[] = {
354#define MICROFMT_REMOTE_FIELD(Name, ...) \
355 {#Name, offsetof(CurrentStruct, Name), µfmt::remote_field_traits<__VA_ARGS__>::format},
357#define MICROFMT_REMOTE_STRUCT_END() \
360 return {static_fields, sizeof(static_fields) / sizeof(static_fields[0])}; \
Type-erased, two-word handle to a remote address space.
Definition address_space.hpp:204
Streaming view of a foreign or non-contiguous string.
Definition foreign_string_view.hpp:29
Definition microfmt.hpp:881
Definition remote_object.hpp:231
constexpr remote_object_view(uintptr_t addr, address_space_ref space, type_tag< T >, span< std::byte > scratch RELOCO_LIFETIMEBOUND) noexcept
Definition remote_object.hpp:234
constexpr size_t struct_size() const noexcept
Definition remote_object.hpp:251
constexpr span< std::byte > scratch() const noexcept RELOCO_LIFETIMEBOUND
Definition remote_object.hpp:252
constexpr bool is_null() const noexcept
Definition remote_object.hpp:253
constexpr uintptr_t address() const noexcept
Definition remote_object.hpp:248
constexpr span< const remote_field_desc > fields() const noexcept RELOCO_LIFETIMEBOUND
Definition remote_object.hpp:250
constexpr address_space_ref space() const noexcept
Definition remote_object.hpp:249
constexpr remote_object_view(uintptr_t addr, address_space_ref space, span< const remote_field_desc > fields RELOCO_LIFETIMEBOUND, size_t struct_size, size_t struct_align, span< std::byte > scratch RELOCO_LIFETIMEBOUND) noexcept
Definition remote_object.hpp:242
RELOCO_BEGIN_UNSAFE_CODE expected< const void *, remote_load_error > load_raw() const noexcept
Definition remote_object.hpp:258
64-bit/Native remote string pointer wrapper.
Definition remote_object.hpp:83
constexpr string_ptr() noexcept
Definition remote_object.hpp:85
RELOCO_END_UNSAFE_CODE constexpr uintptr_t address() const noexcept
Definition remote_object.hpp:93
constexpr foreign_string_view as_view(address_space_ref space, span< char > scratch RELOCO_LIFETIMEBOUND, size_t max_limit=4096) const &&=delete
RELOCO_BEGIN_UNSAFE_CODE string_ptr(const char *ptr) noexcept
Definition remote_object.hpp:90
constexpr string_ptr(uintptr_t addr) noexcept
Definition remote_object.hpp:86
constexpr bool is_null() const noexcept
Definition remote_object.hpp:94
constexpr foreign_string_view as_view(address_space_ref space, span< char > scratch RELOCO_LIFETIMEBOUND, size_t max_limit=4096) const &noexcept RELOCO_LIFETIMEBOUND
Synthesizes a foreign_string_view over the pointed string.
Definition remote_object.hpp:103
32-bit compatibility pointers and remote view helpers for 64-bit hosts.
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Type-erased foreign string view formatter for microfmt.
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
void(*)(address_space_ref space, const void *field_ptr, span< char > work_buf, const sink &out) noexcept remote_field_format_fn
Type-erased function pointer for formatting a single remote object field from a loaded local struct b...
Definition remote_object.hpp:29
class MICROFMT_API_CLASS alignas(uint32_t) string32_ptr
32-bit compatibility string pointer wrapper (for 64-bit hosts).
Definition remote_object.hpp:141
RELOCO_END_UNSAFE_CODE
Definition remote_object.hpp:132
Static descriptor for a single field in a remote structure layout.
Definition remote_object.hpp:34
Default field formatter policy. Can be specialized or overloaded for custom remote types,...
Definition remote_object.hpp:49
static RELOCO_BEGIN_UNSAFE_CODE void format(address_space_ref, const void *field_ptr, span< char >, const sink &out) noexcept
Definition remote_object.hpp:53
Traits customization point for remote object metadata.
Definition remote_object.hpp:217
static constexpr size_t struct_align
Definition remote_object.hpp:221
static constexpr bool is_registered
Definition remote_object.hpp:218
static constexpr span< const remote_field_desc > fields() noexcept
Definition remote_object.hpp:219
static constexpr size_t struct_size
Definition remote_object.hpp:220
Definition remote_object.hpp:229