SimpleDwarf, DwarfReader: fix machine registers

This commit is contained in:
Théophile Bastian 2018-04-23 16:46:03 +02:00
parent dc6072e991
commit d13b625cc5
4 changed files with 35 additions and 17 deletions

View file

@ -32,6 +32,8 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const {
output.end_ip = fde.get_low_pc() + fde.get_func_length();
auto rows = fde.decode().rows;
const core::Cie& cie = *fde.find_cie();
int ra_reg = cie.get_return_address_register_rule();
for(const auto row_pair: rows) {
SimpleDwarf::DwRow cur_row;
@ -47,22 +49,29 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const {
else {
try {
SimpleDwarf::MachineRegister reg_type =
from_dwarfpp_reg(cell.first);
cur_row.regs[reg_type] = read_register(cell.second);
from_dwarfpp_reg(cell.first, ra_reg);
switch(reg_type) {
case SimpleDwarf::REG_RBP:
cur_row.rbp = read_register(cell.second);
break;
case SimpleDwarf::REG_RA:
cur_row.ra = read_register(cell.second);
break;
default:
break;
}
}
catch(UnsupportedRegister) {} // Just ignore it.
}
}
if(cur_row.cfa.type == SimpleDwarf::DwRegister::REG_UNDEFINED
|| (cur_row.regs[SimpleDwarf::REG_RIP].type
== SimpleDwarf::DwRegister::REG_UNDEFINED)
|| (cur_row.regs[SimpleDwarf::REG_RSP].type
== SimpleDwarf::DwRegister::REG_UNDEFINED))
if(cur_row.cfa.type == SimpleDwarf::DwRegister::REG_UNDEFINED)
{
// Not set
throw InvalidDwarf();
}
output.rows.push_back(cur_row);
}
return output;
@ -101,7 +110,13 @@ SimpleDwarf::DwRegister DwarfReader::read_register(
return output;
}
SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(int reg_id) const {
SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(
int reg_id,
int ra_reg
) const
{
if(reg_id == ra_reg)
return SimpleDwarf::REG_RA;
switch(reg_id) {
case lib::DWARF_X86_64_RIP:
return SimpleDwarf::REG_RIP;

View file

@ -29,7 +29,10 @@ class DwarfReader {
SimpleDwarf::DwRegister read_register(
const dwarf::core::FrameSection::register_def& reg) const;
SimpleDwarf::MachineRegister from_dwarfpp_reg(int reg_id) const;
SimpleDwarf::MachineRegister from_dwarfpp_reg(
int reg_id,
int ra_reg=-1
) const;
class UnsupportedRegister: public std::exception {};

View file

@ -30,12 +30,12 @@ std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRegister& reg)
break;
case SimpleDwarf::DwRegister::REG_REGISTER:
out << reg.reg
<< ((reg.offset >= 0) ? '+' : '-')
<< ((reg.offset >= 0) ? "+" : "")
<< reg.offset;
break;
case SimpleDwarf::DwRegister::REG_CFA_OFFSET:
out << 'c'
<< ((reg.offset >= 0) ? '+' : '-')
<< ((reg.offset >= 0) ? "+" : "")
<< reg.offset;
break;
case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED:
@ -47,10 +47,9 @@ std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRegister& reg)
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];
}
<< '\t' << row.cfa
<< '\t' << row.rbp
<< '\t' << row.ra;
out << std::endl;
return out;
}
@ -59,7 +58,7 @@ 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"
<< "IP\tCFA\tRBP\tRA"
<< std::endl;
for(const auto& row: fde.rows)
out << row;

View file

@ -43,7 +43,8 @@ struct SimpleDwarf {
struct DwRow {
uintptr_t ip; ///< Instruction pointer
DwRegister cfa; ///< Canonical Frame Address
DwRegister regs[HANDLED_REGISTERS_COUNT]; ///< Saved machine registers
DwRegister rbp; ///< Base pointer register
DwRegister ra; ///< Return address
friend std::ostream& operator<<(std::ostream &, const DwRow&);
};