1 //===-- x86AssemblyInspectionEngine.cpp -------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "x86AssemblyInspectionEngine.h"
11 
12 #include "llvm-c/Disassembler.h"
13 
14 #include "lldb/Core/Address.h"
15 #include "lldb/Symbol/UnwindPlan.h"
16 #include "lldb/Target/RegisterContext.h"
17 #include "lldb/Target/UnwindAssembly.h"
18 
19 using namespace lldb_private;
20 using namespace lldb;
21 
22 x86AssemblyInspectionEngine::x86AssemblyInspectionEngine(const ArchSpec &arch)
23     : m_cur_insn(nullptr), m_machine_ip_regnum(LLDB_INVALID_REGNUM),
24       m_machine_sp_regnum(LLDB_INVALID_REGNUM),
25       m_machine_fp_regnum(LLDB_INVALID_REGNUM),
26       m_lldb_ip_regnum(LLDB_INVALID_REGNUM),
27       m_lldb_sp_regnum(LLDB_INVALID_REGNUM),
28       m_lldb_fp_regnum(LLDB_INVALID_REGNUM),
29 
30       m_reg_map(), m_arch(arch), m_cpu(k_cpu_unspecified), m_wordsize(-1),
31       m_register_map_initialized(false), m_disasm_context() {
32   m_disasm_context = ::LLVMCreateDisasm("x86_64-apple-macosx", nullptr,
33                                         /*TagType=*/1, nullptr, nullptr);
34   //      ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), nullptr,
35   //                         /*TagType=*/1, nullptr, nullptr);
36 }
37 
38 x86AssemblyInspectionEngine::~x86AssemblyInspectionEngine() {
39   ::LLVMDisasmDispose(m_disasm_context);
40 }
41 
42 void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {
43   m_cpu = k_cpu_unspecified;
44   m_wordsize = -1;
45   m_register_map_initialized = false;
46 
47   const llvm::Triple::ArchType cpu = m_arch.GetMachine();
48   if (cpu == llvm::Triple::x86)
49     m_cpu = k_i386;
50   else if (cpu == llvm::Triple::x86_64)
51     m_cpu = k_x86_64;
52 
53   if (m_cpu == k_cpu_unspecified)
54     return;
55 
56   if (reg_ctx.get() == nullptr)
57     return;
58 
59   if (m_cpu == k_i386) {
60     m_machine_ip_regnum = k_machine_eip;
61     m_machine_sp_regnum = k_machine_esp;
62     m_machine_fp_regnum = k_machine_ebp;
63     m_wordsize = 4;
64 
65     struct lldb_reg_info reginfo;
66     reginfo.name = "eax";
67     m_reg_map[k_machine_eax] = reginfo;
68     reginfo.name = "edx";
69     m_reg_map[k_machine_edx] = reginfo;
70     reginfo.name = "esp";
71     m_reg_map[k_machine_esp] = reginfo;
72     reginfo.name = "esi";
73     m_reg_map[k_machine_esi] = reginfo;
74     reginfo.name = "eip";
75     m_reg_map[k_machine_eip] = reginfo;
76     reginfo.name = "ecx";
77     m_reg_map[k_machine_ecx] = reginfo;
78     reginfo.name = "ebx";
79     m_reg_map[k_machine_ebx] = reginfo;
80     reginfo.name = "ebp";
81     m_reg_map[k_machine_ebp] = reginfo;
82     reginfo.name = "edi";
83     m_reg_map[k_machine_edi] = reginfo;
84   } else {
85     m_machine_ip_regnum = k_machine_rip;
86     m_machine_sp_regnum = k_machine_rsp;
87     m_machine_fp_regnum = k_machine_rbp;
88     m_wordsize = 8;
89 
90     struct lldb_reg_info reginfo;
91     reginfo.name = "rax";
92     m_reg_map[k_machine_rax] = reginfo;
93     reginfo.name = "rdx";
94     m_reg_map[k_machine_rdx] = reginfo;
95     reginfo.name = "rsp";
96     m_reg_map[k_machine_rsp] = reginfo;
97     reginfo.name = "rsi";
98     m_reg_map[k_machine_rsi] = reginfo;
99     reginfo.name = "r8";
100     m_reg_map[k_machine_r8] = reginfo;
101     reginfo.name = "r10";
102     m_reg_map[k_machine_r10] = reginfo;
103     reginfo.name = "r12";
104     m_reg_map[k_machine_r12] = reginfo;
105     reginfo.name = "r14";
106     m_reg_map[k_machine_r14] = reginfo;
107     reginfo.name = "rip";
108     m_reg_map[k_machine_rip] = reginfo;
109     reginfo.name = "rcx";
110     m_reg_map[k_machine_rcx] = reginfo;
111     reginfo.name = "rbx";
112     m_reg_map[k_machine_rbx] = reginfo;
113     reginfo.name = "rbp";
114     m_reg_map[k_machine_rbp] = reginfo;
115     reginfo.name = "rdi";
116     m_reg_map[k_machine_rdi] = reginfo;
117     reginfo.name = "r9";
118     m_reg_map[k_machine_r9] = reginfo;
119     reginfo.name = "r11";
120     m_reg_map[k_machine_r11] = reginfo;
121     reginfo.name = "r13";
122     m_reg_map[k_machine_r13] = reginfo;
123     reginfo.name = "r15";
124     m_reg_map[k_machine_r15] = reginfo;
125   }
126 
127   for (MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.begin();
128        it != m_reg_map.end(); ++it) {
129     const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName(it->second.name);
130     if (ri)
131       it->second.lldb_regnum = ri->kinds[eRegisterKindLLDB];
132   }
133 
134   uint32_t lldb_regno;
135   if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
136     m_lldb_sp_regnum = lldb_regno;
137   if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
138     m_lldb_fp_regnum = lldb_regno;
139   if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
140     m_lldb_ip_regnum = lldb_regno;
141 
142   m_register_map_initialized = true;
143 }
144 
145 void x86AssemblyInspectionEngine::Initialize(
146     std::vector<lldb_reg_info> &reg_info) {
147   m_cpu = k_cpu_unspecified;
148   m_wordsize = -1;
149   m_register_map_initialized = false;
150 
151   const llvm::Triple::ArchType cpu = m_arch.GetMachine();
152   if (cpu == llvm::Triple::x86)
153     m_cpu = k_i386;
154   else if (cpu == llvm::Triple::x86_64)
155     m_cpu = k_x86_64;
156 
157   if (m_cpu == k_cpu_unspecified)
158     return;
159 
160   if (m_cpu == k_i386) {
161     m_machine_ip_regnum = k_machine_eip;
162     m_machine_sp_regnum = k_machine_esp;
163     m_machine_fp_regnum = k_machine_ebp;
164     m_wordsize = 4;
165 
166     struct lldb_reg_info reginfo;
167     reginfo.name = "eax";
168     m_reg_map[k_machine_eax] = reginfo;
169     reginfo.name = "edx";
170     m_reg_map[k_machine_edx] = reginfo;
171     reginfo.name = "esp";
172     m_reg_map[k_machine_esp] = reginfo;
173     reginfo.name = "esi";
174     m_reg_map[k_machine_esi] = reginfo;
175     reginfo.name = "eip";
176     m_reg_map[k_machine_eip] = reginfo;
177     reginfo.name = "ecx";
178     m_reg_map[k_machine_ecx] = reginfo;
179     reginfo.name = "ebx";
180     m_reg_map[k_machine_ebx] = reginfo;
181     reginfo.name = "ebp";
182     m_reg_map[k_machine_ebp] = reginfo;
183     reginfo.name = "edi";
184     m_reg_map[k_machine_edi] = reginfo;
185   } else {
186     m_machine_ip_regnum = k_machine_rip;
187     m_machine_sp_regnum = k_machine_rsp;
188     m_machine_fp_regnum = k_machine_rbp;
189     m_wordsize = 8;
190 
191     struct lldb_reg_info reginfo;
192     reginfo.name = "rax";
193     m_reg_map[k_machine_rax] = reginfo;
194     reginfo.name = "rdx";
195     m_reg_map[k_machine_rdx] = reginfo;
196     reginfo.name = "rsp";
197     m_reg_map[k_machine_rsp] = reginfo;
198     reginfo.name = "rsi";
199     m_reg_map[k_machine_rsi] = reginfo;
200     reginfo.name = "r8";
201     m_reg_map[k_machine_r8] = reginfo;
202     reginfo.name = "r10";
203     m_reg_map[k_machine_r10] = reginfo;
204     reginfo.name = "r12";
205     m_reg_map[k_machine_r12] = reginfo;
206     reginfo.name = "r14";
207     m_reg_map[k_machine_r14] = reginfo;
208     reginfo.name = "rip";
209     m_reg_map[k_machine_rip] = reginfo;
210     reginfo.name = "rcx";
211     m_reg_map[k_machine_rcx] = reginfo;
212     reginfo.name = "rbx";
213     m_reg_map[k_machine_rbx] = reginfo;
214     reginfo.name = "rbp";
215     m_reg_map[k_machine_rbp] = reginfo;
216     reginfo.name = "rdi";
217     m_reg_map[k_machine_rdi] = reginfo;
218     reginfo.name = "r9";
219     m_reg_map[k_machine_r9] = reginfo;
220     reginfo.name = "r11";
221     m_reg_map[k_machine_r11] = reginfo;
222     reginfo.name = "r13";
223     m_reg_map[k_machine_r13] = reginfo;
224     reginfo.name = "r15";
225     m_reg_map[k_machine_r15] = reginfo;
226   }
227 
228   for (MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.begin();
229        it != m_reg_map.end(); ++it) {
230     for (size_t i = 0; i < reg_info.size(); ++i) {
231       if (::strcmp(reg_info[i].name, it->second.name) == 0) {
232         it->second.lldb_regnum = reg_info[i].lldb_regnum;
233         break;
234       }
235     }
236   }
237 
238   uint32_t lldb_regno;
239   if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
240     m_lldb_sp_regnum = lldb_regno;
241   if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
242     m_lldb_fp_regnum = lldb_regno;
243   if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
244     m_lldb_ip_regnum = lldb_regno;
245 
246   m_register_map_initialized = true;
247 }
248 
249 // This function expects an x86 native register number (i.e. the bits stripped
250 // out of the
251 // actual instruction), not an lldb register number.
252 //
253 // FIXME: This is ABI dependent, it shouldn't be hardcoded here.
254 
255 bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) {
256   if (m_cpu == k_i386) {
257     switch (machine_regno) {
258     case k_machine_ebx:
259     case k_machine_ebp: // not actually a nonvolatile but often treated as such
260                         // by convention
261     case k_machine_esi:
262     case k_machine_edi:
263     case k_machine_esp:
264       return true;
265     default:
266       return false;
267     }
268   }
269   if (m_cpu == k_x86_64) {
270     switch (machine_regno) {
271     case k_machine_rbx:
272     case k_machine_rsp:
273     case k_machine_rbp: // not actually a nonvolatile but often treated as such
274                         // by convention
275     case k_machine_r12:
276     case k_machine_r13:
277     case k_machine_r14:
278     case k_machine_r15:
279       return true;
280     default:
281       return false;
282     }
283   }
284   return false;
285 }
286 
287 // Macro to detect if this is a REX mode prefix byte.
288 #define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
289 
290 // The high bit which should be added to the source register number (the "R"
291 // bit)
292 #define REX_W_SRCREG(opcode) (((opcode)&0x4) >> 2)
293 
294 // The high bit which should be added to the destination register number (the
295 // "B" bit)
296 #define REX_W_DSTREG(opcode) ((opcode)&0x1)
297 
298 // pushq %rbp [0x55]
299 bool x86AssemblyInspectionEngine::push_rbp_pattern_p() {
300   uint8_t *p = m_cur_insn;
301   if (*p == 0x55)
302     return true;
303   return false;
304 }
305 
306 // pushq $0 ; the first instruction in start() [0x6a 0x00]
307 bool x86AssemblyInspectionEngine::push_0_pattern_p() {
308   uint8_t *p = m_cur_insn;
309   if (*p == 0x6a && *(p + 1) == 0x0)
310     return true;
311   return false;
312 }
313 
314 // pushq $0
315 // pushl $0
316 bool x86AssemblyInspectionEngine::push_imm_pattern_p() {
317   uint8_t *p = m_cur_insn;
318   if (*p == 0x68 || *p == 0x6a)
319     return true;
320   return false;
321 }
322 
323 // movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
324 // movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
325 bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {
326   uint8_t *p = m_cur_insn;
327   if (m_wordsize == 8 && *p == 0x48)
328     p++;
329   if (*(p) == 0x8b && *(p + 1) == 0xec)
330     return true;
331   if (*(p) == 0x89 && *(p + 1) == 0xe5)
332     return true;
333   return false;
334 }
335 
336 // subq $0x20, %rsp
337 bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) {
338   uint8_t *p = m_cur_insn;
339   if (m_wordsize == 8 && *p == 0x48)
340     p++;
341   // 8-bit immediate operand
342   if (*p == 0x83 && *(p + 1) == 0xec) {
343     amount = (int8_t) * (p + 2);
344     return true;
345   }
346   // 32-bit immediate operand
347   if (*p == 0x81 && *(p + 1) == 0xec) {
348     amount = (int32_t)extract_4(p + 2);
349     return true;
350   }
351   return false;
352 }
353 
354 // addq $0x20, %rsp
355 bool x86AssemblyInspectionEngine::add_rsp_pattern_p(int &amount) {
356   uint8_t *p = m_cur_insn;
357   if (m_wordsize == 8 && *p == 0x48)
358     p++;
359   // 8-bit immediate operand
360   if (*p == 0x83 && *(p + 1) == 0xc4) {
361     amount = (int8_t) * (p + 2);
362     return true;
363   }
364   // 32-bit immediate operand
365   if (*p == 0x81 && *(p + 1) == 0xc4) {
366     amount = (int32_t)extract_4(p + 2);
367     return true;
368   }
369   return false;
370 }
371 
372 // lea esp, [esp - 0x28]
373 // lea esp, [esp + 0x28]
374 bool x86AssemblyInspectionEngine::lea_rsp_pattern_p(int &amount) {
375   uint8_t *p = m_cur_insn;
376   if (m_wordsize == 8 && *p == 0x48)
377     p++;
378 
379   // Check opcode
380   if (*p != 0x8d)
381     return false;
382 
383   // 8 bit displacement
384   if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24) {
385     amount = (int8_t) * (p + 3);
386     return true;
387   }
388 
389   // 32 bit displacement
390   if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24) {
391     amount = (int32_t)extract_4(p + 3);
392     return true;
393   }
394 
395   return false;
396 }
397 
398 // pushq %rbx
399 // pushl %ebx
400 bool x86AssemblyInspectionEngine::push_reg_p(int &regno) {
401   uint8_t *p = m_cur_insn;
402   int regno_prefix_bit = 0;
403   // If we have a rex prefix byte, check to see if a B bit is set
404   if (m_wordsize == 8 && *p == 0x41) {
405     regno_prefix_bit = 1 << 3;
406     p++;
407   }
408   if (*p >= 0x50 && *p <= 0x57) {
409     regno = (*p - 0x50) | regno_prefix_bit;
410     return true;
411   }
412   return false;
413 }
414 
415 // popq %rbx
416 // popl %ebx
417 bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {
418   uint8_t *p = m_cur_insn;
419   int regno_prefix_bit = 0;
420   // If we have a rex prefix byte, check to see if a B bit is set
421   if (m_wordsize == 8 && *p == 0x41) {
422     regno_prefix_bit = 1 << 3;
423     p++;
424   }
425   if (*p >= 0x58 && *p <= 0x5f) {
426     regno = (*p - 0x58) | regno_prefix_bit;
427     return true;
428   }
429   return false;
430 }
431 
432 // popq %rbp [0x5d]
433 // popl %ebp [0x5d]
434 bool x86AssemblyInspectionEngine::pop_rbp_pattern_p() {
435   uint8_t *p = m_cur_insn;
436   return (*p == 0x5d);
437 }
438 
439 // leave [0xc9]
440 bool x86AssemblyInspectionEngine::leave_pattern_p() {
441   uint8_t *p = m_cur_insn;
442   return (*p == 0xc9);
443 }
444 
445 // call $0 [0xe8 0x0 0x0 0x0 0x0]
446 bool x86AssemblyInspectionEngine::call_next_insn_pattern_p() {
447   uint8_t *p = m_cur_insn;
448   return (*p == 0xe8) && (*(p + 1) == 0x0) && (*(p + 2) == 0x0) &&
449          (*(p + 3) == 0x0) && (*(p + 4) == 0x0);
450 }
451 
452 // Look for an instruction sequence storing a nonvolatile register
453 // on to the stack frame.
454 
455 //  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
456 //  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]
457 
458 // The offset value returned in rbp_offset will be positive --
459 // but it must be subtraced from the frame base register to get
460 // the actual location.  The positive value returned for the offset
461 // is a convention used elsewhere for CFA offsets et al.
462 
463 bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
464     int &regno, int &rbp_offset) {
465   uint8_t *p = m_cur_insn;
466   int src_reg_prefix_bit = 0;
467   int target_reg_prefix_bit = 0;
468 
469   if (m_wordsize == 8 && REX_W_PREFIX_P(*p)) {
470     src_reg_prefix_bit = REX_W_SRCREG(*p) << 3;
471     target_reg_prefix_bit = REX_W_DSTREG(*p) << 3;
472     if (target_reg_prefix_bit == 1) {
473       // rbp/ebp don't need a prefix bit - we know this isn't the
474       // reg we care about.
475       return false;
476     }
477     p++;
478   }
479 
480   if (*p == 0x89) {
481     /* Mask off the 3-5 bits which indicate the destination register
482        if this is a ModR/M byte.  */
483     int opcode_destreg_masked_out = *(p + 1) & (~0x38);
484 
485     /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
486        and three bits between them, e.g. 01nnn101
487        We're looking for a destination of ebp-disp8 or ebp-disp32.   */
488     int immsize;
489     if (opcode_destreg_masked_out == 0x45)
490       immsize = 2;
491     else if (opcode_destreg_masked_out == 0x85)
492       immsize = 4;
493     else
494       return false;
495 
496     int offset = 0;
497     if (immsize == 2)
498       offset = (int8_t) * (p + 2);
499     if (immsize == 4)
500       offset = (uint32_t)extract_4(p + 2);
501     if (offset > 0)
502       return false;
503 
504     regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
505     rbp_offset = offset > 0 ? offset : -offset;
506     return true;
507   }
508   return false;
509 }
510 
511 // ret [0xc9] or [0xc2 imm8] or [0xca imm8]
512 bool x86AssemblyInspectionEngine::ret_pattern_p() {
513   uint8_t *p = m_cur_insn;
514   if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
515     return true;
516   return false;
517 }
518 
519 uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) {
520   uint32_t v = 0;
521   for (int i = 3; i >= 0; i--)
522     v = (v << 8) | b[i];
523   return v;
524 }
525 
526 bool x86AssemblyInspectionEngine::instruction_length(uint8_t *insn_p,
527                                                      int &length) {
528 
529   const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
530   llvm::SmallVector<uint8_t, 32> opcode_data;
531   opcode_data.resize(max_op_byte_size);
532 
533   char out_string[512];
534   const size_t inst_size =
535       ::LLVMDisasmInstruction(m_disasm_context, insn_p, max_op_byte_size, 0,
536                               out_string, sizeof(out_string));
537 
538   length = inst_size;
539   return true;
540 }
541 
542 bool x86AssemblyInspectionEngine::machine_regno_to_lldb_regno(
543     int machine_regno, uint32_t &lldb_regno) {
544   MachineRegnumToNameAndLLDBRegnum::iterator it = m_reg_map.find(machine_regno);
545   if (it != m_reg_map.end()) {
546     lldb_regno = it->second.lldb_regnum;
547     return true;
548   }
549   return false;
550   return false;
551 }
552 
553 bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
554     uint8_t *data, size_t size, AddressRange &func_range,
555     UnwindPlan &unwind_plan) {
556   unwind_plan.Clear();
557 
558   if (data == nullptr || size == 0)
559     return false;
560 
561   if (m_register_map_initialized == false)
562     return false;
563 
564   addr_t current_func_text_offset = 0;
565   int current_sp_bytes_offset_from_cfa = 0;
566   UnwindPlan::Row::RegisterLocation initial_regloc;
567   UnwindPlan::RowSP row(new UnwindPlan::Row);
568 
569   unwind_plan.SetPlanValidAddressRange(func_range);
570   unwind_plan.SetRegisterKind(eRegisterKindLLDB);
571 
572   // At the start of the function, find the CFA by adding wordsize to the SP
573   // register
574   row->SetOffset(current_func_text_offset);
575   row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
576 
577   // caller's stack pointer value before the call insn is the CFA address
578   initial_regloc.SetIsCFAPlusOffset(0);
579   row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc);
580 
581   // saved instruction pointer can be found at CFA - wordsize.
582   current_sp_bytes_offset_from_cfa = m_wordsize;
583   initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
584   row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);
585 
586   unwind_plan.AppendRow(row);
587 
588   // Allocate a new Row, populate it with the existing Row contents.
589   UnwindPlan::Row *newrow = new UnwindPlan::Row;
590   *newrow = *row.get();
591   row.reset(newrow);
592 
593   // Track which registers have been saved so far in the prologue.
594   // If we see another push of that register, it's not part of the prologue.
595   // The register numbers used here are the machine register #'s
596   // (i386_register_numbers, x86_64_register_numbers).
597   std::vector<bool> saved_registers(32, false);
598 
599   // Once the prologue has completed we'll save a copy of the unwind
600   // instructions
601   // If there is an epilogue in the middle of the function, after that epilogue
602   // we'll reinstate
603   // the unwind setup -- we assume that some code path jumps over the
604   // mid-function epilogue
605 
606   UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
607   int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the
608                                                    // epilogue started executed
609   std::vector<bool> prologue_completed_saved_registers;
610 
611   while (current_func_text_offset < size) {
612     int stack_offset, insn_len;
613     int machine_regno;   // register numbers masked directly out of instructions
614     uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB
615                          // numbering scheme
616 
617     bool in_epilogue = false; // we're in the middle of an epilogue sequence
618     bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
619 
620     m_cur_insn = data + current_func_text_offset;
621     if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
622         insn_len > kMaxInstructionByteSize) {
623       // An unrecognized/junk instruction
624       break;
625     }
626 
627     if (push_rbp_pattern_p()) {
628       current_sp_bytes_offset_from_cfa += m_wordsize;
629       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
630       UnwindPlan::Row::RegisterLocation regloc;
631       regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset());
632       row->SetRegisterInfo(m_lldb_fp_regnum, regloc);
633       saved_registers[m_machine_fp_regnum] = true;
634       row_updated = true;
635     }
636 
637     else if (mov_rsp_rbp_pattern_p()) {
638       row->GetCFAValue().SetIsRegisterPlusOffset(
639           m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
640       row_updated = true;
641     }
642 
643     // This is the start() function (or a pthread equivalent), it starts with a
644     // pushl $0x0 which puts the
645     // saved pc value of 0 on the stack.  In this case we want to pretend we
646     // didn't see a stack movement at all --
647     // normally the saved pc value is already on the stack by the time the
648     // function starts executing.
649     else if (push_0_pattern_p()) {
650     }
651 
652     else if (push_reg_p(machine_regno)) {
653       current_sp_bytes_offset_from_cfa += m_wordsize;
654       // the PUSH instruction has moved the stack pointer - if the CFA is set in
655       // terms of the stack pointer,
656       // we need to add a new row of instructions.
657       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
658         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
659         row_updated = true;
660       }
661       // record where non-volatile (callee-saved, spilled) registers are saved
662       // on the stack
663       if (nonvolatile_reg_p(machine_regno) &&
664           machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
665           saved_registers[machine_regno] == false) {
666         UnwindPlan::Row::RegisterLocation regloc;
667         regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
668         row->SetRegisterInfo(lldb_regno, regloc);
669         saved_registers[machine_regno] = true;
670         row_updated = true;
671       }
672     }
673 
674     else if (pop_reg_p(machine_regno)) {
675       current_sp_bytes_offset_from_cfa -= m_wordsize;
676 
677       if (nonvolatile_reg_p(machine_regno) &&
678           machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
679           saved_registers[machine_regno] == true) {
680         saved_registers[machine_regno] = false;
681         row->RemoveRegisterInfo(lldb_regno);
682 
683         if (machine_regno == (int)m_machine_fp_regnum) {
684           row->GetCFAValue().SetIsRegisterPlusOffset(
685               m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
686         }
687 
688         in_epilogue = true;
689         row_updated = true;
690       }
691 
692       // the POP instruction has moved the stack pointer - if the CFA is set in
693       // terms of the stack pointer,
694       // we need to add a new row of instructions.
695       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
696         row->GetCFAValue().SetIsRegisterPlusOffset(
697             m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
698         row_updated = true;
699       }
700     }
701 
702     // The LEAVE instruction moves the value from rbp into rsp and pops
703     // a value off the stack into rbp (restoring the caller's rbp value).
704     // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
705     else if (leave_pattern_p()) {
706       // We're going to copy the value in rbp into rsp, so re-set the sp offset
707       // based on the CFAValue.  Also, adjust it to recognize that we're popping
708       // the saved rbp value off the stack.
709       current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
710       current_sp_bytes_offset_from_cfa -= m_wordsize;
711       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
712 
713       // rbp is restored to the caller's value
714       saved_registers[m_machine_fp_regnum] = false;
715       row->RemoveRegisterInfo(m_lldb_fp_regnum);
716 
717       // cfa is now in terms of rsp again.
718       row->GetCFAValue().SetIsRegisterPlusOffset(
719           m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
720       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
721 
722       in_epilogue = true;
723       row_updated = true;
724     }
725 
726     else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) &&
727              nonvolatile_reg_p(machine_regno) &&
728              machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
729              saved_registers[machine_regno] == false) {
730       saved_registers[machine_regno] = true;
731 
732       UnwindPlan::Row::RegisterLocation regloc;
733 
734       // stack_offset for 'movq %r15, -80(%rbp)' will be 80.
735       // In the Row, we want to express this as the offset from the CFA.  If the
736       // frame base
737       // is rbp (like the above instruction), the CFA offset for rbp is probably
738       // 16.  So we
739       // want to say that the value is stored at the CFA address - 96.
740       regloc.SetAtCFAPlusOffset(
741           -(stack_offset + row->GetCFAValue().GetOffset()));
742 
743       row->SetRegisterInfo(lldb_regno, regloc);
744 
745       row_updated = true;
746     }
747 
748     else if (sub_rsp_pattern_p(stack_offset)) {
749       current_sp_bytes_offset_from_cfa += stack_offset;
750       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
751         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
752         row_updated = true;
753       }
754     }
755 
756     else if (add_rsp_pattern_p(stack_offset)) {
757       current_sp_bytes_offset_from_cfa -= stack_offset;
758       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
759         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
760         row_updated = true;
761       }
762       in_epilogue = true;
763     }
764 
765     else if (lea_rsp_pattern_p(stack_offset)) {
766       current_sp_bytes_offset_from_cfa -= stack_offset;
767       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
768         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
769         row_updated = true;
770       }
771       if (stack_offset > 0)
772         in_epilogue = true;
773     }
774 
775     else if (ret_pattern_p() && prologue_completed_row.get()) {
776       // Reinstate the saved prologue setup for any instructions
777       // that come after the ret instruction
778 
779       UnwindPlan::Row *newrow = new UnwindPlan::Row;
780       *newrow = *prologue_completed_row.get();
781       row.reset(newrow);
782       current_sp_bytes_offset_from_cfa =
783           prologue_completed_sp_bytes_offset_from_cfa;
784 
785       saved_registers.clear();
786       saved_registers.resize(prologue_completed_saved_registers.size(), false);
787       for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i) {
788         saved_registers[i] = prologue_completed_saved_registers[i];
789       }
790 
791       in_epilogue = true;
792       row_updated = true;
793     }
794 
795     // call next instruction
796     //     call 0
797     //  => pop  %ebx
798     // This is used in i386 programs to get the PIC base address for finding
799     // global data
800     else if (call_next_insn_pattern_p()) {
801       current_sp_bytes_offset_from_cfa += m_wordsize;
802       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
803         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
804         row_updated = true;
805       }
806     }
807 
808     if (row_updated) {
809       if (current_func_text_offset + insn_len < size) {
810         row->SetOffset(current_func_text_offset + insn_len);
811         unwind_plan.AppendRow(row);
812         // Allocate a new Row, populate it with the existing Row contents.
813         newrow = new UnwindPlan::Row;
814         *newrow = *row.get();
815         row.reset(newrow);
816       }
817     }
818 
819     if (in_epilogue == false && row_updated) {
820       // If we're not in an epilogue sequence, save the updated Row
821       UnwindPlan::Row *newrow = new UnwindPlan::Row;
822       *newrow = *row.get();
823       prologue_completed_row.reset(newrow);
824 
825       prologue_completed_saved_registers.clear();
826       prologue_completed_saved_registers.resize(saved_registers.size(), false);
827       for (size_t i = 0; i < saved_registers.size(); ++i) {
828         prologue_completed_saved_registers[i] = saved_registers[i];
829       }
830     }
831 
832     // We may change the sp value without adding a new Row necessarily -- keep
833     // track of it either way.
834     if (in_epilogue == false) {
835       prologue_completed_sp_bytes_offset_from_cfa =
836           current_sp_bytes_offset_from_cfa;
837     }
838 
839     m_cur_insn = m_cur_insn + insn_len;
840     current_func_text_offset += insn_len;
841   }
842 
843   unwind_plan.SetSourceName("assembly insn profiling");
844   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
845   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
846 
847   return true;
848 }
849 
850 bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
851     uint8_t *data, size_t size, AddressRange &func_range,
852     UnwindPlan &unwind_plan, RegisterContextSP &reg_ctx) {
853   Address addr_start = func_range.GetBaseAddress();
854   if (!addr_start.IsValid())
855     return false;
856 
857   // We either need a live RegisterContext, or we need the UnwindPlan to already
858   // be in the lldb register numbering scheme.
859   if (reg_ctx.get() == nullptr &&
860       unwind_plan.GetRegisterKind() != eRegisterKindLLDB)
861     return false;
862 
863   // Is original unwind_plan valid?
864   // unwind_plan should have at least one row which is ABI-default (CFA register
865   // is sp),
866   // and another row in mid-function.
867   if (unwind_plan.GetRowCount() < 2)
868     return false;
869 
870   UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex(0);
871   if (first_row->GetOffset() != 0)
872     return false;
873   uint32_t cfa_reg = first_row->GetCFAValue().GetRegisterNumber();
874   if (unwind_plan.GetRegisterKind() != eRegisterKindLLDB) {
875     cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
876         unwind_plan.GetRegisterKind(),
877         first_row->GetCFAValue().GetRegisterNumber());
878   }
879   if (cfa_reg != m_lldb_sp_regnum ||
880       first_row->GetCFAValue().GetOffset() != m_wordsize)
881     return false;
882 
883   UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset(-1);
884 
885   size_t offset = 0;
886   int row_id = 1;
887   bool unwind_plan_updated = false;
888   UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
889   m_cur_insn = data + offset;
890 
891   // After a mid-function epilogue we will need to re-insert the original unwind
892   // rules
893   // so unwinds work for the remainder of the function.  These aren't common
894   // with clang/gcc
895   // on x86 but it is possible.
896   bool reinstate_unwind_state = false;
897 
898   while (offset < size) {
899     m_cur_insn = data + offset;
900     int insn_len;
901     if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
902         insn_len > kMaxInstructionByteSize) {
903       // An unrecognized/junk instruction.
904       break;
905     }
906 
907     // Advance offsets.
908     offset += insn_len;
909     m_cur_insn = data + offset;
910 
911     if (reinstate_unwind_state) {
912       // that was the last instruction of this function
913       if (offset >= size)
914         continue;
915 
916       UnwindPlan::RowSP new_row(new UnwindPlan::Row());
917       *new_row = *original_last_row;
918       new_row->SetOffset(offset);
919       unwind_plan.AppendRow(new_row);
920       row.reset(new UnwindPlan::Row());
921       *row = *new_row;
922       reinstate_unwind_state = false;
923       unwind_plan_updated = true;
924       continue;
925     }
926 
927     // If we already have one row for this instruction, we can continue.
928     while (row_id < unwind_plan.GetRowCount() &&
929            unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) {
930       row_id++;
931     }
932     UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex(row_id - 1);
933     if (original_row->GetOffset() == offset) {
934       *row = *original_row;
935       continue;
936     }
937 
938     if (row_id == 0) {
939       // If we are here, compiler didn't generate CFI for prologue.
940       // This won't happen to GCC or clang.
941       // In this case, bail out directly.
942       return false;
943     }
944 
945     // Inspect the instruction to check if we need a new row for it.
946     cfa_reg = row->GetCFAValue().GetRegisterNumber();
947     if (unwind_plan.GetRegisterKind() != eRegisterKindLLDB) {
948       cfa_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
949           unwind_plan.GetRegisterKind(),
950           row->GetCFAValue().GetRegisterNumber());
951     }
952     if (cfa_reg == m_lldb_sp_regnum) {
953       // CFA register is sp.
954 
955       // call next instruction
956       //     call 0
957       //  => pop  %ebx
958       if (call_next_insn_pattern_p()) {
959         row->SetOffset(offset);
960         row->GetCFAValue().IncOffset(m_wordsize);
961 
962         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
963         unwind_plan.InsertRow(new_row);
964         unwind_plan_updated = true;
965         continue;
966       }
967 
968       // push/pop register
969       int regno;
970       if (push_reg_p(regno)) {
971         row->SetOffset(offset);
972         row->GetCFAValue().IncOffset(m_wordsize);
973 
974         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
975         unwind_plan.InsertRow(new_row);
976         unwind_plan_updated = true;
977         continue;
978       }
979       if (pop_reg_p(regno)) {
980         // Technically, this might be a nonvolatile register recover in
981         // epilogue.
982         // We should reset RegisterInfo for the register.
983         // But in practice, previous rule for the register is still valid...
984         // So we ignore this case.
985 
986         row->SetOffset(offset);
987         row->GetCFAValue().IncOffset(-m_wordsize);
988 
989         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
990         unwind_plan.InsertRow(new_row);
991         unwind_plan_updated = true;
992         continue;
993       }
994 
995       // push imm
996       if (push_imm_pattern_p()) {
997         row->SetOffset(offset);
998         row->GetCFAValue().IncOffset(m_wordsize);
999         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1000         unwind_plan.InsertRow(new_row);
1001         unwind_plan_updated = true;
1002         continue;
1003       }
1004 
1005       // add/sub %rsp/%esp
1006       int amount;
1007       if (add_rsp_pattern_p(amount)) {
1008         row->SetOffset(offset);
1009         row->GetCFAValue().IncOffset(-amount);
1010 
1011         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1012         unwind_plan.InsertRow(new_row);
1013         unwind_plan_updated = true;
1014         continue;
1015       }
1016       if (sub_rsp_pattern_p(amount)) {
1017         row->SetOffset(offset);
1018         row->GetCFAValue().IncOffset(amount);
1019 
1020         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1021         unwind_plan.InsertRow(new_row);
1022         unwind_plan_updated = true;
1023         continue;
1024       }
1025 
1026       // lea %rsp, [%rsp + $offset]
1027       if (lea_rsp_pattern_p(amount)) {
1028         row->SetOffset(offset);
1029         row->GetCFAValue().IncOffset(-amount);
1030 
1031         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1032         unwind_plan.InsertRow(new_row);
1033         unwind_plan_updated = true;
1034         continue;
1035       }
1036 
1037       if (ret_pattern_p()) {
1038         reinstate_unwind_state = true;
1039         continue;
1040       }
1041     } else if (cfa_reg == m_lldb_fp_regnum) {
1042       // CFA register is fp.
1043 
1044       // The only case we care about is epilogue:
1045       //     [0x5d] pop %rbp/%ebp
1046       //  => [0xc3] ret
1047       if (pop_rbp_pattern_p() || leave_pattern_p()) {
1048         // FIXME m_cur_insn should probably be updated -- I
1049         // think it's not advanced here because this should be
1050         // the last instruction in a function, assuming no
1051         // mid-function epilogues...
1052         if (ret_pattern_p()) {
1053           row->SetOffset(offset);
1054           row->GetCFAValue().SetIsRegisterPlusOffset(
1055               first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
1056 
1057           UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1058           unwind_plan.InsertRow(new_row);
1059           unwind_plan_updated = true;
1060           reinstate_unwind_state = true;
1061           continue;
1062         }
1063       }
1064     } else {
1065       // CFA register is not sp or fp.
1066 
1067       // This must be hand-written assembly.
1068       // Just trust eh_frame and assume we have finished.
1069       break;
1070     }
1071   }
1072 
1073   unwind_plan.SetPlanValidAddressRange(func_range);
1074   if (unwind_plan_updated) {
1075     std::string unwind_plan_source(unwind_plan.GetSourceName().AsCString());
1076     unwind_plan_source += " plus augmentation from assembly parsing";
1077     unwind_plan.SetSourceName(unwind_plan_source.c_str());
1078     unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1079     unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1080   }
1081   return true;
1082 }
1083 
1084 bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
1085     uint8_t *data, size_t size, size_t &offset) {
1086   offset = 0;
1087 
1088   if (m_register_map_initialized == false)
1089     return false;
1090 
1091   while (offset < size) {
1092     int regno;
1093     int insn_len;
1094     int scratch;
1095 
1096     m_cur_insn = data + offset;
1097     if (!instruction_length(m_cur_insn, insn_len) ||
1098         insn_len > kMaxInstructionByteSize || insn_len == 0) {
1099       // An error parsing the instruction, i.e. probably data/garbage - stop
1100       // scanning
1101       break;
1102     }
1103 
1104     if (push_rbp_pattern_p() || mov_rsp_rbp_pattern_p() ||
1105         sub_rsp_pattern_p(scratch) || push_reg_p(regno) ||
1106         mov_reg_to_local_stack_frame_p(regno, scratch) ||
1107         (lea_rsp_pattern_p(scratch) && offset == 0)) {
1108       offset += insn_len;
1109       continue;
1110     }
1111     //
1112     // Unknown non-prologue instruction - stop scanning
1113     break;
1114   }
1115 
1116   return true;
1117 }
1118