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