#ifndef ELF_HPP #define ELF_HPP #include "utils/common.hpp" #include "utils/utils.hpp" #if IS_LINUX #include #include #include namespace cpptrace { namespace detail { class elf { file_wrapper file; std::string object_path; bool is_little_endian; bool is_64; struct header_info { uint64_t e_phoff; uint32_t e_phnum; uint32_t e_phentsize; uint64_t e_shoff; uint32_t e_shnum; uint32_t e_shentsize; }; bool tried_to_load_header = false; optional header; struct section_info { uint32_t sh_type; uint64_t sh_addr; uint64_t sh_offset; uint64_t sh_size; uint64_t sh_entsize; uint32_t sh_link; }; bool tried_to_load_sections = false; bool did_load_sections = false; std::vector sections; struct strtab_entry { bool tried_to_load_strtab = false; bool did_load_strtab = false; std::vector data; }; std::unordered_map strtab_entries; struct symtab_entry { uint32_t st_name; unsigned char st_info; unsigned char st_other; uint16_t st_shndx; uint64_t st_value; uint64_t st_size; }; struct symtab_info { std::vector entries; std::size_t strtab_link = 0; }; bool tried_to_load_symtab = false; bool did_load_symtab = false; symtab_info symtab; elf(file_wrapper file, const std::string& object_path, bool is_little_endian, bool is_64); public: static NODISCARD Result open_elf(const std::string& object_path); public: Result get_module_image_base(); private: template Result get_module_image_base_impl(); public: std::string lookup_symbol(frame_ptr pc); private: template::value, int>::type = 0> T byteswap_if_needed(T value, bool elf_is_little); Result get_header_info(); template Result get_header_info_impl(); Result&, internal_error> get_sections(); template Result&, internal_error> get_sections_impl(); Result&, internal_error> get_strtab(std::size_t index); Result get_symtab(); template Result get_symtab_impl(); }; } } #endif #endif