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