Handle rbx
This commit is contained in:
parent
cd9ecafb4f
commit
12e749f542
6 changed files with 40 additions and 5 deletions
|
@ -4,13 +4,14 @@ typedef enum {
|
|||
UNWF_RIP=0,
|
||||
UNWF_RSP=1,
|
||||
UNWF_RBP=2,
|
||||
UNWF_RBX=3,
|
||||
|
||||
UNWF_ERROR=7
|
||||
} unwind_flags_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t flags;
|
||||
uintptr_t rip, rsp, rbp;
|
||||
uintptr_t rip, rsp, rbp, rbx;
|
||||
} unwind_context_t;
|
||||
|
||||
typedef uintptr_t (*deref_func_t)(uintptr_t);
|
||||
|
|
|
@ -83,9 +83,9 @@ void CodeGenerator::gen_unwind_func_header(const std::string& name) {
|
|||
|
||||
struct UnwFlags {
|
||||
UnwFlags():
|
||||
error(false), rip(false), rsp(false), rbp(false) {}
|
||||
error(false), rip(false), rsp(false), rbp(false), rbx(false) {}
|
||||
|
||||
bool error, rip, rsp, rbp;
|
||||
bool error, rip, rsp, rbp, rbx;
|
||||
|
||||
uint8_t to_uint8() const {
|
||||
uint8_t out = 0;
|
||||
|
@ -95,6 +95,8 @@ struct UnwFlags {
|
|||
out |= (1 << UNWF_RSP);
|
||||
if(rbp)
|
||||
out |= (1 << UNWF_RBP);
|
||||
if(rbx)
|
||||
out |= (1 << UNWF_RBX);
|
||||
if(error)
|
||||
out |= (1 << UNWF_ERROR);
|
||||
|
||||
|
@ -174,6 +176,12 @@ void CodeGenerator::gen_of_row(
|
|||
os << ';' << endl;
|
||||
}
|
||||
|
||||
if(check_reg_defined(row.rbx)) {
|
||||
flags.rbx = true;
|
||||
os << "\t\t\t" << "out_ctx.rbx = ";
|
||||
gen_of_reg(row.rbx);
|
||||
os << ';' << endl;
|
||||
}
|
||||
} catch(const UnhandledRegister& exn) {
|
||||
// This should not happen, since we check_reg_*, but heh.
|
||||
flags.error = true;
|
||||
|
@ -219,6 +227,8 @@ static const char* ctx_of_dw_name(SimpleDwarf::MachineRegister reg) {
|
|||
return "ctx.rsp";
|
||||
case SimpleDwarf::REG_RBP:
|
||||
return "ctx.rbp";
|
||||
case SimpleDwarf::REG_RBX:
|
||||
return "ctx.rbx";
|
||||
case SimpleDwarf::REG_RA:
|
||||
throw CodeGenerator::NotImplementedCase();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ static bool equiv_row(
|
|||
return r1.ip == r2.ip
|
||||
&& equiv_reg(r1.cfa, r2.cfa)
|
||||
&& equiv_reg(r1.rbp, r2.rbp)
|
||||
&& equiv_reg(r1.rbx, r2.rbx)
|
||||
&& equiv_reg(r1.ra, r2.ra);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const {
|
|||
case SimpleDwarf::REG_RBP:
|
||||
cur_row.rbp = read_register(cell.second);
|
||||
break;
|
||||
case SimpleDwarf::REG_RBX:
|
||||
cur_row.rbx = read_register(cell.second);
|
||||
break;
|
||||
case SimpleDwarf::REG_RA:
|
||||
cur_row.ra = read_register(cell.second);
|
||||
break;
|
||||
|
@ -130,6 +133,8 @@ SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(
|
|||
return SimpleDwarf::REG_RSP;
|
||||
case lib::DWARF_X86_64_RBP:
|
||||
return SimpleDwarf::REG_RBP;
|
||||
case lib::DWARF_X86_64_RBX:
|
||||
return SimpleDwarf::REG_RBX;
|
||||
default:
|
||||
throw UnsupportedRegister();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
#include "SimpleDwarf.hpp"
|
||||
#include "../shared/context_struct.h"
|
||||
|
||||
uint8_t SimpleDwarf::to_shared_flag(SimpleDwarf::MachineRegister mreg) {
|
||||
switch(mreg) {
|
||||
case REG_RIP: return (1 << UNWF_RIP);
|
||||
case REG_RSP: return (1 << UNWF_RSP);
|
||||
case REG_RBP: return (1 << UNWF_RBP);
|
||||
case REG_RBX: return (1 << UNWF_RBX);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static std::ostream& operator<<(
|
||||
std::ostream& out,
|
||||
|
@ -14,6 +25,9 @@ static std::ostream& operator<<(
|
|||
case SimpleDwarf::REG_RBP:
|
||||
out << "rbp";
|
||||
break;
|
||||
case SimpleDwarf::REG_RBX:
|
||||
out << "rbx";
|
||||
break;
|
||||
case SimpleDwarf::REG_RA:
|
||||
out << "RA";
|
||||
break;
|
||||
|
@ -49,6 +63,7 @@ std::ostream& operator<<(std::ostream& out, const SimpleDwarf::DwRow& row) {
|
|||
out << std::hex << row.ip << std::dec
|
||||
<< '\t' << row.cfa
|
||||
<< '\t' << row.rbp
|
||||
<< '\t' << row.rbx
|
||||
<< '\t' << row.ra;
|
||||
out << std::endl;
|
||||
return out;
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
struct SimpleDwarf {
|
||||
/** A machine register (eg. %rip) among the supported ones (x86_64 only
|
||||
* for now) */
|
||||
static const std::size_t HANDLED_REGISTERS_COUNT = 4;
|
||||
static const std::size_t HANDLED_REGISTERS_COUNT = 5;
|
||||
enum MachineRegister {
|
||||
REG_RIP, REG_RSP, REG_RBP,
|
||||
REG_RIP, REG_RSP, REG_RBP, REG_RBX,
|
||||
REG_RA ///< A bit of cheating: not a machine register
|
||||
};
|
||||
|
||||
static uint8_t to_shared_flag(MachineRegister mreg);
|
||||
|
||||
struct DwRegister {
|
||||
/** Holds a single Dwarf register value */
|
||||
|
||||
|
@ -44,6 +46,7 @@ struct SimpleDwarf {
|
|||
uintptr_t ip; ///< Instruction pointer
|
||||
DwRegister cfa; ///< Canonical Frame Address
|
||||
DwRegister rbp; ///< Base pointer register
|
||||
DwRegister rbx; ///< RBX, sometimes used for unwinding
|
||||
DwRegister ra; ///< Return address
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &, const DwRow&);
|
||||
|
|
Loading…
Reference in a new issue