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_RIP=0,
|
||||||
UNWF_RSP=1,
|
UNWF_RSP=1,
|
||||||
UNWF_RBP=2,
|
UNWF_RBP=2,
|
||||||
|
UNWF_RBX=3,
|
||||||
|
|
||||||
UNWF_ERROR=7
|
UNWF_ERROR=7
|
||||||
} unwind_flags_t;
|
} unwind_flags_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uintptr_t rip, rsp, rbp;
|
uintptr_t rip, rsp, rbp, rbx;
|
||||||
} unwind_context_t;
|
} unwind_context_t;
|
||||||
|
|
||||||
typedef uintptr_t (*deref_func_t)(uintptr_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 {
|
struct UnwFlags {
|
||||||
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 to_uint8() const {
|
||||||
uint8_t out = 0;
|
uint8_t out = 0;
|
||||||
|
@ -95,6 +95,8 @@ struct UnwFlags {
|
||||||
out |= (1 << UNWF_RSP);
|
out |= (1 << UNWF_RSP);
|
||||||
if(rbp)
|
if(rbp)
|
||||||
out |= (1 << UNWF_RBP);
|
out |= (1 << UNWF_RBP);
|
||||||
|
if(rbx)
|
||||||
|
out |= (1 << UNWF_RBX);
|
||||||
if(error)
|
if(error)
|
||||||
out |= (1 << UNWF_ERROR);
|
out |= (1 << UNWF_ERROR);
|
||||||
|
|
||||||
|
@ -174,6 +176,12 @@ void CodeGenerator::gen_of_row(
|
||||||
os << ';' << endl;
|
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) {
|
} catch(const UnhandledRegister& exn) {
|
||||||
// This should not happen, since we check_reg_*, but heh.
|
// This should not happen, since we check_reg_*, but heh.
|
||||||
flags.error = true;
|
flags.error = true;
|
||||||
|
@ -219,6 +227,8 @@ static const char* ctx_of_dw_name(SimpleDwarf::MachineRegister reg) {
|
||||||
return "ctx.rsp";
|
return "ctx.rsp";
|
||||||
case SimpleDwarf::REG_RBP:
|
case SimpleDwarf::REG_RBP:
|
||||||
return "ctx.rbp";
|
return "ctx.rbp";
|
||||||
|
case SimpleDwarf::REG_RBX:
|
||||||
|
return "ctx.rbx";
|
||||||
case SimpleDwarf::REG_RA:
|
case SimpleDwarf::REG_RA:
|
||||||
throw CodeGenerator::NotImplementedCase();
|
throw CodeGenerator::NotImplementedCase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ static bool equiv_row(
|
||||||
return r1.ip == r2.ip
|
return r1.ip == r2.ip
|
||||||
&& equiv_reg(r1.cfa, r2.cfa)
|
&& equiv_reg(r1.cfa, r2.cfa)
|
||||||
&& equiv_reg(r1.rbp, r2.rbp)
|
&& equiv_reg(r1.rbp, r2.rbp)
|
||||||
|
&& equiv_reg(r1.rbx, r2.rbx)
|
||||||
&& equiv_reg(r1.ra, r2.ra);
|
&& equiv_reg(r1.ra, r2.ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const {
|
||||||
case SimpleDwarf::REG_RBP:
|
case SimpleDwarf::REG_RBP:
|
||||||
cur_row.rbp = read_register(cell.second);
|
cur_row.rbp = read_register(cell.second);
|
||||||
break;
|
break;
|
||||||
|
case SimpleDwarf::REG_RBX:
|
||||||
|
cur_row.rbx = read_register(cell.second);
|
||||||
|
break;
|
||||||
case SimpleDwarf::REG_RA:
|
case SimpleDwarf::REG_RA:
|
||||||
cur_row.ra = read_register(cell.second);
|
cur_row.ra = read_register(cell.second);
|
||||||
break;
|
break;
|
||||||
|
@ -130,6 +133,8 @@ SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(
|
||||||
return SimpleDwarf::REG_RSP;
|
return SimpleDwarf::REG_RSP;
|
||||||
case lib::DWARF_X86_64_RBP:
|
case lib::DWARF_X86_64_RBP:
|
||||||
return SimpleDwarf::REG_RBP;
|
return SimpleDwarf::REG_RBP;
|
||||||
|
case lib::DWARF_X86_64_RBX:
|
||||||
|
return SimpleDwarf::REG_RBX;
|
||||||
default:
|
default:
|
||||||
throw UnsupportedRegister();
|
throw UnsupportedRegister();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
#include "SimpleDwarf.hpp"
|
#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<<(
|
static std::ostream& operator<<(
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
|
@ -14,6 +25,9 @@ static std::ostream& operator<<(
|
||||||
case SimpleDwarf::REG_RBP:
|
case SimpleDwarf::REG_RBP:
|
||||||
out << "rbp";
|
out << "rbp";
|
||||||
break;
|
break;
|
||||||
|
case SimpleDwarf::REG_RBX:
|
||||||
|
out << "rbx";
|
||||||
|
break;
|
||||||
case SimpleDwarf::REG_RA:
|
case SimpleDwarf::REG_RA:
|
||||||
out << "RA";
|
out << "RA";
|
||||||
break;
|
break;
|
||||||
|
@ -49,6 +63,7 @@ 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
|
||||||
<< '\t' << row.rbp
|
<< '\t' << row.rbp
|
||||||
|
<< '\t' << row.rbx
|
||||||
<< '\t' << row.ra;
|
<< '\t' << row.ra;
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -13,12 +13,14 @@
|
||||||
struct SimpleDwarf {
|
struct SimpleDwarf {
|
||||||
/** A machine register (eg. %rip) among the supported ones (x86_64 only
|
/** A machine register (eg. %rip) among the supported ones (x86_64 only
|
||||||
* for now) */
|
* for now) */
|
||||||
static const std::size_t HANDLED_REGISTERS_COUNT = 4;
|
static const std::size_t HANDLED_REGISTERS_COUNT = 5;
|
||||||
enum MachineRegister {
|
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
|
REG_RA ///< A bit of cheating: not a machine register
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint8_t to_shared_flag(MachineRegister mreg);
|
||||||
|
|
||||||
struct DwRegister {
|
struct DwRegister {
|
||||||
/** Holds a single Dwarf register value */
|
/** Holds a single Dwarf register value */
|
||||||
|
|
||||||
|
@ -44,6 +46,7 @@ struct SimpleDwarf {
|
||||||
uintptr_t ip; ///< Instruction pointer
|
uintptr_t ip; ///< Instruction pointer
|
||||||
DwRegister cfa; ///< Canonical Frame Address
|
DwRegister cfa; ///< Canonical Frame Address
|
||||||
DwRegister rbp; ///< Base pointer register
|
DwRegister rbp; ///< Base pointer register
|
||||||
|
DwRegister rbx; ///< RBX, sometimes used for unwinding
|
||||||
DwRegister ra; ///< Return address
|
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