10#include "../microfmt.hpp"
11#include "../reloco.hpp"
34 microfmt::string_view image_name{
""};
38 uintptr_t load_base{0};
42 uintptr_t image_size{0};
47 uintptr_t exidx_start{0};
51 uintptr_t exidx_end{0};
61 uintptr_t debug_frame_start{0};
68 uintptr_t debug_frame_end{0};
75 [[nodiscard]]
constexpr bool contains(uintptr_t addr)
const noexcept {
76 return addr >= load_base && addr < (load_base + image_size);
83 [[nodiscard]]
constexpr bool has_exidx() const noexcept {
return exidx_start != 0 && exidx_end > exidx_start; }
91 return debug_frame_start != 0 && debug_frame_end > debug_frame_start;
114 bool (*enumerate)(
const void *ctx, span<elf_image_info> out_buffer,
size_t &out_count)
noexcept =
nullptr;
119 bool (*find_by_pc)(
const void *ctx, uintptr_t pc,
elf_image_info &out_info)
noexcept =
nullptr;
135 std::enable_if_t<std::is_convertible_v<const Context *, const typename Traits::context_type *>,
int> = 0>
137 const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
138 : ctx_(&ctx), vtbl_(&s_vtbl<Tag>) {}
140 template <
typename Tag,
typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>,
int> = 0>
143 template <
typename Tag,
typename Context,
typename Traits = elf_image_enumerator_traits<Tag>>
148 template <
typename Tag,
typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>,
int> = 0>
157 [[nodiscard]]
bool enumerate(span<elf_image_info> out_buffer,
size_t &out_count)
const noexcept {
158 if (vtbl_ ==
nullptr)
160 return vtbl_->enumerate(ctx_.get(), out_buffer, out_count);
170 if (vtbl_ ==
nullptr)
172 return vtbl_->find_by_pc(ctx_.get(), pc, out_info);
179 [[nodiscard]]
constexpr explicit operator bool() const noexcept {
return vtbl_ !=
nullptr; }
182 template <
typename Tag>
183 static constexpr vtable s_vtbl{
184 [](
const void *context, span<elf_image_info> buffer,
size_t &count)
noexcept {
186 const auto &typed_context = *
static_cast<const context_type *
>(context);
189 [](
const void *context, uintptr_t pc, elf_image_info &info)
noexcept {
190 using context_type =
typename elf_image_enumerator_traits<Tag>::context_type;
191 const auto &typed_context = *
static_cast<const context_type *
>(context);
192 return elf_image_enumerator_traits<Tag>::find_by_pc(value_ref<const context_type>(typed_context), pc, info);
195 value_ptr<const void> ctx_{};
196 const vtable *vtbl_{
nullptr};
209 [[nodiscard]]
constexpr value_ref<context_type>
context() &
noexcept RELOCO_LIFETIMEBOUND {
210 return value_ref<context_type>(context_);
213 [[nodiscard]]
constexpr value_ref<const context_type>
context() const & noexcept RELOCO_LIFETIMEBOUND {
214 return value_ref<const context_type>(context_);
225 value_ref<context_type>
context() && =
delete;
226 value_ref<const context_type>
context() const && = delete;
256 if (image_count_ >= MaxImages)
258 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
260 images_[image_count_++] = info;
262 RELOCO_END_UNSAFE_BUFFER_USAGE;
273 [[nodiscard]]
constexpr bool enumerate(span<elf_image_info> out_buffer,
size_t &out_count)
const noexcept {
274 size_t copy_count = (image_count_ < out_buffer.size()) ? image_count_ : out_buffer.size();
275 for (
size_t i = 0; i < copy_count; ++i) {
276 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
278 out_buffer[i] = images_[i];
280 RELOCO_END_UNSAFE_BUFFER_USAGE;
282 out_count = copy_count;
293 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
295 for (
size_t i = 0; i < image_count_; ++i) {
296 if (images_[i].contains(pc)) {
297 out_info = images_[i];
302 RELOCO_END_UNSAFE_BUFFER_USAGE;
311 [[nodiscard]]
constexpr size_t size() const noexcept {
return image_count_; }
317 size_t image_count_{0};
327 static bool enumerate(value_ref<const context_type> context, span<elf_image_info> buffer,
size_t &count)
noexcept {
328 return context->enumerate(buffer, count);
332 return context->find_by_pc(pc, info);
Type-erased, two-word handle to an ELF image enumerator.
Definition elf_enumerator.hpp:104
constexpr elf_image_enumerator_ref(Tag, Context &&)=delete
bool enumerate(span< elf_image_info > out_buffer, size_t &out_count) const noexcept
Fills a caller-provided buffer with registered ELF images.
Definition elf_enumerator.hpp:157
static elf_image_enumerator_ref make(Context &&)=delete
bool find_by_pc(uintptr_t pc, elf_image_info &out_info) const noexcept
Locates the ELF image containing the given PC address.
Definition elf_enumerator.hpp:169
constexpr elf_image_enumerator_ref() noexcept=default
Constructs an empty (invalid) handle.
static constexpr elf_image_enumerator_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept
Definition elf_enumerator.hpp:144
Typed owner for an ELF image-enumerator traits specialization.
Definition elf_enumerator.hpp:202
typename traits_type::context_type context_type
Definition elf_enumerator.hpp:205
value_ref< const context_type > context() const &&=delete
constexpr value_ref< context_type > context() &noexcept RELOCO_LIFETIMEBOUND
Definition elf_enumerator.hpp:209
constexpr elf_image_enumerator_ref ref() const &noexcept RELOCO_LIFETIMEBOUND
Definition elf_enumerator.hpp:217
constexpr value_ref< const context_type > context() const &noexcept RELOCO_LIFETIMEBOUND
Definition elf_enumerator.hpp:213
value_ref< context_type > context() &&=delete
constexpr elf_image_enumerator(context_type context) noexcept
Definition elf_enumerator.hpp:207
Fixed-capacity, zero-allocation registry of ELF images.
Definition elf_enumerator.hpp:243
constexpr bool enumerate(span< elf_image_info > out_buffer, size_t &out_count) const noexcept
Copies registered images into a caller buffer.
Definition elf_enumerator.hpp:273
constexpr size_t size() const noexcept
Returns the number of registered images.
Definition elf_enumerator.hpp:311
constexpr bool find_by_pc(uintptr_t pc, elf_image_info &out_info) const noexcept
Locates the registered image containing pc.
Definition elf_enumerator.hpp:292
constexpr multi_elf_registry_context() noexcept=default
Constructs an empty registry.
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Virtual table of image enumeration operations.
Definition elf_enumerator.hpp:109
static bool enumerate(value_ref< const context_type > context, span< elf_image_info > buffer, size_t &count) noexcept
Definition elf_enumerator.hpp:327
static bool find_by_pc(value_ref< const context_type > context, uintptr_t pc, elf_image_info &info) noexcept
Definition elf_enumerator.hpp:331
Definition elf_enumerator.hpp:19
Describes a loaded ELF image and the locations of its unwind tables.
Definition elf_enumerator.hpp:30
constexpr bool has_debug_frame() const noexcept
Reports whether a usable DWARF CFI unwind-record table (.debug_frame or .eh_frame,...
Definition elf_enumerator.hpp:90
constexpr bool has_exidx() const noexcept
Reports whether a usable .ARM.exidx section is present.
Definition elf_enumerator.hpp:83
constexpr bool contains(uintptr_t addr) const noexcept
Reports whether addr falls within the image range.
Definition elf_enumerator.hpp:75
Definition elf_enumerator.hpp:21