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