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();
|
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;
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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&);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue