SimpleDwarf, DwarfReader: fix machine registers
This commit is contained in:
parent
dc6072e991
commit
d13b625cc5
4 changed files with 35 additions and 17 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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&);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue