Handle rbx

This commit is contained in:
Théophile Bastian 2018-06-22 09:14:56 +02:00
parent cd9ecafb4f
commit 12e749f542
6 changed files with 40 additions and 5 deletions

View file

@ -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);

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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&);