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(); output.end_ip = fde.get_low_pc() + fde.get_func_length();
auto rows = fde.decode().rows; 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) { for(const auto row_pair: rows) {
SimpleDwarf::DwRow cur_row; SimpleDwarf::DwRow cur_row;
@ -47,22 +49,29 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const {
else { else {
try { try {
SimpleDwarf::MachineRegister reg_type = SimpleDwarf::MachineRegister reg_type =
from_dwarfpp_reg(cell.first); from_dwarfpp_reg(cell.first, ra_reg);
cur_row.regs[reg_type] = read_register(cell.second); 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. catch(UnsupportedRegister) {} // Just ignore it.
} }
} }
if(cur_row.cfa.type == SimpleDwarf::DwRegister::REG_UNDEFINED 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))
{ {
// Not set // Not set
throw InvalidDwarf(); throw InvalidDwarf();
} }
output.rows.push_back(cur_row);
} }
return output; return output;
@ -101,7 +110,13 @@ SimpleDwarf::DwRegister DwarfReader::read_register(
return output; 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) { switch(reg_id) {
case lib::DWARF_X86_64_RIP: case lib::DWARF_X86_64_RIP:
return SimpleDwarf::REG_RIP; return SimpleDwarf::REG_RIP;

View file

@ -29,7 +29,10 @@ class DwarfReader {
SimpleDwarf::DwRegister read_register( SimpleDwarf::DwRegister read_register(
const dwarf::core::FrameSection::register_def& reg) const; 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 {}; class UnsupportedRegister: public std::exception {};

View file

@ -30,12 +30,12 @@ std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRegister& reg)
break; break;
case SimpleDwarf::DwRegister::REG_REGISTER: case SimpleDwarf::DwRegister::REG_REGISTER:
out << reg.reg out << reg.reg
<< ((reg.offset >= 0) ? '+' : '-') << ((reg.offset >= 0) ? "+" : "")
<< reg.offset; << reg.offset;
break; break;
case SimpleDwarf::DwRegister::REG_CFA_OFFSET: case SimpleDwarf::DwRegister::REG_CFA_OFFSET:
out << 'c' out << 'c'
<< ((reg.offset >= 0) ? '+' : '-') << ((reg.offset >= 0) ? "+" : "")
<< reg.offset; << reg.offset;
break; break;
case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED: 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) { std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRow& row) {
out << std::hex << row.ip << std::dec out << std::hex << row.ip << std::dec
<< '\t' << row.cfa; << '\t' << row.cfa
for(size_t r_id = 0; r_id < SimpleDwarf::HANDLED_REGISTERS_COUNT; ++r_id) { << '\t' << row.rbp
out << '\t' << row.regs[r_id]; << '\t' << row.ra;
}
out << std::endl; out << std::endl;
return out; return out;
} }
@ -59,7 +58,7 @@ std::ostream& operator<<(std::ostream& out, const SimpleDwarf::Fde& fde) {
out << "FDE: " out << "FDE: "
<< std::hex << fde.beg_ip << "" << fde.end_ip << std::dec << std::hex << fde.beg_ip << "" << fde.end_ip << std::dec
<< std::endl << std::endl
<< "IP\tCFA\tRIP\tRSP\tRBP\tRA" << "IP\tCFA\tRBP\tRA"
<< std::endl; << std::endl;
for(const auto& row: fde.rows) for(const auto& row: fde.rows)
out << row; out << row;

View file

@ -43,7 +43,8 @@ struct SimpleDwarf {
struct DwRow { struct DwRow {
uintptr_t ip; ///< Instruction pointer uintptr_t ip; ///< Instruction pointer
DwRegister cfa; ///< Canonical Frame Address 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&); friend std::ostream& operator<<(std::ostream &, const DwRow&);
}; };