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