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