#pragma once #include #include #include #include #include #include #include #include #include #define OF_WHAT_EXCEPTION(cl_name) \ cl_name: public WhatException { \ public:\ cl_name(const std::string& what): WhatException(what) {} \ cl_name() = default; \ } class DwarfInterpret { /** Singleton class holding a Dwarf interpret. * Must be first instanciated with the path to the binary being run, with a * call to `instanciate`, and can afterwards be accessed with calls to * `acquire`. */ public: class WhatException: public std::exception { /** Base exception for other exceptions, not supposed to be thrown * by itself */ std::string what_str; public: WhatException(const std::string& what): what_str(what) {} WhatException(): what_str("") {} const char* what() const noexcept { return what_str.c_str(); } }; class OF_WHAT_EXCEPTION(NotInstanciated); class OF_WHAT_EXCEPTION(AlreadyInstanciated); class OF_WHAT_EXCEPTION(ValuelessRegister); class OF_WHAT_EXCEPTION(NotImplemented); class OF_WHAT_EXCEPTION(FailedGetContext); class OF_WHAT_EXCEPTION(NotFound); typedef dwarf::core::FrameSection::register_def DwarfRegister; typedef std::set > DwarfRow; // FIXME typedef uintptr_t reg_content_t; private: //typedef std::set > DwarfRow; public: DwarfInterpret(DwarfInterpret const&) = delete; void operator=(DwarfInterpret const&) = delete; static DwarfInterpret& acquire(); static DwarfInterpret& instanciate(const std::string& elf_path); int get_elf_machine() const { return elf_machine; } reg_content_t interpret_dw_register( const DwarfRow& row, const DwarfRegister& reg ) const; reg_content_t interpret_dw_register( const DwarfRow& row, int reg_id ) const; uintptr_t get_return_address(uintptr_t cur_pc) const; uintptr_t get_self_return_address() const; static uintptr_t get_current_pc(); private: DwarfInterpret(const std::string& elf_path); DwarfRegister get_column(const DwarfRow& row, int column) const; reg_content_t get_cpu_register(int reg_id) const; const dwarf::core::FrameSection::fde_iterator fde_at( uintptr_t pc) const; const dwarf::core::FrameSection::cie_iterator cie_at( uintptr_t pc) const; const DwarfRow& dwarf_row_at(uintptr_t pc) const; uintptr_t get_caller_pc() const; private: // members static std::unique_ptr instance; dwarf::core::root_die root_die; int elf_machine; friend class std::unique_ptr; };