Théophile Bastian
bf8864e7e6
Doesn't work for now: still have to take into account the memory map offsets.
106 lines
3.1 KiB
C++
106 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <memory>
|
|
#include <cstdint>
|
|
|
|
#include <dwarfpp/lib.hpp>
|
|
#include <dwarfpp/regs.hpp>
|
|
#include <dwarfpp/frame.hpp>
|
|
#include <dwarfpp/attr.hpp>
|
|
#include <dwarfpp/frame.hpp>
|
|
#include <dwarfpp/root.hpp>
|
|
|
|
#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<std::pair<int, DwarfRegister> > DwarfRow; // FIXME
|
|
|
|
typedef uintptr_t reg_content_t;
|
|
|
|
private:
|
|
//typedef std::set<std::pair<int, DwarfRegister> > 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<DwarfInterpret> instance;
|
|
|
|
dwarf::core::root_die root_die;
|
|
int elf_machine;
|
|
|
|
friend class std::unique_ptr<DwarfInterpret>;
|
|
};
|