Skip to content

Commit 82d7186

Browse files
authored
[k2] add k2 resolve symbol (#1325)
1 parent add0757 commit 82d7186

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

runtime-light/k2-platform/k2-api.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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

2829
inline constexpr int32_t errno_ok = 0;
2930
inline 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

3135
inline 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

runtime-light/k2-platform/k2-header.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,51 @@ uint32_t k2_env_value_len(uint32_t env_num);
436436
*/
437437
void k2_env_fetch(uint32_t env_num, char* key, char* value);
438438

439+
// diagnostic functions for instance debugging
440+
441+
/**
442+
* Return symbol name's len that overlaps address
443+
* @param `addr` pointer to code instruction
444+
* @param `name_len` buffer where symbol name's len will be written
445+
* @return: `0` on success, `errno != 0` otherwise
446+
* `errno` options:
447+
* `EINVAL` => `addr` symbol can't be resolved
448+
* `ENODATA` => there is no debug information for the image
449+
* `EFAULT` => attempt to dereference a nullptr
450+
*/
451+
int32_t k2_symbol_name_len(const void* addr, size_t* name_len);
452+
453+
/**
454+
* Return symbol filename's len
455+
* @param `addr` pointer to code instruction
456+
* @param `filename_len` buffer where symbol filename's will be written
457+
* @return: `0` on success, `errno != 0` otherwise
458+
* `errno` options:
459+
* `EINVAL` => `addr` symbol can't be resolved
460+
* `ENODATA` => there is no debug information for the image
461+
* `EFAULT` => attempt to dereference a nullptr
462+
*/
463+
int32_t k2_symbol_filename_len(const void* addr, size_t* filename_len);
464+
465+
struct SymbolInfo {
466+
char* name;
467+
char* filename;
468+
uint32_t lineno;
469+
};
470+
471+
/**
472+
* Returns information about the symbol that overlaps addr and it's position in source code.
473+
* Note: name and filename in symbol_info are **not** null-terminated.
474+
* @param `addr` pointer to code instruction
475+
* @param `symbol_info` structure stores buffers where the name and file name will be written. The buffer
476+
* lens must staisfy `name_len >= k2_symbol_name_len and filename_len >= k2_symbol_filename_len`
477+
* `errno` options:
478+
* `EINVAL` => `addr` symbol can't be resolved
479+
* `ENODATA` => there is no debug information for the image
480+
* `EFAULT` => attempt to dereference a nullptr
481+
*/
482+
int32_t k2_resolve_symbol(const void* addr, struct SymbolInfo* symbol_info);
483+
439484
// ---- libc analogues, designed to work instance-local ----
440485

441486
/**

0 commit comments

Comments
 (0)