From d893b9138ad721b0e2aeb67751bfa96d45db24d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Wed, 4 Apr 2018 14:42:27 +0200 Subject: [PATCH] Move header files to dwarfinterpret/ --- include/DwarfInterpret.hpp | 147 +----------------- include/dwarfinterpret/DwarfInterpret.hpp | 147 ++++++++++++++++++ {src => include/dwarfinterpret}/MemoryMap.hpp | 0 3 files changed, 149 insertions(+), 145 deletions(-) create mode 100644 include/dwarfinterpret/DwarfInterpret.hpp rename {src => include/dwarfinterpret}/MemoryMap.hpp (100%) diff --git a/include/DwarfInterpret.hpp b/include/DwarfInterpret.hpp index 5fb342e..22391b9 100644 --- a/include/DwarfInterpret.hpp +++ b/include/DwarfInterpret.hpp @@ -1,147 +1,4 @@ #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: // Types, sub-classes, … - class WhatException: public std::exception { - /** Base exception for other exceptions, not supposed to be thrown - * by itself */ - - std::string what_str; - - public: - /// Initialize the exception with an explanatory text chunk - explicit WhatException(const std::string& what) - : what_str(what) {} - - /// Leave the explanatory text empty - WhatException(): what_str("") {} - - /// Get the explanatory text for this exception - const char* what() const noexcept { - return what_str.c_str(); - } - }; - - - /// Thrown when `acquire` is called before `instanciate` - class OF_WHAT_EXCEPTION(NotInstanciated); - - /// Thrown when `instanciate` is called twice - class OF_WHAT_EXCEPTION(AlreadyInstanciated); - - /** Thrown when trying to get the value of a Dwarf register (column) - * that is not defined or has, somehow, no value at this PC. */ - class OF_WHAT_EXCEPTION(ValuelessRegister); - - /// Thrown when accessing unimplemented parts of this library - class OF_WHAT_EXCEPTION(NotImplemented); - - /// Thrown when somehow, getcontext (read CPU registers) fails - class OF_WHAT_EXCEPTION(FailedGetContext); - - /// Thrown when a Dwarf element is not found for a given PC - class OF_WHAT_EXCEPTION(NotFound); - - - /// A Dwarf register - typedef dwarf::core::FrameSection::register_def DwarfRegister; - - /// A Dwarf row of registers (for a given PC) - typedef std::set > DwarfRow; - - /// The value type of a register's contents - typedef uintptr_t reg_content_t; - - public: // methods - DwarfInterpret(DwarfInterpret const&) = delete; - void operator=(DwarfInterpret const&) = delete; - - /** Acquire the instance of `DwarfInterpret`. The method #instanciate - * must have been called beforehand. - * - * \throws NotInstanciated whenever this condition is not met. - */ - static DwarfInterpret& acquire(); - - /** Instanciate the instance of DwarfInterpret with the path to the - * program currently running (usually, argv[0]) - * - * \throws AlreadyInstanciated if this method is called twice. */ - static DwarfInterpret& instanciate(const std::string& elf_path); - - /// Returns the ELF machine number for this ELF - int get_elf_machine() const { return elf_machine; } - - /** Retrieves the value pointed to by the given Dwarf register - * - * \throws ValuelessRegister */ - reg_content_t interpret_dw_register( - const DwarfRow& row, - const DwarfRegister& reg - ) const; - - /** Retrieves the value pointed to by the given Dwarf register - * - * \throws ValuelessRegister */ - reg_content_t interpret_dw_register( - const DwarfRow& row, - int reg_id - ) const; - - /** Get the return address at a given program counter, assuming the - * correct registers are stored */ - uintptr_t get_return_address(uintptr_t cur_pc) const; - - /** Get the return address of the current program point */ - uintptr_t get_self_return_address() const; - - /// Get the current program counter - 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; -}; +#include +#include diff --git a/include/dwarfinterpret/DwarfInterpret.hpp b/include/dwarfinterpret/DwarfInterpret.hpp new file mode 100644 index 0000000..5fb342e --- /dev/null +++ b/include/dwarfinterpret/DwarfInterpret.hpp @@ -0,0 +1,147 @@ +#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: // Types, sub-classes, … + class WhatException: public std::exception { + /** Base exception for other exceptions, not supposed to be thrown + * by itself */ + + std::string what_str; + + public: + /// Initialize the exception with an explanatory text chunk + explicit WhatException(const std::string& what) + : what_str(what) {} + + /// Leave the explanatory text empty + WhatException(): what_str("") {} + + /// Get the explanatory text for this exception + const char* what() const noexcept { + return what_str.c_str(); + } + }; + + + /// Thrown when `acquire` is called before `instanciate` + class OF_WHAT_EXCEPTION(NotInstanciated); + + /// Thrown when `instanciate` is called twice + class OF_WHAT_EXCEPTION(AlreadyInstanciated); + + /** Thrown when trying to get the value of a Dwarf register (column) + * that is not defined or has, somehow, no value at this PC. */ + class OF_WHAT_EXCEPTION(ValuelessRegister); + + /// Thrown when accessing unimplemented parts of this library + class OF_WHAT_EXCEPTION(NotImplemented); + + /// Thrown when somehow, getcontext (read CPU registers) fails + class OF_WHAT_EXCEPTION(FailedGetContext); + + /// Thrown when a Dwarf element is not found for a given PC + class OF_WHAT_EXCEPTION(NotFound); + + + /// A Dwarf register + typedef dwarf::core::FrameSection::register_def DwarfRegister; + + /// A Dwarf row of registers (for a given PC) + typedef std::set > DwarfRow; + + /// The value type of a register's contents + typedef uintptr_t reg_content_t; + + public: // methods + DwarfInterpret(DwarfInterpret const&) = delete; + void operator=(DwarfInterpret const&) = delete; + + /** Acquire the instance of `DwarfInterpret`. The method #instanciate + * must have been called beforehand. + * + * \throws NotInstanciated whenever this condition is not met. + */ + static DwarfInterpret& acquire(); + + /** Instanciate the instance of DwarfInterpret with the path to the + * program currently running (usually, argv[0]) + * + * \throws AlreadyInstanciated if this method is called twice. */ + static DwarfInterpret& instanciate(const std::string& elf_path); + + /// Returns the ELF machine number for this ELF + int get_elf_machine() const { return elf_machine; } + + /** Retrieves the value pointed to by the given Dwarf register + * + * \throws ValuelessRegister */ + reg_content_t interpret_dw_register( + const DwarfRow& row, + const DwarfRegister& reg + ) const; + + /** Retrieves the value pointed to by the given Dwarf register + * + * \throws ValuelessRegister */ + reg_content_t interpret_dw_register( + const DwarfRow& row, + int reg_id + ) const; + + /** Get the return address at a given program counter, assuming the + * correct registers are stored */ + uintptr_t get_return_address(uintptr_t cur_pc) const; + + /** Get the return address of the current program point */ + uintptr_t get_self_return_address() const; + + /// Get the current program counter + 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; +}; diff --git a/src/MemoryMap.hpp b/include/dwarfinterpret/MemoryMap.hpp similarity index 100% rename from src/MemoryMap.hpp rename to include/dwarfinterpret/MemoryMap.hpp