forked from OSchip/llvm-project
Clean up the coding conventions in UnwindAssembly-x86.cpp a little bit.
I wrote this originally as a part of an unwind library that was using a different coding convention and some of that old style remained after its integration into lldb. llvm-svn: 216419
This commit is contained in:
parent
40e200eb69
commit
31e7191513
|
@ -27,12 +27,14 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
enum CPU {
|
||||
enum CPU
|
||||
{
|
||||
k_i386,
|
||||
k_x86_64
|
||||
};
|
||||
|
||||
enum i386_register_numbers {
|
||||
enum i386_register_numbers
|
||||
{
|
||||
k_machine_eax = 0,
|
||||
k_machine_ecx = 1,
|
||||
k_machine_edx = 2,
|
||||
|
@ -44,7 +46,8 @@ enum i386_register_numbers {
|
|||
k_machine_eip = 8
|
||||
};
|
||||
|
||||
enum x86_64_register_numbers {
|
||||
enum x86_64_register_numbers
|
||||
{
|
||||
k_machine_rax = 0,
|
||||
k_machine_rcx = 1,
|
||||
k_machine_rdx = 2,
|
||||
|
@ -64,13 +67,15 @@ enum x86_64_register_numbers {
|
|||
k_machine_rip = 16
|
||||
};
|
||||
|
||||
struct regmap_ent {
|
||||
struct regmap_ent
|
||||
{
|
||||
const char *name;
|
||||
int machine_regno;
|
||||
int lldb_regno;
|
||||
};
|
||||
|
||||
static struct regmap_ent i386_register_map[] = {
|
||||
static struct regmap_ent i386_register_map[] =
|
||||
{
|
||||
{"eax", k_machine_eax, -1},
|
||||
{"ecx", k_machine_ecx, -1},
|
||||
{"edx", k_machine_edx, -1},
|
||||
|
@ -82,11 +87,12 @@ static struct regmap_ent i386_register_map[] = {
|
|||
{"eip", k_machine_eip, -1}
|
||||
};
|
||||
|
||||
const int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent);
|
||||
const int size_of_i386_register_map = llvm::array_lengthof (i386_register_map);
|
||||
|
||||
static int i386_register_map_initialized = 0;
|
||||
|
||||
static struct regmap_ent x86_64_register_map[] = {
|
||||
static struct regmap_ent x86_64_register_map[] =
|
||||
{
|
||||
{"rax", k_machine_rax, -1},
|
||||
{"rcx", k_machine_rcx, -1},
|
||||
{"rdx", k_machine_rdx, -1},
|
||||
|
@ -106,7 +112,7 @@ static struct regmap_ent x86_64_register_map[] = {
|
|||
{"rip", k_machine_rip, -1}
|
||||
};
|
||||
|
||||
const int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent);
|
||||
const int size_of_x86_64_register_map = llvm::array_lengthof (x86_64_register_map);
|
||||
|
||||
static int x86_64_register_map_initialized = 0;
|
||||
|
||||
|
@ -114,7 +120,8 @@ static int x86_64_register_map_initialized = 0;
|
|||
// AssemblyParse_x86 local-file class definition & implementation functions
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
class AssemblyParse_x86 {
|
||||
class AssemblyParse_x86
|
||||
{
|
||||
public:
|
||||
|
||||
AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
|
||||
|
@ -269,7 +276,8 @@ AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
|
|||
{
|
||||
if (m_cpu == k_i386)
|
||||
{
|
||||
switch (machine_regno) {
|
||||
switch (machine_regno)
|
||||
{
|
||||
case k_machine_ebx:
|
||||
case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention
|
||||
case k_machine_esi:
|
||||
|
@ -282,7 +290,8 @@ AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
|
|||
}
|
||||
if (m_cpu == k_x86_64)
|
||||
{
|
||||
switch (machine_regno) {
|
||||
switch (machine_regno)
|
||||
{
|
||||
case k_machine_rbx:
|
||||
case k_machine_rsp:
|
||||
case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention
|
||||
|
@ -309,7 +318,8 @@ AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
|
|||
#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
|
||||
|
||||
// pushq %rbp [0x55]
|
||||
bool AssemblyParse_x86::push_rbp_pattern_p () {
|
||||
bool AssemblyParse_x86::push_rbp_pattern_p ()
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
if (*p == 0x55)
|
||||
return true;
|
||||
|
@ -327,7 +337,8 @@ bool AssemblyParse_x86::push_0_pattern_p ()
|
|||
|
||||
// pushq $0
|
||||
// pushl $0
|
||||
bool AssemblyParse_x86::push_imm_pattern_p () {
|
||||
bool AssemblyParse_x86::push_imm_pattern_p ()
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
if (*p == 0x68 || *p == 0x6a)
|
||||
return true;
|
||||
|
@ -336,7 +347,8 @@ bool AssemblyParse_x86::push_imm_pattern_p () {
|
|||
|
||||
// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
|
||||
// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
|
||||
bool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
|
||||
bool AssemblyParse_x86::mov_rsp_rbp_pattern_p ()
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
if (m_wordsize == 8 && *p == 0x48)
|
||||
p++;
|
||||
|
@ -348,17 +360,20 @@ bool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
|
|||
}
|
||||
|
||||
// subq $0x20, %rsp
|
||||
bool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) {
|
||||
bool AssemblyParse_x86::sub_rsp_pattern_p (int& amount)
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
if (m_wordsize == 8 && *p == 0x48)
|
||||
p++;
|
||||
// 8-bit immediate operand
|
||||
if (*p == 0x83 && *(p + 1) == 0xec) {
|
||||
if (*p == 0x83 && *(p + 1) == 0xec)
|
||||
{
|
||||
amount = (int8_t) *(p + 2);
|
||||
return true;
|
||||
}
|
||||
// 32-bit immediate operand
|
||||
if (*p == 0x81 && *(p + 1) == 0xec) {
|
||||
if (*p == 0x81 && *(p + 1) == 0xec)
|
||||
{
|
||||
amount = (int32_t) extract_4 (p + 2);
|
||||
return true;
|
||||
}
|
||||
|
@ -366,17 +381,20 @@ bool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) {
|
|||
}
|
||||
|
||||
// addq $0x20, %rsp
|
||||
bool AssemblyParse_x86::add_rsp_pattern_p (int& amount) {
|
||||
bool AssemblyParse_x86::add_rsp_pattern_p (int& amount)
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
if (m_wordsize == 8 && *p == 0x48)
|
||||
p++;
|
||||
// 8-bit immediate operand
|
||||
if (*p == 0x83 && *(p + 1) == 0xc4) {
|
||||
if (*p == 0x83 && *(p + 1) == 0xc4)
|
||||
{
|
||||
amount = (int8_t) *(p + 2);
|
||||
return true;
|
||||
}
|
||||
// 32-bit immediate operand
|
||||
if (*p == 0x81 && *(p + 1) == 0xc4) {
|
||||
if (*p == 0x81 && *(p + 1) == 0xc4)
|
||||
{
|
||||
amount = (int32_t) extract_4 (p + 2);
|
||||
return true;
|
||||
}
|
||||
|
@ -385,15 +403,18 @@ bool AssemblyParse_x86::add_rsp_pattern_p (int& amount) {
|
|||
|
||||
// pushq %rbx
|
||||
// pushl %ebx
|
||||
bool AssemblyParse_x86::push_reg_p (int& regno) {
|
||||
bool AssemblyParse_x86::push_reg_p (int& regno)
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
int regno_prefix_bit = 0;
|
||||
// If we have a rex prefix byte, check to see if a B bit is set
|
||||
if (m_wordsize == 8 && *p == 0x41) {
|
||||
if (m_wordsize == 8 && *p == 0x41)
|
||||
{
|
||||
regno_prefix_bit = 1 << 3;
|
||||
p++;
|
||||
}
|
||||
if (*p >= 0x50 && *p <= 0x57) {
|
||||
if (*p >= 0x50 && *p <= 0x57)
|
||||
{
|
||||
regno = (*p - 0x50) | regno_prefix_bit;
|
||||
return true;
|
||||
}
|
||||
|
@ -402,15 +423,18 @@ bool AssemblyParse_x86::push_reg_p (int& regno) {
|
|||
|
||||
// popq %rbx
|
||||
// popl %ebx
|
||||
bool AssemblyParse_x86::pop_reg_p (int& regno) {
|
||||
bool AssemblyParse_x86::pop_reg_p (int& regno)
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
int regno_prefix_bit = 0;
|
||||
// If we have a rex prefix byte, check to see if a B bit is set
|
||||
if (m_wordsize == 8 && *p == 0x41) {
|
||||
if (m_wordsize == 8 && *p == 0x41)
|
||||
{
|
||||
regno_prefix_bit = 1 << 3;
|
||||
p++;
|
||||
}
|
||||
if (*p >= 0x58 && *p <= 0x5f) {
|
||||
if (*p >= 0x58 && *p <= 0x5f)
|
||||
{
|
||||
regno = (*p - 0x58) | regno_prefix_bit;
|
||||
return true;
|
||||
}
|
||||
|
@ -419,13 +443,15 @@ bool AssemblyParse_x86::pop_reg_p (int& regno) {
|
|||
|
||||
// popq %rbp [0x5d]
|
||||
// popl %ebp [0x5d]
|
||||
bool AssemblyParse_x86::pop_rbp_pattern_p () {
|
||||
bool AssemblyParse_x86::pop_rbp_pattern_p ()
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
return (*p == 0x5d);
|
||||
}
|
||||
|
||||
// call $0 [0xe8 0x0 0x0 0x0 0x0]
|
||||
bool AssemblyParse_x86::call_next_insn_pattern_p () {
|
||||
bool AssemblyParse_x86::call_next_insn_pattern_p ()
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
return (*p == 0xe8) && (*(p+1) == 0x0) && (*(p+2) == 0x0)
|
||||
&& (*(p+3) == 0x0) && (*(p+4) == 0x0);
|
||||
|
@ -442,15 +468,18 @@ bool AssemblyParse_x86::call_next_insn_pattern_p () {
|
|||
// the actual location. The positive value returned for the offset
|
||||
// is a convention used elsewhere for CFA offsets et al.
|
||||
|
||||
bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) {
|
||||
bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset)
|
||||
{
|
||||
uint8_t *p = m_cur_insn_bytes;
|
||||
int src_reg_prefix_bit = 0;
|
||||
int target_reg_prefix_bit = 0;
|
||||
|
||||
if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) {
|
||||
if (m_wordsize == 8 && REX_W_PREFIX_P (*p))
|
||||
{
|
||||
src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
|
||||
target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
|
||||
if (target_reg_prefix_bit == 1) {
|
||||
if (target_reg_prefix_bit == 1)
|
||||
{
|
||||
// rbp/ebp don't need a prefix bit - we know this isn't the
|
||||
// reg we care about.
|
||||
return false;
|
||||
|
@ -458,7 +487,8 @@ bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_off
|
|||
p++;
|
||||
}
|
||||
|
||||
if (*p == 0x89) {
|
||||
if (*p == 0x89)
|
||||
{
|
||||
/* Mask off the 3-5 bits which indicate the destination register
|
||||
if this is a ModR/M byte. */
|
||||
int opcode_destreg_masked_out = *(p + 1) & (~0x38);
|
||||
|
@ -911,7 +941,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
continue;
|
||||
}
|
||||
|
||||
if (row_id == 0) {
|
||||
if (row_id == 0)
|
||||
{
|
||||
// If we are here, compiler didn't generate CFI for prologue.
|
||||
// This won't happen to GCC or clang.
|
||||
// In this case, bail out directly.
|
||||
|
@ -942,7 +973,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
|
||||
// push/pop register
|
||||
int regno;
|
||||
if (push_reg_p (regno)) {
|
||||
if (push_reg_p (regno))
|
||||
{
|
||||
row->SetOffset (offset);
|
||||
row->SetCFAOffset (m_wordsize + row->GetCFAOffset());
|
||||
|
||||
|
@ -951,7 +983,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
unwind_plan_updated = true;
|
||||
continue;
|
||||
}
|
||||
if (pop_reg_p (regno)) {
|
||||
if (pop_reg_p (regno))
|
||||
{
|
||||
// Technically, this might be a nonvolatile register recover in epilogue.
|
||||
// We should reset RegisterInfo for the register.
|
||||
// But in practice, previous rule for the register is still valid...
|
||||
|
@ -967,7 +1000,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
}
|
||||
|
||||
// push imm
|
||||
if (push_imm_pattern_p ()) {
|
||||
if (push_imm_pattern_p ())
|
||||
{
|
||||
row->SetOffset (offset);
|
||||
row->SetCFAOffset (m_wordsize + row->GetCFAOffset());
|
||||
UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
|
||||
|
@ -978,7 +1012,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
|
||||
// add/sub %rsp/%esp
|
||||
int amount;
|
||||
if (add_rsp_pattern_p (amount)) {
|
||||
if (add_rsp_pattern_p (amount))
|
||||
{
|
||||
row->SetOffset (offset);
|
||||
row->SetCFAOffset (-amount + row->GetCFAOffset());
|
||||
|
||||
|
@ -987,7 +1022,8 @@ AssemblyParse_x86::augment_unwind_plan_from_call_site (AddressRange& func, Unwin
|
|||
unwind_plan_updated = true;
|
||||
continue;
|
||||
}
|
||||
if (sub_rsp_pattern_p (amount)) {
|
||||
if (sub_rsp_pattern_p (amount))
|
||||
{
|
||||
row->SetOffset (offset);
|
||||
row->SetCFAOffset (amount + row->GetCFAOffset());
|
||||
|
||||
|
|
Loading…
Reference in New Issue