13 #include "llvm-c/Disassembler.h"
32 m_cpu(k_cpu_unspecified), m_wordsize(-1),
33 m_register_map_initialized(false), m_disasm_context() {
35 ::LLVMCreateDisasm(arch.
GetTriple().getTriple().c_str(),
nullptr,
49 if (cpu == llvm::Triple::x86)
51 else if (cpu == llvm::Triple::x86_64)
57 if (reg_ctx.get() ==
nullptr)
67 struct lldb_reg_info reginfo;
93 struct lldb_reg_info reginfo;
100 reginfo.name =
"rsi";
104 reginfo.name =
"r10";
106 reginfo.name =
"r12";
108 reginfo.name =
"r14";
110 reginfo.name =
"rip";
112 reginfo.name =
"rcx";
114 reginfo.name =
"rbx";
116 reginfo.name =
"rbp";
118 reginfo.name =
"rdi";
122 reginfo.name =
"r11";
124 reginfo.name =
"r13";
126 reginfo.name =
"r15";
130 for (MachineRegnumToNameAndLLDBRegnum::iterator it =
m_reg_map.begin();
132 const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName(it->second.name);
151 std::vector<lldb_reg_info> ®_info) {
157 if (cpu == llvm::Triple::x86)
159 else if (cpu == llvm::Triple::x86_64)
173 reginfo.
name =
"eax";
175 reginfo.
name =
"edx";
177 reginfo.
name =
"esp";
179 reginfo.
name =
"esi";
181 reginfo.
name =
"eip";
183 reginfo.
name =
"ecx";
185 reginfo.
name =
"ebx";
187 reginfo.
name =
"ebp";
189 reginfo.
name =
"edi";
199 reginfo.
name =
"rax";
201 reginfo.
name =
"rdx";
203 reginfo.
name =
"rsp";
205 reginfo.
name =
"rsi";
209 reginfo.
name =
"r10";
211 reginfo.
name =
"r12";
213 reginfo.
name =
"r14";
215 reginfo.
name =
"rip";
217 reginfo.
name =
"rcx";
219 reginfo.
name =
"rbx";
221 reginfo.
name =
"rbp";
223 reginfo.
name =
"rdi";
227 reginfo.
name =
"r11";
229 reginfo.
name =
"r13";
231 reginfo.
name =
"r15";
235 for (MachineRegnumToNameAndLLDBRegnum::iterator it =
m_reg_map.begin();
237 for (
size_t i = 0; i < reg_info.size(); ++i) {
238 if (::strcmp(reg_info[i].name, it->second.name) == 0) {
265 switch (machine_regno) {
278 switch (machine_regno) {
296 #define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
300 #define REX_W_SRCREG(opcode) (((opcode)&0x4) >> 2)
304 #define REX_W_DSTREG(opcode) ((opcode)&0x1)
315 return *p == 0x6a && *(p + 1) == 0
x0;
322 return *p == 0x68 || *p == 0x6a;
339 uint8_t opcode = (*(
m_cur_insn + 1) >> 3) & 7;
358 if (p == 0x0e || p == 0
x16 || p == 0x1e || p == 0x06)
368 int regno_prefix_bit = 0;
371 regno_prefix_bit = (*p & 1) << 3;
374 if (*p >= 0x50 && *p <= 0x57) {
375 regno = (*p - 0x50) | regno_prefix_bit;
387 if (*(p) == 0x8b && *(p + 1) == 0xec)
389 if (*(p) == 0x89 && *(p + 1) == 0xe5)
400 if (*(p) == 0x8b && *(p + 1) == 0xdc)
402 if (*(p) == 0x89 && *(p + 1) == 0xe3)
413 if (*(p) == 0x8b && *(p + 1) == 0xe5)
415 if (*(p) == 0x89 && *(p + 1) == 0xec)
426 if (*(p) == 0x8b && *(p + 1) == 0xe3)
428 if (*(p) == 0x89 && *(p + 1) == 0xdc)
439 if (*p == 0x83 && *(p + 1) == 0xec) {
440 amount = (int8_t) * (p + 2);
444 if (*p == 0x81 && *(p + 1) == 0xec) {
457 if (*p == 0x83 && *(p + 1) == 0xc4) {
458 amount = (int8_t) * (p + 2);
462 if (*p == 0x81 && *(p + 1) == 0xc4) {
481 if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0
x24) {
482 amount = (int8_t) * (p + 3);
487 if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24) {
509 amount = (int8_t)p[1];
536 amount = (int8_t)p[1];
556 if (*p != 0x81 && *p != 0x83)
566 int regno_prefix_bit = 0;
569 regno_prefix_bit = (*p & 1) << 3;
572 if (*p >= 0x58 && *p <= 0x5f) {
573 regno = (*p - 0x58) | regno_prefix_bit;
593 if (p == 0x1f || p == 0x07 || p == 0
x17)
608 return (*p == 0xe8) && (*(p + 1) == 0
x0) && (*(p + 2) == 0
x0) &&
609 (*(p + 3) == 0
x0) && (*(p + 4) == 0
x0);
624 int ®no,
int &rbp_offset) {
626 int src_reg_prefix_bit = 0;
627 int target_reg_prefix_bit = 0;
632 if (target_reg_prefix_bit == 1) {
643 int opcode_destreg_masked_out = *(p + 1) & (~0x38);
649 if (opcode_destreg_masked_out == 0x45)
651 else if (opcode_destreg_masked_out == 0x85)
658 offset = (int8_t) * (p + 2);
664 regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
665 rbp_offset = offset > 0 ? offset : -offset;
683 uint8_t second_byte_sans_reg = *(
m_cur_insn + 1) & ~7;
686 if (second_byte_sans_reg == 0
x20)
690 if (second_byte_sans_reg == 0x60)
694 if (second_byte_sans_reg == 0xa0)
698 if (second_byte_sans_reg == 0xe0)
720 const int instruction_length,
int &offset)
751 if (b1 == 0x0f && opcode_size == 0) {
777 if (opcode_size == 0)
782 int8_t rel8 = (int8_t) *(
m_cur_insn + opcode_size);
801 const addr_t current_func_text_offset,
803 const int instruction_length,
804 addr_t &target_insn_offset) {
808 if (offset < 0 &&
addr_t(-offset) > current_func_text_offset) {
812 if (offset + next_pc_value > func_range.
GetByteSize()) {
817 target_insn_offset = next_pc_value + offset;
828 const addr_t current_func_text_offset,
830 const int instruction_length) {
832 addr_t target_insn_offset;
842 return *p == 0xc3 || *p == 0xc2 || *p == 0xca || *p == 0xcb;
847 for (
int i = 1; i >= 0; i--)
854 for (
int i = 1; i >= 0; i--)
861 for (
int i = 3; i >= 0; i--)
868 for (
int i = 3; i >= 0; i--)
879 llvm::SmallVector<uint8_t, 32> opcode_data;
880 opcode_data.resize(max_op_byte_size);
882 char out_string[512];
883 const size_t inst_size =
885 out_string,
sizeof(out_string));
892 int machine_regno,
uint32_t &lldb_regno) {
893 MachineRegnumToNameAndLLDBRegnum::iterator it =
m_reg_map.find(machine_regno);
895 lldb_regno = it->second.lldb_regnum;
906 if (data ==
nullptr || size == 0)
912 addr_t current_func_text_offset = 0;
913 int current_sp_bytes_offset_from_fa = 0;
914 bool is_aligned =
false;
923 row->SetOffset(current_func_text_offset);
939 *newrow = *row.get();
946 std::vector<bool> saved_registers(32,
false);
954 int prologue_completed_sp_bytes_offset_from_cfa = 0;
956 bool prologue_completed_is_aligned =
false;
957 std::vector<bool> prologue_completed_saved_registers;
959 while (current_func_text_offset < size) {
960 int stack_offset, insn_len;
965 bool in_epilogue =
false;
966 bool row_updated =
false;
976 auto &cfa_value = row->GetCFAValue();
977 auto &afa_value = row->GetAFAValue();
978 auto fa_value_ptr = is_aligned ? &afa_value : &cfa_value;
982 fa_value_ptr->SetIsRegisterPlusOffset(
990 fa_value_ptr->SetIsRegisterPlusOffset(
997 current_sp_bytes_offset_from_fa = 0;
998 afa_value.SetIsRegisterPlusOffset(
1000 fa_value_ptr = &afa_value;
1009 fa_value_ptr = &cfa_value;
1010 afa_value.SetUnspecified();
1014 current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
1021 fa_value_ptr = &cfa_value;
1022 afa_value.SetUnspecified();
1026 current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
1038 current_sp_bytes_offset_from_fa +=
m_wordsize;
1043 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1050 !saved_registers[machine_regno]) {
1056 row->SetRegisterInfo(lldb_regno, regloc);
1057 saved_registers[machine_regno] =
true;
1063 current_sp_bytes_offset_from_fa -=
m_wordsize;
1067 saved_registers[machine_regno]) {
1068 saved_registers[machine_regno] =
false;
1069 row->RemoveRegisterInfo(lldb_regno);
1071 if (lldb_regno == fa_value_ptr->GetRegisterNumber()) {
1072 fa_value_ptr->SetIsRegisterPlusOffset(
1083 fa_value_ptr->SetIsRegisterPlusOffset(
1090 current_sp_bytes_offset_from_fa -=
m_wordsize;
1092 fa_value_ptr->SetIsRegisterPlusOffset(
1112 fa_value_ptr = &cfa_value;
1113 afa_value.SetUnspecified();
1119 fa_value_ptr->SetIsRegisterPlusOffset(
1122 current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
1125 current_sp_bytes_offset_from_fa -=
m_wordsize;
1128 fa_value_ptr->SetIsRegisterPlusOffset(
1139 !saved_registers[machine_regno]) {
1140 saved_registers[machine_regno] =
true;
1154 row->SetRegisterInfo(lldb_regno, regloc);
1160 current_sp_bytes_offset_from_fa += stack_offset;
1162 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1168 current_sp_bytes_offset_from_fa -= stack_offset;
1170 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1178 current_sp_bytes_offset_from_fa +=
m_wordsize;
1180 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1186 current_sp_bytes_offset_from_fa -= stack_offset;
1188 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1191 if (stack_offset > 0)
1199 fa_value_ptr = &cfa_value;
1200 afa_value.SetUnspecified();
1204 current_sp_bytes_offset_from_fa =
1205 fa_value_ptr->GetOffset() - stack_offset;
1213 fa_value_ptr = &cfa_value;
1214 afa_value.SetUnspecified();
1218 current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset() - stack_offset;
1222 else if (prologue_completed_row.get() &&
1241 (
sp.IsCFAPlusOffset() &&
sp.GetOffset() == 0 &&
1247 *newrow = *prologue_completed_row.get();
1249 current_sp_bytes_offset_from_fa =
1250 prologue_completed_sp_bytes_offset_from_cfa;
1251 is_aligned = prologue_completed_is_aligned;
1253 saved_registers.clear();
1254 saved_registers.resize(prologue_completed_saved_registers.size(),
false);
1255 for (
size_t i = 0; i < prologue_completed_saved_registers.size(); ++i) {
1256 saved_registers[i] = prologue_completed_saved_registers[i];
1271 current_sp_bytes_offset_from_fa +=
m_wordsize;
1273 fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
1279 if (current_func_text_offset + insn_len < size) {
1280 row->SetOffset(current_func_text_offset + insn_len);
1284 *newrow = *row.get();
1289 if (!in_epilogue && row_updated) {
1292 *newrow = *row.get();
1293 prologue_completed_row.reset(newrow);
1295 prologue_completed_saved_registers.clear();
1296 prologue_completed_saved_registers.resize(saved_registers.size(),
false);
1297 for (
size_t i = 0; i < saved_registers.size(); ++i) {
1298 prologue_completed_saved_registers[i] = saved_registers[i];
1305 prologue_completed_sp_bytes_offset_from_cfa =
1306 current_sp_bytes_offset_from_fa;
1307 prologue_completed_is_aligned = is_aligned;
1311 current_func_text_offset += insn_len;
1324 UnwindPlan &unwind_plan, RegisterContextSP ®_ctx) {
1331 if (reg_ctx.get() ==
nullptr &&
1342 if (first_row->GetOffset() != 0)
1344 uint32_t cfa_reg = first_row->GetCFAValue().GetRegisterNumber();
1346 cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1348 first_row->GetCFAValue().GetRegisterNumber());
1351 first_row->GetCFAValue().GetOffset() !=
m_wordsize)
1358 bool unwind_plan_updated =
false;
1364 bool reinstate_unwind_state =
false;
1366 while (offset < size) {
1382 if (reinstate_unwind_state) {
1384 *new_row = *original_last_row;
1385 new_row->SetOffset(offset);
1387 row = std::make_shared<UnwindPlan::Row>();
1389 reinstate_unwind_state =
false;
1390 unwind_plan_updated =
true;
1400 if (original_row->GetOffset() == offset) {
1401 *row = *original_row;
1412 cfa_reg = row->GetCFAValue().GetRegisterNumber();
1414 cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1416 row->GetCFAValue().GetRegisterNumber());
1425 row->SetOffset(offset);
1430 unwind_plan_updated =
true;
1437 row->SetOffset(offset);
1442 unwind_plan_updated =
true;
1451 row->SetOffset(offset);
1456 unwind_plan_updated =
true;
1461 row->SetOffset(offset);
1466 unwind_plan_updated =
true;
1472 row->SetOffset(offset);
1476 unwind_plan_updated =
true;
1482 row->SetOffset(offset);
1486 unwind_plan_updated =
true;
1493 row->SetOffset(offset);
1494 row->GetCFAValue().IncOffset(-amount);
1498 unwind_plan_updated =
true;
1502 row->SetOffset(offset);
1503 row->GetCFAValue().IncOffset(amount);
1507 unwind_plan_updated =
true;
1513 row->SetOffset(offset);
1514 row->GetCFAValue().IncOffset(-amount);
1518 unwind_plan_updated =
true;
1523 reinstate_unwind_state =
true;
1535 row->SetOffset(offset);
1536 row->GetCFAValue().SetIsRegisterPlusOffset(
1537 first_row->GetCFAValue().GetRegisterNumber(),
m_wordsize);
1541 unwind_plan_updated =
true;
1542 reinstate_unwind_state =
true;
1556 if (unwind_plan_updated) {
1558 unwind_plan_source +=
" plus augmentation from assembly parsing";
1567 uint8_t *data,
size_t size,
size_t &offset) {
1573 while (offset < size) {