diff --git a/src/DwarfReader.cpp b/src/DwarfReader.cpp index c6a6858..1573cb6 100644 --- a/src/DwarfReader.cpp +++ b/src/DwarfReader.cpp @@ -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; diff --git a/src/DwarfReader.hpp b/src/DwarfReader.hpp index 0d4505c..034d055 100644 --- a/src/DwarfReader.hpp +++ b/src/DwarfReader.hpp @@ -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 {}; diff --git a/src/SimpleDwarf.cpp b/src/SimpleDwarf.cpp index 350fbde..c556734 100644 --- a/src/SimpleDwarf.cpp +++ b/src/SimpleDwarf.cpp @@ -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; diff --git a/src/SimpleDwarf.hpp b/src/SimpleDwarf.hpp index 5110110..67158f1 100644 --- a/src/SimpleDwarf.hpp +++ b/src/SimpleDwarf.hpp @@ -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&); };