Add in-code documentation and Doxygen settings
This commit is contained in:
parent
bf8864e7e6
commit
ea7405e3ba
5 changed files with 2548 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -28,3 +28,4 @@
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
|
docs
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -25,3 +25,8 @@ $(TARGET): $(OBJS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) $(TARGET)
|
rm -f $(OBJS) $(TARGET)
|
||||||
|
|
||||||
|
docs:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
|
11
README.md
11
README.md
|
@ -8,4 +8,13 @@ Allows the evaluation of a Dwarf register value of self at runtime. Useful for
|
||||||
manual stack unwind, in the absence of a base pointer.
|
manual stack unwind, in the absence of a base pointer.
|
||||||
|
|
||||||
|
|
||||||
**WIP**, to be documented.
|
**WIP**, the documentation is probably not awesome.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
To generate the documentation, make sure you have Doxygen installed on your
|
||||||
|
computer, then run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docs
|
||||||
|
```
|
||||||
|
|
|
@ -25,7 +25,7 @@ class DwarfInterpret {
|
||||||
* `acquire`.
|
* `acquire`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public:
|
public: // Types, sub-classes, …
|
||||||
class WhatException: public std::exception {
|
class WhatException: public std::exception {
|
||||||
/** Base exception for other exceptions, not supposed to be thrown
|
/** Base exception for other exceptions, not supposed to be thrown
|
||||||
* by itself */
|
* by itself */
|
||||||
|
@ -33,52 +33,93 @@ class DwarfInterpret {
|
||||||
std::string what_str;
|
std::string what_str;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WhatException(const std::string& what): what_str(what) {}
|
/// 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("") {}
|
WhatException(): what_str("") {}
|
||||||
|
|
||||||
|
/// Get the explanatory text for this exception
|
||||||
const char* what() const noexcept {
|
const char* what() const noexcept {
|
||||||
return what_str.c_str();
|
return what_str.c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Thrown when `acquire` is called before `instanciate`
|
||||||
class OF_WHAT_EXCEPTION(NotInstanciated);
|
class OF_WHAT_EXCEPTION(NotInstanciated);
|
||||||
|
|
||||||
|
/// Thrown when `instanciate` is called twice
|
||||||
class OF_WHAT_EXCEPTION(AlreadyInstanciated);
|
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);
|
class OF_WHAT_EXCEPTION(ValuelessRegister);
|
||||||
|
|
||||||
|
/// Thrown when accessing unimplemented parts of this library
|
||||||
class OF_WHAT_EXCEPTION(NotImplemented);
|
class OF_WHAT_EXCEPTION(NotImplemented);
|
||||||
|
|
||||||
|
/// Thrown when somehow, getcontext (read CPU registers) fails
|
||||||
class OF_WHAT_EXCEPTION(FailedGetContext);
|
class OF_WHAT_EXCEPTION(FailedGetContext);
|
||||||
|
|
||||||
|
/// Thrown when a Dwarf element is not found for a given PC
|
||||||
class OF_WHAT_EXCEPTION(NotFound);
|
class OF_WHAT_EXCEPTION(NotFound);
|
||||||
|
|
||||||
typedef dwarf::core::FrameSection::register_def DwarfRegister;
|
|
||||||
typedef std::set<std::pair<int, DwarfRegister> > DwarfRow; // FIXME
|
|
||||||
|
|
||||||
|
/// A Dwarf register
|
||||||
|
typedef dwarf::core::FrameSection::register_def DwarfRegister;
|
||||||
|
|
||||||
|
/// A Dwarf row of registers (for a given PC)
|
||||||
|
typedef std::set<std::pair<int, DwarfRegister> > DwarfRow;
|
||||||
|
|
||||||
|
/// The value type of a register's contents
|
||||||
typedef uintptr_t reg_content_t;
|
typedef uintptr_t reg_content_t;
|
||||||
|
|
||||||
private:
|
public: // methods
|
||||||
//typedef std::set<std::pair<int, DwarfRegister> > DwarfRow;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
DwarfInterpret(DwarfInterpret const&) = delete;
|
DwarfInterpret(DwarfInterpret const&) = delete;
|
||||||
void operator=(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();
|
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);
|
static DwarfInterpret& instanciate(const std::string& elf_path);
|
||||||
|
|
||||||
|
/// Returns the ELF machine number for this ELF
|
||||||
int get_elf_machine() const { return elf_machine; }
|
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(
|
reg_content_t interpret_dw_register(
|
||||||
const DwarfRow& row,
|
const DwarfRow& row,
|
||||||
const DwarfRegister& reg
|
const DwarfRegister& reg
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
/** Retrieves the value pointed to by the given Dwarf register
|
||||||
|
*
|
||||||
|
* \throws ValuelessRegister */
|
||||||
reg_content_t interpret_dw_register(
|
reg_content_t interpret_dw_register(
|
||||||
const DwarfRow& row,
|
const DwarfRow& row,
|
||||||
int reg_id
|
int reg_id
|
||||||
) const;
|
) 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;
|
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;
|
uintptr_t get_self_return_address() const;
|
||||||
|
|
||||||
|
/// Get the current program counter
|
||||||
static uintptr_t get_current_pc();
|
static uintptr_t get_current_pc();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue