88#include < cstddef>
99#include < cstdint>
1010#include < ctime>
11+ #include < expected>
1112#include < memory>
1213#include < string_view>
1314#include < sys/utsname.h>
@@ -27,6 +28,9 @@ inline constexpr size_t DEFAULT_MEMORY_ALIGN = 16;
2728
2829inline constexpr int32_t errno_ok = 0 ;
2930inline constexpr int32_t errno_einval = EINVAL ;
31+ inline constexpr int32_t errno_enodata = ENODATA ;
32+ inline constexpr int32_t errno_efault = EFAULT ;
33+ inline constexpr int32_t errno_enomem = ENOMEM ;
3034
3135inline constexpr uint64_t INVALID_PLATFORM_DESCRIPTOR = 0 ;
3236
@@ -234,4 +238,47 @@ inline int32_t iconv(size_t* result, void* iconv_cd, char** inbuf, size_t* inbyt
234238 return k2_iconv (result, iconv_cd, inbuf, inbytesleft, outbuf, outbytesleft);
235239}
236240
241+ struct SymbolInfo {
242+ std::unique_ptr<char , decltype (std::addressof(k2::free))> name;
243+ std::unique_ptr<char , decltype (std::addressof(k2::free))> filename;
244+ uint32_t lineno;
245+ };
246+
247+ inline std::expected<k2::SymbolInfo, int32_t > resolve_symbol (void * addr) noexcept {
248+ size_t name_len{};
249+ if (auto error_code{k2_symbol_name_len (addr, std::addressof (name_len))}; error_code != k2::errno_ok) [[unlikely]] {
250+ return std::unexpected{error_code};
251+ }
252+ size_t filename_len{};
253+ if (auto error_code{k2_symbol_filename_len (addr, std::addressof (filename_len))}; error_code != k2::errno_ok) [[unlikely]] {
254+ return std::unexpected{error_code};
255+ }
256+
257+ // +1 since we get non-null-terminated strings from platform and we want to null-terminate them on our side
258+ auto * name{static_cast <char *>(k2::alloc (name_len + 1 ))};
259+ if (name == nullptr ) [[unlikely]] {
260+ return std::unexpected{k2::errno_enomem};
261+ }
262+
263+ auto * filename{static_cast <char *>(k2::alloc (filename_len + 1 ))};
264+ if (filename == nullptr ) [[unlikely]] {
265+ return std::unexpected{k2::errno_enomem};
266+ }
267+
268+ ::SymbolInfo symbol_info{.name = name, .filename = filename, .lineno = 0 };
269+ if (auto error_code{k2_resolve_symbol (addr, std::addressof (symbol_info))}; error_code != k2::errno_ok) [[unlikely]] {
270+ k2::free (filename);
271+ k2::free (name);
272+ return std::unexpected{error_code};
273+ }
274+
275+ // null-terminate
276+ name[name_len] = ' \0 ' ;
277+ filename[filename_len] = ' \0 ' ;
278+
279+ return k2::SymbolInfo{.name = std::unique_ptr<char , decltype (std::addressof (k2::free))>{name, k2::free},
280+ .filename = std::unique_ptr<char , decltype (std::addressof (k2::free))>{filename, k2::free},
281+ .lineno = symbol_info.lineno };
282+ }
283+
237284} // namespace k2
0 commit comments