30 microfmt::string_view symbol_name{
""};
34 uintptr_t symbol_base{0};
43 microfmt::string_view image_name{
""};
47 uintptr_t image_load_base{0};
57 microfmt::string_view symbol_name{
""};
61 uintptr_t symbol_base{0};
65 uintptr_t offset_from_symbol{0};
74 microfmt::string_view image_name{
""};
78 uintptr_t image_load_base{0};
82 uintptr_t offset_from_image{0};
88 [[nodiscard]]
constexpr bool has_symbol() const noexcept {
return !symbol_name.empty(); }
94 [[nodiscard]]
constexpr bool has_image() const noexcept {
return !image_name.empty(); }
102 : scratch(string_scratch) {}
107 span<char> scratch{};
141 bool (*resolve)(
const void *ctx, uintptr_t addr, span<char> scratch,
156 std::enable_if_t<std::is_void_v<typename Traits::context_type>,
int> = 0>
167 template <
typename Tag,
typename Context,
typename Traits = symbol_resolver_traits<Tag>,
168 std::enable_if_t<!std::is_
void_v<
typename Traits::context_type> &&
169 std::is_convertible_v<const Context *, const
typename Traits::context_type *>,
171 constexpr symbol_resolver_ref(Tag,
const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
172 : ctx_(&ctx), vtbl_(&s_vtbl<Tag>) {}
174 template <
typename Tag,
typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>,
int> = 0>
183 template <
typename Tag,
typename Traits = symbol_resolver_traits<Tag>,
184 std::enable_if_t<std::is_
void_v<
typename Traits::context_type>,
int> = 0>
197 template <
typename Tag,
typename Context,
typename Traits = symbol_resolver_traits<Tag>,
198 std::enable_if_t<!std::is_
void_v<
typename Traits::context_type>,
int> = 0>
203 template <
typename Tag,
typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>,
int> = 0>
215 return resolve(addr, context.scratch, context.raw, context.resolved);
229 if (vtbl_ ==
nullptr)
233 if (!vtbl_->resolve(ctx_.get(), addr, scratch, raw_storage)) {
238 out_info.symbol_name = raw_storage.symbol_name;
239 out_info.symbol_base = raw_storage.symbol_base;
240 out_info.is_exact = raw_storage.is_exact;
241 out_info.image_name = raw_storage.image_name;
242 out_info.image_load_base = raw_storage.image_load_base;
244 if (raw_storage.symbol_base != 0 && addr >= raw_storage.symbol_base) {
245 out_info.offset_from_symbol = addr - raw_storage.symbol_base;
247 out_info.offset_from_symbol = 0;
250 if (raw_storage.image_load_base != 0 && addr >= raw_storage.image_load_base) {
251 out_info.offset_from_image = addr - raw_storage.image_load_base;
253 out_info.offset_from_image = 0;
263 [[nodiscard]]
constexpr explicit operator bool() const noexcept {
return vtbl_ !=
nullptr; }
266 template <
typename Tag>
267 static bool resolve_entry(
const void *context, uintptr_t address, span<char> scratch,
270 if constexpr (std::is_void_v<context_type>) {
273 const auto &typed_context = *
static_cast<const context_type *
>(context);
274 return symbol_resolver_traits<Tag>::resolve(value_ref<const context_type>(typed_context), address, scratch,
279 template <
typename Tag>
static constexpr vtable s_vtbl{&resolve_entry<Tag>};
281 value_ptr<const void> ctx_{};
282 const vtable *vtbl_{
nullptr};
285template <typename Tag, bool Stateless = std::is_void_v<typename symbol_resolver_traits<Tag>::context_type>>
295 [[nodiscard]]
constexpr value_ref<context_type>
context() &
noexcept RELOCO_LIFETIMEBOUND {
296 return value_ref<context_type>(context_);
299 [[nodiscard]]
constexpr value_ref<const context_type>
context() const & noexcept RELOCO_LIFETIMEBOUND {
300 return value_ref<const context_type>(context_);
307 value_ref<context_type>
context() && =
delete;
308 value_ref<const context_type>
context() const && = delete;
343 : addr_(addr), resolver_(resolver), context_(&context), demangle_(demangle) {}
349 [[nodiscard]]
constexpr uintptr_t
address() const noexcept {
return addr_; }
363 [[nodiscard]]
constexpr bool demangle() const noexcept {
return demangle_; }
369 symbol_resolver_ref resolver_{};
371 value_ptr<symbol_resolution_context> context_{};
373 bool demangle_{
true};
393 const auto spec = ctx.spec();
394 if (!spec.empty() && spec.front() ==
'#') {
405 if (view.address() == 0) {
410 if (!view.resolver()) {
415 auto &context = view.context();
417 context.resolved = {};
418 const bool ok = view.resolver().resolve(view.address(), context);
419 const auto &info = context.resolved;
422 if (!
ok || (!info.has_symbol() && !info.has_image())) {
428 if (info.has_symbol()) {
429 if (mode ==
'#' && info.has_image()) {
433 if (view.demangle()) {
436 out.write(info.symbol_name);
439 if (info.offset_from_symbol > 0) {
446 if (info.has_image()) {
Type-erased remote address-space access and remote string/object views.
Definition microfmt.hpp:881
Formattable view resolving and rendering a remote code address.
Definition symbol_resolver.hpp:327
constexpr symbol_resolver_ref resolver() const noexcept
Returns the symbol resolver handle.
Definition symbol_resolver.hpp:354
constexpr uintptr_t address() const noexcept
Returns the address being resolved.
Definition symbol_resolver.hpp:349
constexpr remote_symbol_view() noexcept=default
Constructs an empty (null) view.
constexpr symbol_resolution_context & context() const noexcept RELOCO_LIFETIMEBOUND
Returns caller-owned symbol-resolution temporaries.
Definition symbol_resolver.hpp:358
constexpr bool demangle() const noexcept
Reports whether symbol names are demangled.
Definition symbol_resolver.hpp:363
value_ref< context_type > context() &&=delete
typename traits_type::context_type context_type
Definition symbol_resolver.hpp:291
constexpr symbol_resolver_ref ref() const &noexcept RELOCO_LIFETIMEBOUND
Definition symbol_resolver.hpp:303
constexpr value_ref< const context_type > context() const &noexcept RELOCO_LIFETIMEBOUND
Definition symbol_resolver.hpp:299
constexpr value_ref< context_type > context() &noexcept RELOCO_LIFETIMEBOUND
Definition symbol_resolver.hpp:295
constexpr symbol_resolver(context_type context) noexcept
Definition symbol_resolver.hpp:293
value_ref< const context_type > context() const &&=delete
static constexpr symbol_resolver_ref ref() noexcept
Definition symbol_resolver.hpp:317
Type-erased, two-word handle to a symbol resolver.
Definition symbol_resolver.hpp:132
constexpr symbol_resolver_ref(Tag, Context &&)=delete
constexpr symbol_resolver_ref() noexcept=default
Constructs an empty (invalid) handle.
static symbol_resolver_ref make(Context &&)=delete
constexpr symbol_resolver_ref(Tag, const Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Constructs a handle for a stateful resolver tag.
Definition symbol_resolver.hpp:171
static constexpr symbol_resolver_ref make(const Context &ctx RELOCO_LIFETIMEBOUND) noexcept
Creates a handle for a stateful resolver tag.
Definition symbol_resolver.hpp:199
bool resolve(uintptr_t addr, span< char > scratch, raw_resolved_symbol &raw_storage, resolved_symbol_info &out_info) const noexcept
Resolves an address using caller-owned intermediate storage.
Definition symbol_resolver.hpp:227
bool resolve(uintptr_t addr, symbol_resolution_context &context) const noexcept
Resolves an address and computes the derived offsets.
Definition symbol_resolver.hpp:214
static constexpr symbol_resolver_ref make() noexcept
Creates a handle for a stateless resolver tag.
Definition symbol_resolver.hpp:185
Definition symbol_resolver.hpp:286
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Zero-allocation Itanium (GCC/Clang) name demangler.
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
constexpr auto as_demangled(microfmt::string_view sym) noexcept
Wraps a symbol for demangled formatting.
Definition demangle.hpp:523
constexpr auto make_remote_symbol(uintptr_t addr, symbol_resolver_ref resolver, symbol_resolution_context &context, bool demangle=true) noexcept
Convenience factory building a remote_symbol_view.
Definition symbol_resolver.hpp:460
Raw resolution result as returned by a resolver backend.
Definition symbol_resolver.hpp:26
Derived symbol info with precomputed relative offsets.
Definition symbol_resolver.hpp:53
constexpr bool has_symbol() const noexcept
Reports whether a symbol name is available.
Definition symbol_resolver.hpp:88
constexpr bool has_image() const noexcept
Reports whether an owning image is known.
Definition symbol_resolver.hpp:94
Caller-owned temporary storage for one symbol resolution.
Definition symbol_resolver.hpp:100
constexpr symbol_resolution_context(char(&string_scratch)[N]) noexcept
Definition symbol_resolver.hpp:105
constexpr symbol_resolution_context(span< char > string_scratch RELOCO_LIFETIMEBOUND={}) noexcept
Definition symbol_resolver.hpp:101
Virtual table of symbol-resolution operations.
Definition symbol_resolver.hpp:137
Static customization point for symbol resolver backends.
Definition symbol_resolver.hpp:120