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