1 //===-- UnwindAssembly-x86.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 "UnwindAssembly-x86.h"
11 
12 #include "llvm-c/Disassembler.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Support/TargetSelect.h"
15 
16 #include "lldb/Core/Address.h"
17 #include "lldb/Core/ArchSpec.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/ABI.h"
22 #include "lldb/Target/ExecutionContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/RegisterContext.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Target/UnwindAssembly.h"
28 #include "lldb/Utility/RegisterNumber.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 enum CPU { k_i386, k_x86_64 };
34 
35 enum i386_register_numbers {
36   k_machine_eax = 0,
37   k_machine_ecx = 1,
38   k_machine_edx = 2,
39   k_machine_ebx = 3,
40   k_machine_esp = 4,
41   k_machine_ebp = 5,
42   k_machine_esi = 6,
43   k_machine_edi = 7,
44   k_machine_eip = 8
45 };
46 
47 enum x86_64_register_numbers {
48   k_machine_rax = 0,
49   k_machine_rcx = 1,
50   k_machine_rdx = 2,
51   k_machine_rbx = 3,
52   k_machine_rsp = 4,
53   k_machine_rbp = 5,
54   k_machine_rsi = 6,
55   k_machine_rdi = 7,
56   k_machine_r8 = 8,
57   k_machine_r9 = 9,
58   k_machine_r10 = 10,
59   k_machine_r11 = 11,
60   k_machine_r12 = 12,
61   k_machine_r13 = 13,
62   k_machine_r14 = 14,
63   k_machine_r15 = 15,
64   k_machine_rip = 16
65 };
66 
67 struct regmap_ent {
68   const char *name;
69   int machine_regno;
70   int lldb_regno;
71 };
72 
73 static struct regmap_ent i386_register_map[] = {
74     {"eax", k_machine_eax, -1}, {"ecx", k_machine_ecx, -1},
75     {"edx", k_machine_edx, -1}, {"ebx", k_machine_ebx, -1},
76     {"esp", k_machine_esp, -1}, {"ebp", k_machine_ebp, -1},
77     {"esi", k_machine_esi, -1}, {"edi", k_machine_edi, -1},
78     {"eip", k_machine_eip, -1}};
79 
80 const int size_of_i386_register_map = llvm::array_lengthof(i386_register_map);
81 
82 static int i386_register_map_initialized = 0;
83 
84 static struct regmap_ent x86_64_register_map[] = {
85     {"rax", k_machine_rax, -1}, {"rcx", k_machine_rcx, -1},
86     {"rdx", k_machine_rdx, -1}, {"rbx", k_machine_rbx, -1},
87     {"rsp", k_machine_rsp, -1}, {"rbp", k_machine_rbp, -1},
88     {"rsi", k_machine_rsi, -1}, {"rdi", k_machine_rdi, -1},
89     {"r8", k_machine_r8, -1},   {"r9", k_machine_r9, -1},
90     {"r10", k_machine_r10, -1}, {"r11", k_machine_r11, -1},
91     {"r12", k_machine_r12, -1}, {"r13", k_machine_r13, -1},
92     {"r14", k_machine_r14, -1}, {"r15", k_machine_r15, -1},
93     {"rip", k_machine_rip, -1}};
94 
95 const int size_of_x86_64_register_map =
96     llvm::array_lengthof(x86_64_register_map);
97 
98 static int x86_64_register_map_initialized = 0;
99 
100 //-----------------------------------------------------------------------------------------------
101 //  AssemblyParse_x86 local-file class definition & implementation functions
102 //-----------------------------------------------------------------------------------------------
103 
104 class AssemblyParse_x86 {
105 public:
106   AssemblyParse_x86(const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch,
107                     AddressRange func);
108 
109   ~AssemblyParse_x86();
110 
111   bool get_non_call_site_unwind_plan(UnwindPlan &unwind_plan);
112 
113   bool augment_unwind_plan_from_call_site(AddressRange &func,
114                                           UnwindPlan &unwind_plan);
115 
116   bool get_fast_unwind_plan(AddressRange &func, UnwindPlan &unwind_plan);
117 
118   bool find_first_non_prologue_insn(Address &address);
119 
120 private:
121   enum { kMaxInstructionByteSize = 32 };
122 
123   bool nonvolatile_reg_p(int machine_regno);
124   bool push_rbp_pattern_p();
125   bool push_0_pattern_p();
126   bool mov_rsp_rbp_pattern_p();
127   bool sub_rsp_pattern_p(int &amount);
128   bool add_rsp_pattern_p(int &amount);
129   bool lea_rsp_pattern_p(int &amount);
130   bool push_reg_p(int &regno);
131   bool pop_reg_p(int &regno);
132   bool push_imm_pattern_p();
133   bool mov_reg_to_local_stack_frame_p(int &regno, int &fp_offset);
134   bool ret_pattern_p();
135   bool pop_rbp_pattern_p();
136   bool leave_pattern_p();
137   bool call_next_insn_pattern_p();
138   uint32_t extract_4(uint8_t *b);
139   bool machine_regno_to_lldb_regno(int machine_regno, uint32_t &lldb_regno);
140   bool instruction_length(Address addr, int &length);
141 
142   const ExecutionContext m_exe_ctx;
143 
144   AddressRange m_func_bounds;
145 
146   Address m_cur_insn;
147   uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
148 
149   uint32_t m_machine_ip_regnum;
150   uint32_t m_machine_sp_regnum;
151   uint32_t m_machine_fp_regnum;
152 
153   uint32_t m_lldb_ip_regnum;
154   uint32_t m_lldb_sp_regnum;
155   uint32_t m_lldb_fp_regnum;
156 
157   int m_wordsize;
158   int m_cpu;
159   ArchSpec m_arch;
160   ::LLVMDisasmContextRef m_disasm_context;
161 
162   DISALLOW_COPY_AND_ASSIGN(AssemblyParse_x86);
163 };
164 
165 AssemblyParse_x86::AssemblyParse_x86(const ExecutionContext &exe_ctx, int cpu,
166                                      ArchSpec &arch, AddressRange func)
167     : m_exe_ctx(exe_ctx), m_func_bounds(func), m_cur_insn(),
168       m_machine_ip_regnum(LLDB_INVALID_REGNUM),
169       m_machine_sp_regnum(LLDB_INVALID_REGNUM),
170       m_machine_fp_regnum(LLDB_INVALID_REGNUM),
171       m_lldb_ip_regnum(LLDB_INVALID_REGNUM),
172       m_lldb_sp_regnum(LLDB_INVALID_REGNUM),
173       m_lldb_fp_regnum(LLDB_INVALID_REGNUM), m_wordsize(-1), m_cpu(cpu),
174       m_arch(arch) {
175   int *initialized_flag = NULL;
176   if (cpu == k_i386) {
177     m_machine_ip_regnum = k_machine_eip;
178     m_machine_sp_regnum = k_machine_esp;
179     m_machine_fp_regnum = k_machine_ebp;
180     m_wordsize = 4;
181     initialized_flag = &i386_register_map_initialized;
182   } else {
183     m_machine_ip_regnum = k_machine_rip;
184     m_machine_sp_regnum = k_machine_rsp;
185     m_machine_fp_regnum = k_machine_rbp;
186     m_wordsize = 8;
187     initialized_flag = &x86_64_register_map_initialized;
188   }
189 
190   // we only look at prologue - it will be complete earlier than 512 bytes into
191   // func
192   if (m_func_bounds.GetByteSize() == 0)
193     m_func_bounds.SetByteSize(512);
194 
195   Thread *thread = m_exe_ctx.GetThreadPtr();
196   if (thread && *initialized_flag == 0) {
197     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
198     if (reg_ctx) {
199       struct regmap_ent *ent;
200       int count, i;
201       if (cpu == k_i386) {
202         ent = i386_register_map;
203         count = size_of_i386_register_map;
204       } else {
205         ent = x86_64_register_map;
206         count = size_of_x86_64_register_map;
207       }
208       for (i = 0; i < count; i++, ent++) {
209         const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName(ent->name);
210         if (ri)
211           ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
212       }
213       *initialized_flag = 1;
214     }
215   }
216 
217   // on initial construction we may not have a Thread so these have to remain
218   // uninitialized until we can get a RegisterContext to set up the register map
219   // table
220   if (*initialized_flag == 1) {
221     uint32_t lldb_regno;
222     if (machine_regno_to_lldb_regno(m_machine_sp_regnum, lldb_regno))
223       m_lldb_sp_regnum = lldb_regno;
224     if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
225       m_lldb_fp_regnum = lldb_regno;
226     if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
227       m_lldb_ip_regnum = lldb_regno;
228   }
229 
230   m_disasm_context =
231       ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(), (void *)this,
232                          /*TagType=*/1, NULL, NULL);
233 }
234 
235 AssemblyParse_x86::~AssemblyParse_x86() {
236   ::LLVMDisasmDispose(m_disasm_context);
237 }
238 
239 // This function expects an x86 native register number (i.e. the bits stripped
240 // out of the
241 // actual instruction), not an lldb register number.
242 
243 bool AssemblyParse_x86::nonvolatile_reg_p(int machine_regno) {
244   if (m_cpu == k_i386) {
245     switch (machine_regno) {
246     case k_machine_ebx:
247     case k_machine_ebp: // not actually a nonvolatile but often treated as such
248                         // by convention
249     case k_machine_esi:
250     case k_machine_edi:
251     case k_machine_esp:
252       return true;
253     default:
254       return false;
255     }
256   }
257   if (m_cpu == k_x86_64) {
258     switch (machine_regno) {
259     case k_machine_rbx:
260     case k_machine_rsp:
261     case k_machine_rbp: // not actually a nonvolatile but often treated as such
262                         // by convention
263     case k_machine_r12:
264     case k_machine_r13:
265     case k_machine_r14:
266     case k_machine_r15:
267       return true;
268     default:
269       return false;
270     }
271   }
272   return false;
273 }
274 
275 // Macro to detect if this is a REX mode prefix byte.
276 #define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
277 
278 // The high bit which should be added to the source register number (the "R"
279 // bit)
280 #define REX_W_SRCREG(opcode) (((opcode)&0x4) >> 2)
281 
282 // The high bit which should be added to the destination register number (the
283 // "B" bit)
284 #define REX_W_DSTREG(opcode) ((opcode)&0x1)
285 
286 // pushq %rbp [0x55]
287 bool AssemblyParse_x86::push_rbp_pattern_p() {
288   uint8_t *p = m_cur_insn_bytes;
289   if (*p == 0x55)
290     return true;
291   return false;
292 }
293 
294 // pushq $0 ; the first instruction in start() [0x6a 0x00]
295 bool AssemblyParse_x86::push_0_pattern_p() {
296   uint8_t *p = m_cur_insn_bytes;
297   if (*p == 0x6a && *(p + 1) == 0x0)
298     return true;
299   return false;
300 }
301 
302 // pushq $0
303 // pushl $0
304 bool AssemblyParse_x86::push_imm_pattern_p() {
305   uint8_t *p = m_cur_insn_bytes;
306   if (*p == 0x68 || *p == 0x6a)
307     return true;
308   return false;
309 }
310 
311 // movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
312 // movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
313 bool AssemblyParse_x86::mov_rsp_rbp_pattern_p() {
314   uint8_t *p = m_cur_insn_bytes;
315   if (m_wordsize == 8 && *p == 0x48)
316     p++;
317   if (*(p) == 0x8b && *(p + 1) == 0xec)
318     return true;
319   if (*(p) == 0x89 && *(p + 1) == 0xe5)
320     return true;
321   return false;
322 }
323 
324 // subq $0x20, %rsp
325 bool AssemblyParse_x86::sub_rsp_pattern_p(int &amount) {
326   uint8_t *p = m_cur_insn_bytes;
327   if (m_wordsize == 8 && *p == 0x48)
328     p++;
329   // 8-bit immediate operand
330   if (*p == 0x83 && *(p + 1) == 0xec) {
331     amount = (int8_t) * (p + 2);
332     return true;
333   }
334   // 32-bit immediate operand
335   if (*p == 0x81 && *(p + 1) == 0xec) {
336     amount = (int32_t)extract_4(p + 2);
337     return true;
338   }
339   return false;
340 }
341 
342 // addq $0x20, %rsp
343 bool AssemblyParse_x86::add_rsp_pattern_p(int &amount) {
344   uint8_t *p = m_cur_insn_bytes;
345   if (m_wordsize == 8 && *p == 0x48)
346     p++;
347   // 8-bit immediate operand
348   if (*p == 0x83 && *(p + 1) == 0xc4) {
349     amount = (int8_t) * (p + 2);
350     return true;
351   }
352   // 32-bit immediate operand
353   if (*p == 0x81 && *(p + 1) == 0xc4) {
354     amount = (int32_t)extract_4(p + 2);
355     return true;
356   }
357   return false;
358 }
359 
360 // lea esp, [esp - 0x28]
361 // lea esp, [esp + 0x28]
362 bool AssemblyParse_x86::lea_rsp_pattern_p(int &amount) {
363   uint8_t *p = m_cur_insn_bytes;
364   if (m_wordsize == 8 && *p == 0x48)
365     p++;
366 
367   // Check opcode
368   if (*p != 0x8d)
369     return false;
370 
371   // 8 bit displacement
372   if (*(p + 1) == 0x64 && (*(p + 2) & 0x3f) == 0x24) {
373     amount = (int8_t) * (p + 3);
374     return true;
375   }
376 
377   // 32 bit displacement
378   if (*(p + 1) == 0xa4 && (*(p + 2) & 0x3f) == 0x24) {
379     amount = (int32_t)extract_4(p + 3);
380     return true;
381   }
382 
383   return false;
384 }
385 
386 // pushq %rbx
387 // pushl %ebx
388 bool AssemblyParse_x86::push_reg_p(int &regno) {
389   uint8_t *p = m_cur_insn_bytes;
390   int regno_prefix_bit = 0;
391   // If we have a rex prefix byte, check to see if a B bit is set
392   if (m_wordsize == 8 && *p == 0x41) {
393     regno_prefix_bit = 1 << 3;
394     p++;
395   }
396   if (*p >= 0x50 && *p <= 0x57) {
397     regno = (*p - 0x50) | regno_prefix_bit;
398     return true;
399   }
400   return false;
401 }
402 
403 // popq %rbx
404 // popl %ebx
405 bool AssemblyParse_x86::pop_reg_p(int &regno) {
406   uint8_t *p = m_cur_insn_bytes;
407   int regno_prefix_bit = 0;
408   // If we have a rex prefix byte, check to see if a B bit is set
409   if (m_wordsize == 8 && *p == 0x41) {
410     regno_prefix_bit = 1 << 3;
411     p++;
412   }
413   if (*p >= 0x58 && *p <= 0x5f) {
414     regno = (*p - 0x58) | regno_prefix_bit;
415     return true;
416   }
417   return false;
418 }
419 
420 // popq %rbp [0x5d]
421 // popl %ebp [0x5d]
422 bool AssemblyParse_x86::pop_rbp_pattern_p() {
423   uint8_t *p = m_cur_insn_bytes;
424   return (*p == 0x5d);
425 }
426 
427 // leave [0xc9]
428 bool AssemblyParse_x86::leave_pattern_p() {
429   uint8_t *p = m_cur_insn_bytes;
430   return (*p == 0xc9);
431 }
432 
433 // call $0 [0xe8 0x0 0x0 0x0 0x0]
434 bool AssemblyParse_x86::call_next_insn_pattern_p() {
435   uint8_t *p = m_cur_insn_bytes;
436   return (*p == 0xe8) && (*(p + 1) == 0x0) && (*(p + 2) == 0x0) &&
437          (*(p + 3) == 0x0) && (*(p + 4) == 0x0);
438 }
439 
440 // Look for an instruction sequence storing a nonvolatile register
441 // on to the stack frame.
442 
443 //  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
444 //  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]
445 
446 // The offset value returned in rbp_offset will be positive --
447 // but it must be subtraced from the frame base register to get
448 // the actual location.  The positive value returned for the offset
449 // is a convention used elsewhere for CFA offsets et al.
450 
451 bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p(int &regno,
452                                                        int &rbp_offset) {
453   uint8_t *p = m_cur_insn_bytes;
454   int src_reg_prefix_bit = 0;
455   int target_reg_prefix_bit = 0;
456 
457   if (m_wordsize == 8 && REX_W_PREFIX_P(*p)) {
458     src_reg_prefix_bit = REX_W_SRCREG(*p) << 3;
459     target_reg_prefix_bit = REX_W_DSTREG(*p) << 3;
460     if (target_reg_prefix_bit == 1) {
461       // rbp/ebp don't need a prefix bit - we know this isn't the
462       // reg we care about.
463       return false;
464     }
465     p++;
466   }
467 
468   if (*p == 0x89) {
469     /* Mask off the 3-5 bits which indicate the destination register
470        if this is a ModR/M byte.  */
471     int opcode_destreg_masked_out = *(p + 1) & (~0x38);
472 
473     /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
474        and three bits between them, e.g. 01nnn101
475        We're looking for a destination of ebp-disp8 or ebp-disp32.   */
476     int immsize;
477     if (opcode_destreg_masked_out == 0x45)
478       immsize = 2;
479     else if (opcode_destreg_masked_out == 0x85)
480       immsize = 4;
481     else
482       return false;
483 
484     int offset = 0;
485     if (immsize == 2)
486       offset = (int8_t) * (p + 2);
487     if (immsize == 4)
488       offset = (uint32_t)extract_4(p + 2);
489     if (offset > 0)
490       return false;
491 
492     regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
493     rbp_offset = offset > 0 ? offset : -offset;
494     return true;
495   }
496   return false;
497 }
498 
499 // ret [0xc9] or [0xc2 imm8] or [0xca imm8]
500 bool AssemblyParse_x86::ret_pattern_p() {
501   uint8_t *p = m_cur_insn_bytes;
502   if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
503     return true;
504   return false;
505 }
506 
507 uint32_t AssemblyParse_x86::extract_4(uint8_t *b) {
508   uint32_t v = 0;
509   for (int i = 3; i >= 0; i--)
510     v = (v << 8) | b[i];
511   return v;
512 }
513 
514 bool AssemblyParse_x86::machine_regno_to_lldb_regno(int machine_regno,
515                                                     uint32_t &lldb_regno) {
516   struct regmap_ent *ent;
517   int count, i;
518   if (m_cpu == k_i386) {
519     ent = i386_register_map;
520     count = size_of_i386_register_map;
521   } else {
522     ent = x86_64_register_map;
523     count = size_of_x86_64_register_map;
524   }
525   for (i = 0; i < count; i++, ent++) {
526     if (ent->machine_regno == machine_regno)
527       if (ent->lldb_regno != -1) {
528         lldb_regno = ent->lldb_regno;
529         return true;
530       }
531   }
532   return false;
533 }
534 
535 bool AssemblyParse_x86::instruction_length(Address addr, int &length) {
536   const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
537   llvm::SmallVector<uint8_t, 32> opcode_data;
538   opcode_data.resize(max_op_byte_size);
539 
540   if (!addr.IsValid())
541     return false;
542 
543   const bool prefer_file_cache = true;
544   Error error;
545   Target *target = m_exe_ctx.GetTargetPtr();
546   if (target->ReadMemory(addr, prefer_file_cache, opcode_data.data(),
547                          max_op_byte_size, error) == static_cast<size_t>(-1)) {
548     return false;
549   }
550 
551   char out_string[512];
552   const addr_t pc = addr.GetFileAddress();
553   const size_t inst_size = ::LLVMDisasmInstruction(
554       m_disasm_context, opcode_data.data(), max_op_byte_size,
555       pc, // PC value
556       out_string, sizeof(out_string));
557 
558   length = inst_size;
559   return true;
560 }
561 
562 bool AssemblyParse_x86::get_non_call_site_unwind_plan(UnwindPlan &unwind_plan) {
563   UnwindPlan::RowSP row(new UnwindPlan::Row);
564   m_cur_insn = m_func_bounds.GetBaseAddress();
565   addr_t current_func_text_offset = 0;
566   int current_sp_bytes_offset_from_cfa = 0;
567   UnwindPlan::Row::RegisterLocation initial_regloc;
568   Error error;
569 
570   if (!m_cur_insn.IsValid()) {
571     return false;
572   }
573 
574   unwind_plan.SetPlanValidAddressRange(m_func_bounds);
575   unwind_plan.SetRegisterKind(eRegisterKindLLDB);
576 
577   // At the start of the function, find the CFA by adding wordsize to the SP
578   // register
579   row->SetOffset(current_func_text_offset);
580   row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
581 
582   // caller's stack pointer value before the call insn is the CFA address
583   initial_regloc.SetIsCFAPlusOffset(0);
584   row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc);
585 
586   // saved instruction pointer can be found at CFA - wordsize.
587   current_sp_bytes_offset_from_cfa = m_wordsize;
588   initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
589   row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);
590 
591   unwind_plan.AppendRow(row);
592 
593   // Allocate a new Row, populate it with the existing Row contents.
594   UnwindPlan::Row *newrow = new UnwindPlan::Row;
595   *newrow = *row.get();
596   row.reset(newrow);
597 
598   // Track which registers have been saved so far in the prologue.
599   // If we see another push of that register, it's not part of the prologue.
600   // The register numbers used here are the machine register #'s
601   // (i386_register_numbers, x86_64_register_numbers).
602   std::vector<bool> saved_registers(32, false);
603 
604   const bool prefer_file_cache = true;
605 
606   // Once the prologue has completed we'll save a copy of the unwind
607   // instructions
608   // If there is an epilogue in the middle of the function, after that epilogue
609   // we'll reinstate
610   // the unwind setup -- we assume that some code path jumps over the
611   // mid-function epilogue
612 
613   UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
614   int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the
615                                                    // epilogue started executed
616   std::vector<bool> prologue_completed_saved_registers;
617 
618   Target *target = m_exe_ctx.GetTargetPtr();
619   while (m_func_bounds.ContainsFileAddress(m_cur_insn)) {
620     int stack_offset, insn_len;
621     int machine_regno;   // register numbers masked directly out of instructions
622     uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB
623                          // numbering scheme
624 
625     bool in_epilogue = false; // we're in the middle of an epilogue sequence
626     bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
627 
628     if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
629         insn_len > kMaxInstructionByteSize) {
630       // An unrecognized/junk instruction
631       break;
632     }
633 
634     if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
635                            insn_len, error) == static_cast<size_t>(-1)) {
636       // Error reading the instruction out of the file, stop scanning
637       break;
638     }
639 
640     if (push_rbp_pattern_p()) {
641       current_sp_bytes_offset_from_cfa += m_wordsize;
642       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
643       UnwindPlan::Row::RegisterLocation regloc;
644       regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset());
645       row->SetRegisterInfo(m_lldb_fp_regnum, regloc);
646       saved_registers[m_machine_fp_regnum] = true;
647       row_updated = true;
648     }
649 
650     else if (mov_rsp_rbp_pattern_p()) {
651       row->GetCFAValue().SetIsRegisterPlusOffset(
652           m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
653       row_updated = true;
654     }
655 
656     // This is the start() function (or a pthread equivalent), it starts with a
657     // pushl $0x0 which puts the
658     // saved pc value of 0 on the stack.  In this case we want to pretend we
659     // didn't see a stack movement at all --
660     // normally the saved pc value is already on the stack by the time the
661     // function starts executing.
662     else if (push_0_pattern_p()) {
663     }
664 
665     else if (push_reg_p(machine_regno)) {
666       current_sp_bytes_offset_from_cfa += m_wordsize;
667       // the PUSH instruction has moved the stack pointer - if the CFA is set in
668       // terms of the stack pointer,
669       // we need to add a new row of instructions.
670       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
671         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
672         row_updated = true;
673       }
674       // record where non-volatile (callee-saved, spilled) registers are saved
675       // on the stack
676       if (nonvolatile_reg_p(machine_regno) &&
677           machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
678           saved_registers[machine_regno] == false) {
679         UnwindPlan::Row::RegisterLocation regloc;
680         regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
681         row->SetRegisterInfo(lldb_regno, regloc);
682         saved_registers[machine_regno] = true;
683         row_updated = true;
684       }
685     }
686 
687     else if (pop_reg_p(machine_regno)) {
688       current_sp_bytes_offset_from_cfa -= m_wordsize;
689 
690       if (nonvolatile_reg_p(machine_regno) &&
691           machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
692           saved_registers[machine_regno] == true) {
693         saved_registers[machine_regno] = false;
694         row->RemoveRegisterInfo(lldb_regno);
695 
696         if (machine_regno == (int)m_machine_fp_regnum) {
697           row->GetCFAValue().SetIsRegisterPlusOffset(
698               m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
699         }
700 
701         in_epilogue = true;
702         row_updated = true;
703       }
704 
705       // the POP instruction has moved the stack pointer - if the CFA is set in
706       // terms of the stack pointer,
707       // we need to add a new row of instructions.
708       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
709         row->GetCFAValue().SetIsRegisterPlusOffset(
710             m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
711         row_updated = true;
712       }
713     }
714 
715     // The LEAVE instruction moves the value from rbp into rsp and pops
716     // a value off the stack into rbp (restoring the caller's rbp value).
717     // It is the opposite of ENTER, or 'push rbp, mov rsp rbp'.
718     else if (leave_pattern_p()) {
719       // We're going to copy the value in rbp into rsp, so re-set the sp offset
720       // based on the CFAValue.  Also, adjust it to recognize that we're popping
721       // the saved rbp value off the stack.
722       current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
723       current_sp_bytes_offset_from_cfa -= m_wordsize;
724       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
725 
726       // rbp is restored to the caller's value
727       saved_registers[m_machine_fp_regnum] = false;
728       row->RemoveRegisterInfo(m_lldb_fp_regnum);
729 
730       // cfa is now in terms of rsp again.
731       row->GetCFAValue().SetIsRegisterPlusOffset(
732           m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
733       row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
734 
735       in_epilogue = true;
736       row_updated = true;
737     }
738 
739     else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) &&
740              nonvolatile_reg_p(machine_regno) &&
741              machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
742              saved_registers[machine_regno] == false) {
743       saved_registers[machine_regno] = true;
744 
745       UnwindPlan::Row::RegisterLocation regloc;
746 
747       // stack_offset for 'movq %r15, -80(%rbp)' will be 80.
748       // In the Row, we want to express this as the offset from the CFA.  If the
749       // frame base
750       // is rbp (like the above instruction), the CFA offset for rbp is probably
751       // 16.  So we
752       // want to say that the value is stored at the CFA address - 96.
753       regloc.SetAtCFAPlusOffset(
754           -(stack_offset + row->GetCFAValue().GetOffset()));
755 
756       row->SetRegisterInfo(lldb_regno, regloc);
757 
758       row_updated = true;
759     }
760 
761     else if (sub_rsp_pattern_p(stack_offset)) {
762       current_sp_bytes_offset_from_cfa += stack_offset;
763       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
764         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
765         row_updated = true;
766       }
767     }
768 
769     else if (add_rsp_pattern_p(stack_offset)) {
770       current_sp_bytes_offset_from_cfa -= stack_offset;
771       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
772         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
773         row_updated = true;
774       }
775       in_epilogue = true;
776     }
777 
778     else if (lea_rsp_pattern_p(stack_offset)) {
779       current_sp_bytes_offset_from_cfa -= stack_offset;
780       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
781         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
782         row_updated = true;
783       }
784       if (stack_offset > 0)
785         in_epilogue = true;
786     }
787 
788     else if (ret_pattern_p() && prologue_completed_row.get()) {
789       // Reinstate the saved prologue setup for any instructions
790       // that come after the ret instruction
791 
792       UnwindPlan::Row *newrow = new UnwindPlan::Row;
793       *newrow = *prologue_completed_row.get();
794       row.reset(newrow);
795       current_sp_bytes_offset_from_cfa =
796           prologue_completed_sp_bytes_offset_from_cfa;
797 
798       saved_registers.clear();
799       saved_registers.resize(prologue_completed_saved_registers.size(), false);
800       for (size_t i = 0; i < prologue_completed_saved_registers.size(); ++i) {
801         saved_registers[i] = prologue_completed_saved_registers[i];
802       }
803 
804       in_epilogue = true;
805       row_updated = true;
806     }
807 
808     // call next instruction
809     //     call 0
810     //  => pop  %ebx
811     // This is used in i386 programs to get the PIC base address for finding
812     // global data
813     else if (call_next_insn_pattern_p()) {
814       current_sp_bytes_offset_from_cfa += m_wordsize;
815       if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
816         row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
817         row_updated = true;
818       }
819     }
820 
821     if (row_updated) {
822       if (current_func_text_offset + insn_len < m_func_bounds.GetByteSize()) {
823         row->SetOffset(current_func_text_offset + insn_len);
824         unwind_plan.AppendRow(row);
825         // Allocate a new Row, populate it with the existing Row contents.
826         newrow = new UnwindPlan::Row;
827         *newrow = *row.get();
828         row.reset(newrow);
829       }
830     }
831 
832     if (in_epilogue == false && row_updated) {
833       // If we're not in an epilogue sequence, save the updated Row
834       UnwindPlan::Row *newrow = new UnwindPlan::Row;
835       *newrow = *row.get();
836       prologue_completed_row.reset(newrow);
837 
838       prologue_completed_saved_registers.clear();
839       prologue_completed_saved_registers.resize(saved_registers.size(), false);
840       for (size_t i = 0; i < saved_registers.size(); ++i) {
841         prologue_completed_saved_registers[i] = saved_registers[i];
842       }
843     }
844 
845     // We may change the sp value without adding a new Row necessarily -- keep
846     // track of it either way.
847     if (in_epilogue == false) {
848       prologue_completed_sp_bytes_offset_from_cfa =
849           current_sp_bytes_offset_from_cfa;
850     }
851 
852     m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
853     current_func_text_offset += insn_len;
854   }
855 
856   unwind_plan.SetSourceName("assembly insn profiling");
857   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
858   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
859 
860   return true;
861 }
862 
863 bool AssemblyParse_x86::augment_unwind_plan_from_call_site(
864     AddressRange &func, UnwindPlan &unwind_plan) {
865   // Is func address valid?
866   Address addr_start = func.GetBaseAddress();
867   if (!addr_start.IsValid())
868     return false;
869 
870   // Is original unwind_plan valid?
871   // unwind_plan should have at least one row which is ABI-default (CFA register
872   // is sp),
873   // and another row in mid-function.
874   if (unwind_plan.GetRowCount() < 2)
875     return false;
876   UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex(0);
877   if (first_row->GetOffset() != 0)
878     return false;
879   uint32_t cfa_reg = m_exe_ctx.GetThreadPtr()
880                          ->GetRegisterContext()
881                          ->ConvertRegisterKindToRegisterNumber(
882                              unwind_plan.GetRegisterKind(),
883                              first_row->GetCFAValue().GetRegisterNumber());
884   if (cfa_reg != m_lldb_sp_regnum ||
885       first_row->GetCFAValue().GetOffset() != m_wordsize)
886     return false;
887 
888   UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset(-1);
889 
890   Target *target = m_exe_ctx.GetTargetPtr();
891   m_cur_insn = func.GetBaseAddress();
892   uint64_t offset = 0;
893   int row_id = 1;
894   bool unwind_plan_updated = false;
895   UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
896 
897   // After a mid-function epilogue we will need to re-insert the original unwind
898   // rules
899   // so unwinds work for the remainder of the function.  These aren't common
900   // with clang/gcc
901   // on x86 but it is possible.
902   bool reinstate_unwind_state = false;
903 
904   while (func.ContainsFileAddress(m_cur_insn)) {
905     int insn_len;
906     if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
907         insn_len > kMaxInstructionByteSize) {
908       // An unrecognized/junk instruction.
909       break;
910     }
911     const bool prefer_file_cache = true;
912     Error error;
913     if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
914                            insn_len, error) == static_cast<size_t>(-1)) {
915       // Error reading the instruction out of the file, stop scanning.
916       break;
917     }
918 
919     // Advance offsets.
920     offset += insn_len;
921     m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
922 
923     if (reinstate_unwind_state) {
924       // that was the last instruction of this function
925       if (func.ContainsFileAddress(m_cur_insn) == false)
926         continue;
927 
928       UnwindPlan::RowSP new_row(new UnwindPlan::Row());
929       *new_row = *original_last_row;
930       new_row->SetOffset(offset);
931       unwind_plan.AppendRow(new_row);
932       row.reset(new UnwindPlan::Row());
933       *row = *new_row;
934       reinstate_unwind_state = false;
935       unwind_plan_updated = true;
936       continue;
937     }
938 
939     // If we already have one row for this instruction, we can continue.
940     while (row_id < unwind_plan.GetRowCount() &&
941            unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) {
942       row_id++;
943     }
944     UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex(row_id - 1);
945     if (original_row->GetOffset() == offset) {
946       *row = *original_row;
947       continue;
948     }
949 
950     if (row_id == 0) {
951       // If we are here, compiler didn't generate CFI for prologue.
952       // This won't happen to GCC or clang.
953       // In this case, bail out directly.
954       return false;
955     }
956 
957     // Inspect the instruction to check if we need a new row for it.
958     cfa_reg = m_exe_ctx.GetThreadPtr()
959                   ->GetRegisterContext()
960                   ->ConvertRegisterKindToRegisterNumber(
961                       unwind_plan.GetRegisterKind(),
962                       row->GetCFAValue().GetRegisterNumber());
963     if (cfa_reg == m_lldb_sp_regnum) {
964       // CFA register is sp.
965 
966       // call next instruction
967       //     call 0
968       //  => pop  %ebx
969       if (call_next_insn_pattern_p()) {
970         row->SetOffset(offset);
971         row->GetCFAValue().IncOffset(m_wordsize);
972 
973         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
974         unwind_plan.InsertRow(new_row);
975         unwind_plan_updated = true;
976         continue;
977       }
978 
979       // push/pop register
980       int regno;
981       if (push_reg_p(regno)) {
982         row->SetOffset(offset);
983         row->GetCFAValue().IncOffset(m_wordsize);
984 
985         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
986         unwind_plan.InsertRow(new_row);
987         unwind_plan_updated = true;
988         continue;
989       }
990       if (pop_reg_p(regno)) {
991         // Technically, this might be a nonvolatile register recover in
992         // epilogue.
993         // We should reset RegisterInfo for the register.
994         // But in practice, previous rule for the register is still valid...
995         // So we ignore this case.
996 
997         row->SetOffset(offset);
998         row->GetCFAValue().IncOffset(-m_wordsize);
999 
1000         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1001         unwind_plan.InsertRow(new_row);
1002         unwind_plan_updated = true;
1003         continue;
1004       }
1005 
1006       // push imm
1007       if (push_imm_pattern_p()) {
1008         row->SetOffset(offset);
1009         row->GetCFAValue().IncOffset(m_wordsize);
1010         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1011         unwind_plan.InsertRow(new_row);
1012         unwind_plan_updated = true;
1013         continue;
1014       }
1015 
1016       // add/sub %rsp/%esp
1017       int amount;
1018       if (add_rsp_pattern_p(amount)) {
1019         row->SetOffset(offset);
1020         row->GetCFAValue().IncOffset(-amount);
1021 
1022         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1023         unwind_plan.InsertRow(new_row);
1024         unwind_plan_updated = true;
1025         continue;
1026       }
1027       if (sub_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       // lea %rsp, [%rsp + $offset]
1038       if (lea_rsp_pattern_p(amount)) {
1039         row->SetOffset(offset);
1040         row->GetCFAValue().IncOffset(-amount);
1041 
1042         UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1043         unwind_plan.InsertRow(new_row);
1044         unwind_plan_updated = true;
1045         continue;
1046       }
1047 
1048       if (ret_pattern_p()) {
1049         reinstate_unwind_state = true;
1050         continue;
1051       }
1052     } else if (cfa_reg == m_lldb_fp_regnum) {
1053       // CFA register is fp.
1054 
1055       // The only case we care about is epilogue:
1056       //     [0x5d] pop %rbp/%ebp
1057       //  => [0xc3] ret
1058       if (pop_rbp_pattern_p() || leave_pattern_p()) {
1059         if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
1060                                1, error) != static_cast<size_t>(-1) &&
1061             ret_pattern_p()) {
1062           row->SetOffset(offset);
1063           row->GetCFAValue().SetIsRegisterPlusOffset(
1064               first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
1065 
1066           UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
1067           unwind_plan.InsertRow(new_row);
1068           unwind_plan_updated = true;
1069           reinstate_unwind_state = true;
1070           continue;
1071         }
1072       }
1073     } else {
1074       // CFA register is not sp or fp.
1075 
1076       // This must be hand-written assembly.
1077       // Just trust eh_frame and assume we have finished.
1078       break;
1079     }
1080   }
1081 
1082   unwind_plan.SetPlanValidAddressRange(func);
1083   if (unwind_plan_updated) {
1084     std::string unwind_plan_source(unwind_plan.GetSourceName().AsCString());
1085     unwind_plan_source += " plus augmentation from assembly parsing";
1086     unwind_plan.SetSourceName(unwind_plan_source.c_str());
1087     unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1088     unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1089   }
1090   return true;
1091 }
1092 
1093 /* The "fast unwind plan" is valid for functions that follow the usual
1094    convention of
1095    using the frame pointer register (ebp, rbp), i.e. the function prologue looks
1096    like
1097      push   %rbp      [0x55]
1098      mov    %rsp,%rbp [0x48 0x89 0xe5]   (this is a 2-byte insn seq on i386)
1099 */
1100 
1101 bool AssemblyParse_x86::get_fast_unwind_plan(AddressRange &func,
1102                                              UnwindPlan &unwind_plan) {
1103   UnwindPlan::RowSP row(new UnwindPlan::Row);
1104   UnwindPlan::Row::RegisterLocation pc_reginfo;
1105   UnwindPlan::Row::RegisterLocation sp_reginfo;
1106   UnwindPlan::Row::RegisterLocation fp_reginfo;
1107   unwind_plan.SetRegisterKind(eRegisterKindLLDB);
1108 
1109   if (!func.GetBaseAddress().IsValid())
1110     return false;
1111 
1112   Target *target = m_exe_ctx.GetTargetPtr();
1113 
1114   uint8_t bytebuf[4];
1115   Error error;
1116   const bool prefer_file_cache = true;
1117   if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache, bytebuf,
1118                          sizeof(bytebuf), error) == static_cast<size_t>(-1))
1119     return false;
1120 
1121   uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
1122   uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
1123   int prologue_size;
1124 
1125   if (memcmp(bytebuf, i386_prologue, sizeof(i386_prologue)) == 0) {
1126     prologue_size = sizeof(i386_prologue);
1127   } else if (memcmp(bytebuf, x86_64_prologue, sizeof(x86_64_prologue)) == 0) {
1128     prologue_size = sizeof(x86_64_prologue);
1129   } else {
1130     return false;
1131   }
1132 
1133   pc_reginfo.SetAtCFAPlusOffset(-m_wordsize);
1134   row->SetRegisterInfo(m_lldb_ip_regnum, pc_reginfo);
1135 
1136   sp_reginfo.SetIsCFAPlusOffset(0);
1137   row->SetRegisterInfo(m_lldb_sp_regnum, sp_reginfo);
1138 
1139   // Zero instructions into the function
1140   row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
1141   row->SetOffset(0);
1142   unwind_plan.AppendRow(row);
1143   UnwindPlan::Row *newrow = new UnwindPlan::Row;
1144   *newrow = *row.get();
1145   row.reset(newrow);
1146 
1147   // push %rbp has executed - stack moved, rbp now saved
1148   row->GetCFAValue().IncOffset(m_wordsize);
1149   fp_reginfo.SetAtCFAPlusOffset(2 * -m_wordsize);
1150   row->SetRegisterInfo(m_lldb_fp_regnum, fp_reginfo);
1151   row->SetOffset(1);
1152   unwind_plan.AppendRow(row);
1153 
1154   newrow = new UnwindPlan::Row;
1155   *newrow = *row.get();
1156   row.reset(newrow);
1157 
1158   // mov %rsp, %rbp has executed
1159   row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_fp_regnum, 2 * m_wordsize);
1160   row->SetOffset(prologue_size); /// 3 or 4 bytes depending on arch
1161   unwind_plan.AppendRow(row);
1162 
1163   newrow = new UnwindPlan::Row;
1164   *newrow = *row.get();
1165   row.reset(newrow);
1166 
1167   unwind_plan.SetPlanValidAddressRange(func);
1168   unwind_plan.SetSourceName("fast unwind assembly profiling");
1169   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1170   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1171   return true;
1172 }
1173 
1174 bool AssemblyParse_x86::find_first_non_prologue_insn(Address &address) {
1175   m_cur_insn = m_func_bounds.GetBaseAddress();
1176   if (!m_cur_insn.IsValid()) {
1177     return false;
1178   }
1179 
1180   const bool prefer_file_cache = true;
1181   Target *target = m_exe_ctx.GetTargetPtr();
1182   while (m_func_bounds.ContainsFileAddress(m_cur_insn)) {
1183     Error error;
1184     int insn_len, offset, regno;
1185     if (!instruction_length(m_cur_insn, insn_len) ||
1186         insn_len > kMaxInstructionByteSize || insn_len == 0) {
1187       // An error parsing the instruction, i.e. probably data/garbage - stop
1188       // scanning
1189       break;
1190     }
1191     if (target->ReadMemory(m_cur_insn, prefer_file_cache, m_cur_insn_bytes,
1192                            insn_len, error) == static_cast<size_t>(-1)) {
1193       // Error reading the instruction out of the file, stop scanning
1194       break;
1195     }
1196 
1197     if (push_rbp_pattern_p() || mov_rsp_rbp_pattern_p() ||
1198         sub_rsp_pattern_p(offset) || push_reg_p(regno) ||
1199         mov_reg_to_local_stack_frame_p(regno, offset) ||
1200         (lea_rsp_pattern_p(offset) && offset < 0)) {
1201       m_cur_insn.SetOffset(m_cur_insn.GetOffset() + insn_len);
1202       continue;
1203     }
1204 
1205     // Unknown non-prologue instruction - stop scanning
1206     break;
1207   }
1208 
1209   address = m_cur_insn;
1210   return true;
1211 }
1212 
1213 //-----------------------------------------------------------------------------------------------
1214 //  UnwindAssemblyParser_x86 method definitions
1215 //-----------------------------------------------------------------------------------------------
1216 
1217 UnwindAssembly_x86::UnwindAssembly_x86(const ArchSpec &arch, int cpu)
1218     : lldb_private::UnwindAssembly(arch), m_cpu(cpu), m_arch(arch) {}
1219 
1220 UnwindAssembly_x86::~UnwindAssembly_x86() {}
1221 
1222 bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly(
1223     AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
1224   ExecutionContext exe_ctx(thread.shared_from_this());
1225   AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
1226   return asm_parse.get_non_call_site_unwind_plan(unwind_plan);
1227 }
1228 
1229 bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
1230     AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
1231   bool do_augment_unwindplan = true;
1232 
1233   UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset(0);
1234   UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset(-1);
1235 
1236   int wordsize = 8;
1237   ProcessSP process_sp(thread.GetProcess());
1238   if (process_sp) {
1239     wordsize = process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
1240   }
1241 
1242   RegisterNumber sp_regnum(thread, eRegisterKindGeneric,
1243                            LLDB_REGNUM_GENERIC_SP);
1244   RegisterNumber pc_regnum(thread, eRegisterKindGeneric,
1245                            LLDB_REGNUM_GENERIC_PC);
1246 
1247   // Does this UnwindPlan describe the prologue?  I want to see that the CFA is
1248   // set
1249   // in terms of the stack pointer plus an offset, and I want to see that rip is
1250   // retrieved at the CFA-wordsize.
1251   // If there is no description of the prologue, don't try to augment this
1252   // eh_frame
1253   // unwinder code, fall back to assembly parsing instead.
1254 
1255   if (first_row->GetCFAValue().GetValueType() !=
1256           UnwindPlan::Row::CFAValue::isRegisterPlusOffset ||
1257       RegisterNumber(thread, unwind_plan.GetRegisterKind(),
1258                      first_row->GetCFAValue().GetRegisterNumber()) !=
1259           sp_regnum ||
1260       first_row->GetCFAValue().GetOffset() != wordsize) {
1261     return false;
1262   }
1263   UnwindPlan::Row::RegisterLocation first_row_pc_loc;
1264   if (first_row->GetRegisterInfo(
1265           pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
1266           first_row_pc_loc) == false ||
1267       first_row_pc_loc.IsAtCFAPlusOffset() == false ||
1268       first_row_pc_loc.GetOffset() != -wordsize) {
1269     return false;
1270   }
1271 
1272   // It looks like the prologue is described.
1273   // Is the epilogue described?  If it is, no need to do any augmentation.
1274 
1275   if (first_row != last_row &&
1276       first_row->GetOffset() != last_row->GetOffset()) {
1277     // The first & last row have the same CFA register
1278     // and the same CFA offset value
1279     // and the CFA register is esp/rsp (the stack pointer).
1280 
1281     // We're checking that both of them have an unwind rule like "CFA=esp+4" or
1282     // CFA+rsp+8".
1283 
1284     if (first_row->GetCFAValue().GetValueType() ==
1285             last_row->GetCFAValue().GetValueType() &&
1286         first_row->GetCFAValue().GetRegisterNumber() ==
1287             last_row->GetCFAValue().GetRegisterNumber() &&
1288         first_row->GetCFAValue().GetOffset() ==
1289             last_row->GetCFAValue().GetOffset()) {
1290       // Get the register locations for eip/rip from the first & last rows.
1291       // Are they both CFA plus an offset?  Is it the same offset?
1292 
1293       UnwindPlan::Row::RegisterLocation last_row_pc_loc;
1294       if (last_row->GetRegisterInfo(
1295               pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
1296               last_row_pc_loc)) {
1297         if (last_row_pc_loc.IsAtCFAPlusOffset() &&
1298             first_row_pc_loc.GetOffset() == last_row_pc_loc.GetOffset()) {
1299 
1300           // One last sanity check:  Is the unwind rule for getting the caller
1301           // pc value
1302           // "deref the CFA-4" or "deref the CFA-8"?
1303 
1304           // If so, we have an UnwindPlan that already describes the epilogue
1305           // and we don't need
1306           // to modify it at all.
1307 
1308           if (first_row_pc_loc.GetOffset() == -wordsize) {
1309             do_augment_unwindplan = false;
1310           }
1311         }
1312       }
1313     }
1314   }
1315 
1316   if (do_augment_unwindplan) {
1317     ExecutionContext exe_ctx(thread.shared_from_this());
1318     AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
1319     return asm_parse.augment_unwind_plan_from_call_site(func, unwind_plan);
1320   }
1321 
1322   return false;
1323 }
1324 
1325 bool UnwindAssembly_x86::GetFastUnwindPlan(AddressRange &func, Thread &thread,
1326                                            UnwindPlan &unwind_plan) {
1327   // if prologue is
1328   //   55     pushl %ebp
1329   //   89 e5  movl %esp, %ebp
1330   //  or
1331   //   55        pushq %rbp
1332   //   48 89 e5  movq %rsp, %rbp
1333 
1334   // We should pull in the ABI architecture default unwind plan and return that
1335 
1336   llvm::SmallVector<uint8_t, 4> opcode_data;
1337 
1338   ProcessSP process_sp = thread.GetProcess();
1339   if (process_sp) {
1340     Target &target(process_sp->GetTarget());
1341     const bool prefer_file_cache = true;
1342     Error error;
1343     if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
1344                           opcode_data.data(), 4, error) == 4) {
1345       uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
1346       uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
1347 
1348       if (memcmp(opcode_data.data(), i386_push_mov, sizeof(i386_push_mov)) ==
1349               0 ||
1350           memcmp(opcode_data.data(), x86_64_push_mov,
1351                  sizeof(x86_64_push_mov)) == 0) {
1352         ABISP abi_sp = process_sp->GetABI();
1353         if (abi_sp) {
1354           return abi_sp->CreateDefaultUnwindPlan(unwind_plan);
1355         }
1356       }
1357     }
1358   }
1359   return false;
1360 }
1361 
1362 bool UnwindAssembly_x86::FirstNonPrologueInsn(
1363     AddressRange &func, const ExecutionContext &exe_ctx,
1364     Address &first_non_prologue_insn) {
1365   AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
1366   return asm_parse.find_first_non_prologue_insn(first_non_prologue_insn);
1367 }
1368 
1369 UnwindAssembly *UnwindAssembly_x86::CreateInstance(const ArchSpec &arch) {
1370   const llvm::Triple::ArchType cpu = arch.GetMachine();
1371   if (cpu == llvm::Triple::x86)
1372     return new UnwindAssembly_x86(arch, k_i386);
1373   else if (cpu == llvm::Triple::x86_64)
1374     return new UnwindAssembly_x86(arch, k_x86_64);
1375   return NULL;
1376 }
1377 
1378 //------------------------------------------------------------------
1379 // PluginInterface protocol in UnwindAssemblyParser_x86
1380 //------------------------------------------------------------------
1381 
1382 ConstString UnwindAssembly_x86::GetPluginName() {
1383   return GetPluginNameStatic();
1384 }
1385 
1386 uint32_t UnwindAssembly_x86::GetPluginVersion() { return 1; }
1387 
1388 void UnwindAssembly_x86::Initialize() {
1389   PluginManager::RegisterPlugin(GetPluginNameStatic(),
1390                                 GetPluginDescriptionStatic(), CreateInstance);
1391 }
1392 
1393 void UnwindAssembly_x86::Terminate() {
1394   PluginManager::UnregisterPlugin(CreateInstance);
1395 }
1396 
1397 lldb_private::ConstString UnwindAssembly_x86::GetPluginNameStatic() {
1398   static ConstString g_name("x86");
1399   return g_name;
1400 }
1401 
1402 const char *UnwindAssembly_x86::GetPluginDescriptionStatic() {
1403   return "i386 and x86_64 assembly language profiler plugin.";
1404 }
1405