Skip to content

Instantly share code, notes, and snippets.

@qookei
Created September 9, 2020 15:26
Show Gist options
  • Select an option

  • Save qookei/00f892cbaf026b1058e3e9ddd5f4ca4e to your computer and use it in GitHub Desktop.

Select an option

Save qookei/00f892cbaf026b1058e3e9ddd5f4ca4e to your computer and use it in GitHub Desktop.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <string_view>
#include <elf.h>
struct symbol {
std::string_view name;
uintptr_t base;
size_t size;
};
struct symbol_table {
symbol_table()
: symbols_{} {
[[gnu::weak]] extern char __ehdr_start[];
auto ehdr_addr = reinterpret_cast<uintptr_t>(&__ehdr_start);
auto ehdr = reinterpret_cast<Elf64_Ehdr *>(ehdr_addr);
if (!ehdr) return;
if (!ehdr->e_shnum) return;
Elf64_Shdr *symtab{}, *strtab{};
auto shdrs = reinterpret_cast<Elf64_Shdr *>(ehdr_addr + ehdr->e_shoff);
for (int i = 0; i < ehdr->e_shnum; i++) {
auto &shdr = shdrs[i];
if (!symtab && shdr.sh_type == SHT_SYMTAB)
symtab = &shdr;
if (!strtab && shdr.sh_type == SHT_STRTAB && i != ehdr->e_shstrndx)
strtab = &shdr;
}
size_t n_symbols = symtab->sh_size / symtab->sh_entsize;
symbols_.reserve(n_symbols);
for (size_t i = 0; i < n_symbols; i++) {
Elf64_Sym &sym = reinterpret_cast<Elf64_Sym *>(symtab->sh_addr)[i];
if ((sym.st_info & 0xf) != STT_FUNC)
continue;
symbols_.push_back({reinterpret_cast<char *>(strtab->sh_addr + sym.st_name), sym.st_value, sym.st_size});
}
}
std::vector<symbol> symbols_;
};
int main() {
symbol_table st;
for (auto &sym : st.symbols_) {
std::cout << sym.name << " " << std::hex << sym.base << " " << std::dec << sym.size << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment