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