105 lines
3.2 KiB
C++
105 lines
3.2 KiB
C++
#include <inttypes.h>
|
|
#include <libelfin/dwarf/dwarf++.hh>
|
|
#include <libelfin/elf/elf++.hh>
|
|
|
|
#include "libelfin_wrap.h"
|
|
|
|
class LibelfinBinding
|
|
{
|
|
public:
|
|
LibelfinBinding(int fd, uintptr_t _loadoffset)
|
|
: elf(elf::create_mmap_loader(fd)),
|
|
dwarf(dwarf::elf::create_loader(this->elf)),
|
|
loadoffset(_loadoffset)
|
|
{
|
|
}
|
|
|
|
elf::elf elf;
|
|
dwarf::dwarf dwarf;
|
|
uintptr_t loadoffset;
|
|
};
|
|
|
|
DEBUGUS_EXTERNC void libelfin_wrap_get_funcs(PLibelfinBinding pbind, Funcs *funcs)
|
|
{
|
|
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
|
for (auto §ion : bind->elf.sections()) {
|
|
if (section.get_hdr().type == elf::sht::symtab) {
|
|
for (auto sym : section.as_symtab()) {
|
|
auto &d = sym.get_data();
|
|
if (d.type() == elf::stt::func) {
|
|
Func f = {
|
|
.name = (const char *)malloc(strlen(sym.get_name().c_str())+1),
|
|
.ai = libelfin_wrap_info_from_rip(pbind, (uintptr_t)d.value),
|
|
};
|
|
strcpy((char*)f.name, sym.get_name().c_str());
|
|
da_append(funcs, f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_line(PLibelfinBinding pbind, const char *file, size_t line)
|
|
{
|
|
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
|
for (auto &cu : bind->dwarf.compilation_units()) {
|
|
auto < = cu.get_line_table();
|
|
for (auto &ent : lt) {
|
|
if (ent.is_stmt && ent.line == line) {
|
|
AddrInfo *ai = (AddrInfo *)malloc(sizeof(*ai));
|
|
ai->addr = bind->loadoffset + (uintptr_t)ent.address;
|
|
ai->line = (ssize_t)line;
|
|
ai->file = (const char*)malloc(strlen(file)+1);
|
|
strcpy((char*)ai->file, file);
|
|
return ai;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
DEBUGUS_EXTERNC uintptr_t libelfin_wrap_func_addr(PLibelfinBinding pbind, Func *f)
|
|
{
|
|
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
|
return bind->loadoffset + f->ai->addr;
|
|
}
|
|
|
|
DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd, uintptr_t loadoffset)
|
|
{
|
|
return (PLibelfinBinding)new LibelfinBinding(fd, loadoffset);
|
|
}
|
|
|
|
DEBUGUS_EXTERNC void libelfin_wrap_free_binding(PLibelfinBinding pbind)
|
|
{
|
|
delete (LibelfinBinding *)pbind;
|
|
}
|
|
|
|
DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_rip(PLibelfinBinding pbind, uint64_t rip)
|
|
{
|
|
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
|
for (auto &cu : bind->dwarf.compilation_units()) {
|
|
if (die_pc_range(cu.root()).contains(rip)) {
|
|
auto < = cu.get_line_table();
|
|
auto it = lt.find_address(rip);
|
|
if (it == lt.end()) {
|
|
return NULL;
|
|
} else {
|
|
AddrInfo *ai = (AddrInfo *)malloc(sizeof(*ai));
|
|
ai->addr = rip;
|
|
ai->line = it->line;
|
|
ai->file = (const char*)malloc(strlen(it->file->path.c_str())+1);
|
|
strcpy((char*)ai->file, it->file->path.c_str());
|
|
return ai;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
DEBUGUS_EXTERNC void libelfin_wrap_free_info(AddrInfo *ai)
|
|
{
|
|
free((void*)ai->file);
|
|
free((void*)ai);
|
|
}
|
|
|