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