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