SimpleDwarf: add pretty-printing operator<<
This commit is contained in:
parent
13e3647629
commit
8bf2e1e49d
2 changed files with 102 additions and 8 deletions
70
src/SimpleDwarf.cpp
Normal file
70
src/SimpleDwarf.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#include "SimpleDwarf.hpp"
|
||||||
|
|
||||||
|
static std::ostream& operator<<(
|
||||||
|
std::ostream& out,
|
||||||
|
SimpleDwarf::MachineRegister reg)
|
||||||
|
{
|
||||||
|
switch(reg) {
|
||||||
|
case SimpleDwarf::REG_RIP:
|
||||||
|
out << "rip";
|
||||||
|
break;
|
||||||
|
case SimpleDwarf::REG_RSP:
|
||||||
|
out << "rsp";
|
||||||
|
break;
|
||||||
|
case SimpleDwarf::REG_RBP:
|
||||||
|
out << "rbp";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRegister& reg)
|
||||||
|
{
|
||||||
|
switch(reg.type) {
|
||||||
|
case SimpleDwarf::DwRegister::REG_UNDEFINED:
|
||||||
|
out << "u";
|
||||||
|
break;
|
||||||
|
case SimpleDwarf::DwRegister::REG_REGISTER:
|
||||||
|
out << reg.reg
|
||||||
|
<< ((reg.offset >= 0) ? '+' : '-')
|
||||||
|
<< reg.offset;
|
||||||
|
break;
|
||||||
|
case SimpleDwarf::DwRegister::REG_CFA_OFFSET:
|
||||||
|
out << 'c'
|
||||||
|
<< ((reg.offset >= 0) ? '+' : '-')
|
||||||
|
<< reg.offset;
|
||||||
|
break;
|
||||||
|
case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED:
|
||||||
|
out << 'X';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRow& row) {
|
||||||
|
out << std::hex << row.ip << std::dec
|
||||||
|
<< '\t' << row.cfa;
|
||||||
|
for(size_t r_id = 0; r_id < SimpleDwarf::HANDLED_REGISTERS_COUNT; ++r_id) {
|
||||||
|
out << '\t' << row.regs[r_id];
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf::Fde& fde) {
|
||||||
|
out << "FDE: "
|
||||||
|
<< std::hex << fde.beg_ip << " … " << fde.end_ip << std::dec
|
||||||
|
<< std::endl
|
||||||
|
<< "IP\tCFA\tRIP\tRSP\tRBP\tRA"
|
||||||
|
<< std::endl;
|
||||||
|
for(const auto& row: fde.rows)
|
||||||
|
out << row;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf& dwarf) {
|
||||||
|
for(const auto& fde: dwarf.fde_list)
|
||||||
|
out << fde << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
|
@ -8,13 +8,15 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector> // We only need linear swipes, no need for anything fancier
|
#include <vector> // We only need linear swipes, no need for anything fancier
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
struct SimpleDwarf {
|
struct SimpleDwarf {
|
||||||
/** A machine register (eg. %rip) among the supported ones (x86_64 only
|
/** A machine register (eg. %rip) among the supported ones (x86_64 only
|
||||||
* for now) */
|
* for now) */
|
||||||
static const std::size_t HANDLED_REGISTERS_COUNT = 3;
|
static const std::size_t HANDLED_REGISTERS_COUNT = 4;
|
||||||
enum MachineRegister {
|
enum MachineRegister {
|
||||||
REG_RIP, REG_RSP, REG_RBP
|
REG_RIP, REG_RSP, REG_RBP,
|
||||||
|
REG_RA ///< A bit of cheating: not a machine register
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DwRegister {
|
struct DwRegister {
|
||||||
|
@ -34,18 +36,40 @@ struct SimpleDwarf {
|
||||||
Type type; ///< Type of this register
|
Type type; ///< Type of this register
|
||||||
uintptr_t offset; ///< Offset from the expression, if applicable
|
uintptr_t offset; ///< Offset from the expression, if applicable
|
||||||
MachineRegister reg; ///< Machine register implied, if applicable
|
MachineRegister reg; ///< Machine register implied, if applicable
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream &, const DwRegister&);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DwRow {
|
struct DwRow {
|
||||||
uintptr_t ip;
|
uintptr_t ip; ///< Instruction pointer
|
||||||
DwRegister cfa;
|
DwRegister cfa; ///< Canonical Frame Address
|
||||||
DwRegister regs[HANDLED_REGISTERS_COUNT];
|
DwRegister regs[HANDLED_REGISTERS_COUNT]; ///< Saved machine registers
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream &, const DwRow&);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Fde {
|
struct Fde {
|
||||||
uintptr_t beg_ip, end_ip;
|
uintptr_t beg_ip, ///< This FDE's start instruction pointer
|
||||||
std::vector<DwRow> rows;
|
end_ip; ///< This FDE's end instruction pointer
|
||||||
|
std::vector<DwRow> rows; ///< Dwarf rows for this FDE
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream &, const Fde&);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Fde> fde_list;
|
std::vector<Fde> fde_list; ///< List of FDEs in this Dwarf
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream &, const SimpleDwarf&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Dumps this object to `out`
|
||||||
|
std::ostream& operator<<(std::ostream& out,
|
||||||
|
const SimpleDwarf::DwRegister& reg);
|
||||||
|
|
||||||
|
/// Dumps this object to `out`
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRow& reg);
|
||||||
|
|
||||||
|
/// Dumps this object to `out`
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf::Fde& reg);
|
||||||
|
|
||||||
|
/// Dumps this object to `out`
|
||||||
|
std::ostream& operator<<(std::ostream& out, const SimpleDwarf& reg);
|
||||||
|
|
Loading…
Reference in a new issue