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/Support/TargetSelect.h" 14 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/Error.h" 17 #include "lldb/Core/ArchSpec.h" 18 #include "lldb/Core/PluginManager.h" 19 #include "lldb/Symbol/UnwindPlan.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/Thread.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/UnwindAssembly.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 enum CPU { 31 k_i386, 32 k_x86_64 33 }; 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}, 75 {"ecx", k_machine_ecx, -1}, 76 {"edx", k_machine_edx, -1}, 77 {"ebx", k_machine_ebx, -1}, 78 {"esp", k_machine_esp, -1}, 79 {"ebp", k_machine_ebp, -1}, 80 {"esi", k_machine_esi, -1}, 81 {"edi", k_machine_edi, -1}, 82 {"eip", k_machine_eip, -1} 83 }; 84 85 const int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent); 86 87 static int i386_register_map_initialized = 0; 88 89 static struct regmap_ent x86_64_register_map[] = { 90 {"rax", k_machine_rax, -1}, 91 {"rcx", k_machine_rcx, -1}, 92 {"rdx", k_machine_rdx, -1}, 93 {"rbx", k_machine_rbx, -1}, 94 {"rsp", k_machine_rsp, -1}, 95 {"rbp", k_machine_rbp, -1}, 96 {"rsi", k_machine_rsi, -1}, 97 {"rdi", k_machine_rdi, -1}, 98 {"r8", k_machine_r8, -1}, 99 {"r9", k_machine_r9, -1}, 100 {"r10", k_machine_r10, -1}, 101 {"r11", k_machine_r11, -1}, 102 {"r12", k_machine_r12, -1}, 103 {"r13", k_machine_r13, -1}, 104 {"r14", k_machine_r14, -1}, 105 {"r15", k_machine_r15, -1}, 106 {"rip", k_machine_rip, -1} 107 }; 108 109 const int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent); 110 111 static int x86_64_register_map_initialized = 0; 112 113 //----------------------------------------------------------------------------------------------- 114 // AssemblyParse_x86 local-file class definition & implementation functions 115 //----------------------------------------------------------------------------------------------- 116 117 class AssemblyParse_x86 { 118 public: 119 120 AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func); 121 122 ~AssemblyParse_x86 (); 123 124 bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan); 125 126 bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan); 127 128 bool find_first_non_prologue_insn (Address &address); 129 130 private: 131 enum { kMaxInstructionByteSize = 32 }; 132 133 bool nonvolatile_reg_p (int machine_regno); 134 bool push_rbp_pattern_p (); 135 bool push_0_pattern_p (); 136 bool mov_rsp_rbp_pattern_p (); 137 bool sub_rsp_pattern_p (int& amount); 138 bool push_reg_p (int& regno); 139 bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset); 140 bool ret_pattern_p (); 141 uint32_t extract_4 (uint8_t *b); 142 bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno); 143 bool instruction_length (Address addr, int &length); 144 145 const ExecutionContext m_exe_ctx; 146 147 AddressRange m_func_bounds; 148 149 Address m_cur_insn; 150 uint8_t m_cur_insn_bytes[kMaxInstructionByteSize]; 151 152 int m_machine_ip_regnum; 153 int m_machine_sp_regnum; 154 int m_machine_fp_regnum; 155 156 int m_lldb_ip_regnum; 157 int m_lldb_sp_regnum; 158 int m_lldb_fp_regnum; 159 160 int m_wordsize; 161 int m_cpu; 162 ArchSpec m_arch; 163 ::LLVMDisasmContextRef m_disasm_context; 164 165 DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86); 166 }; 167 168 AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) : 169 m_exe_ctx (exe_ctx), 170 m_func_bounds(func), 171 m_cur_insn (), 172 m_machine_ip_regnum (LLDB_INVALID_REGNUM), 173 m_machine_sp_regnum (LLDB_INVALID_REGNUM), 174 m_machine_fp_regnum (LLDB_INVALID_REGNUM), 175 m_lldb_ip_regnum (LLDB_INVALID_REGNUM), 176 m_lldb_sp_regnum (LLDB_INVALID_REGNUM), 177 m_lldb_fp_regnum (LLDB_INVALID_REGNUM), 178 m_wordsize (-1), 179 m_cpu(cpu), 180 m_arch(arch) 181 { 182 int *initialized_flag = NULL; 183 if (cpu == k_i386) 184 { 185 m_machine_ip_regnum = k_machine_eip; 186 m_machine_sp_regnum = k_machine_esp; 187 m_machine_fp_regnum = k_machine_ebp; 188 m_wordsize = 4; 189 initialized_flag = &i386_register_map_initialized; 190 } 191 else 192 { 193 m_machine_ip_regnum = k_machine_rip; 194 m_machine_sp_regnum = k_machine_rsp; 195 m_machine_fp_regnum = k_machine_rbp; 196 m_wordsize = 8; 197 initialized_flag = &x86_64_register_map_initialized; 198 } 199 200 // we only look at prologue - it will be complete earlier than 512 bytes into func 201 if (m_func_bounds.GetByteSize() == 0) 202 m_func_bounds.SetByteSize(512); 203 204 Thread *thread = m_exe_ctx.GetThreadPtr(); 205 if (thread && *initialized_flag == 0) 206 { 207 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 208 if (reg_ctx) 209 { 210 struct regmap_ent *ent; 211 int count, i; 212 if (cpu == k_i386) 213 { 214 ent = i386_register_map; 215 count = size_of_i386_register_map; 216 } 217 else 218 { 219 ent = x86_64_register_map; 220 count = size_of_x86_64_register_map; 221 } 222 for (i = 0; i < count; i++, ent++) 223 { 224 const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name); 225 if (ri) 226 ent->lldb_regno = ri->kinds[eRegisterKindLLDB]; 227 } 228 *initialized_flag = 1; 229 } 230 } 231 232 // on initial construction we may not have a Thread so these have to remain 233 // uninitialized until we can get a RegisterContext to set up the register map table 234 if (*initialized_flag == 1) 235 { 236 uint32_t lldb_regno; 237 if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno)) 238 m_lldb_sp_regnum = lldb_regno; 239 if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno)) 240 m_lldb_fp_regnum = lldb_regno; 241 if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno)) 242 m_lldb_ip_regnum = lldb_regno; 243 } 244 245 m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(), 246 (void*)this, 247 /*TagType=*/1, 248 NULL, 249 NULL); 250 } 251 252 AssemblyParse_x86::~AssemblyParse_x86 () 253 { 254 ::LLVMDisasmDispose(m_disasm_context); 255 } 256 257 // This function expects an x86 native register number (i.e. the bits stripped out of the 258 // actual instruction), not an lldb register number. 259 260 bool 261 AssemblyParse_x86::nonvolatile_reg_p (int machine_regno) 262 { 263 if (m_cpu == k_i386) 264 { 265 switch (machine_regno) { 266 case k_machine_ebx: 267 case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention 268 case k_machine_esi: 269 case k_machine_edi: 270 case k_machine_esp: 271 return true; 272 default: 273 return false; 274 } 275 } 276 if (m_cpu == k_x86_64) 277 { 278 switch (machine_regno) { 279 case k_machine_rbx: 280 case k_machine_rsp: 281 case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention 282 case k_machine_r12: 283 case k_machine_r13: 284 case k_machine_r14: 285 case k_machine_r15: 286 return true; 287 default: 288 return false; 289 } 290 } 291 return false; 292 } 293 294 295 // Macro to detect if this is a REX mode prefix byte. 296 #define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48) 297 298 // The high bit which should be added to the source register number (the "R" bit) 299 #define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2) 300 301 // The high bit which should be added to the destination register number (the "B" bit) 302 #define REX_W_DSTREG(opcode) ((opcode) & 0x1) 303 304 // pushq %rbp [0x55] 305 bool AssemblyParse_x86::push_rbp_pattern_p () { 306 uint8_t *p = m_cur_insn_bytes; 307 if (*p == 0x55) 308 return true; 309 return false; 310 } 311 312 // pushq $0 ; the first instruction in start() [0x6a 0x00] 313 bool AssemblyParse_x86::push_0_pattern_p () 314 { 315 uint8_t *p = m_cur_insn_bytes; 316 if (*p == 0x6a && *(p + 1) == 0x0) 317 return true; 318 return false; 319 } 320 321 // movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5] 322 // movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5] 323 bool AssemblyParse_x86::mov_rsp_rbp_pattern_p () { 324 uint8_t *p = m_cur_insn_bytes; 325 if (m_wordsize == 8 && *p == 0x48) 326 p++; 327 if (*(p) == 0x8b && *(p + 1) == 0xec) 328 return true; 329 if (*(p) == 0x89 && *(p + 1) == 0xe5) 330 return true; 331 return false; 332 } 333 334 // subq $0x20, %rsp 335 bool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) { 336 uint8_t *p = m_cur_insn_bytes; 337 if (m_wordsize == 8 && *p == 0x48) 338 p++; 339 // 8-bit immediate operand 340 if (*p == 0x83 && *(p + 1) == 0xec) { 341 amount = (int8_t) *(p + 2); 342 return true; 343 } 344 // 32-bit immediate operand 345 if (*p == 0x81 && *(p + 1) == 0xec) { 346 amount = (int32_t) extract_4 (p + 2); 347 return true; 348 } 349 // Not handled: [0x83 0xc4] for imm8 with neg values 350 // [0x81 0xc4] for imm32 with neg values 351 return false; 352 } 353 354 // pushq %rbx 355 // pushl $ebx 356 bool AssemblyParse_x86::push_reg_p (int& regno) { 357 uint8_t *p = m_cur_insn_bytes; 358 int regno_prefix_bit = 0; 359 // If we have a rex prefix byte, check to see if a B bit is set 360 if (m_wordsize == 8 && *p == 0x41) { 361 regno_prefix_bit = 1 << 3; 362 p++; 363 } 364 if (*p >= 0x50 && *p <= 0x57) { 365 regno = (*p - 0x50) | regno_prefix_bit; 366 return true; 367 } 368 return false; 369 } 370 371 // Look for an instruction sequence storing a nonvolatile register 372 // on to the stack frame. 373 374 // movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0] 375 // movl %eax, -0xc(%ebp) [0x89 0x45 0xf4] 376 bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) { 377 uint8_t *p = m_cur_insn_bytes; 378 int src_reg_prefix_bit = 0; 379 int target_reg_prefix_bit = 0; 380 381 if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) { 382 src_reg_prefix_bit = REX_W_SRCREG (*p) << 3; 383 target_reg_prefix_bit = REX_W_DSTREG (*p) << 3; 384 if (target_reg_prefix_bit == 1) { 385 // rbp/ebp don't need a prefix bit - we know this isn't the 386 // reg we care about. 387 return false; 388 } 389 p++; 390 } 391 392 if (*p == 0x89) { 393 /* Mask off the 3-5 bits which indicate the destination register 394 if this is a ModR/M byte. */ 395 int opcode_destreg_masked_out = *(p + 1) & (~0x38); 396 397 /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101 398 and three bits between them, e.g. 01nnn101 399 We're looking for a destination of ebp-disp8 or ebp-disp32. */ 400 int immsize; 401 if (opcode_destreg_masked_out == 0x45) 402 immsize = 2; 403 else if (opcode_destreg_masked_out == 0x85) 404 immsize = 4; 405 else 406 return false; 407 408 int offset = 0; 409 if (immsize == 2) 410 offset = (int8_t) *(p + 2); 411 if (immsize == 4) 412 offset = (uint32_t) extract_4 (p + 2); 413 if (offset > 0) 414 return false; 415 416 regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit; 417 rbp_offset = offset > 0 ? offset : -offset; 418 return true; 419 } 420 return false; 421 } 422 423 // ret [0xc9] or [0xc2 imm8] or [0xca imm8] 424 bool 425 AssemblyParse_x86::ret_pattern_p () 426 { 427 uint8_t *p = m_cur_insn_bytes; 428 if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3) 429 return true; 430 return false; 431 } 432 433 uint32_t 434 AssemblyParse_x86::extract_4 (uint8_t *b) 435 { 436 uint32_t v = 0; 437 for (int i = 3; i >= 0; i--) 438 v = (v << 8) | b[i]; 439 return v; 440 } 441 442 bool 443 AssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno) 444 { 445 struct regmap_ent *ent; 446 int count, i; 447 if (m_cpu == k_i386) 448 { 449 ent = i386_register_map; 450 count = size_of_i386_register_map; 451 } 452 else 453 { 454 ent = x86_64_register_map; 455 count = size_of_x86_64_register_map; 456 } 457 for (i = 0; i < count; i++, ent++) 458 { 459 if (ent->machine_regno == machine_regno) 460 if (ent->lldb_regno != -1) 461 { 462 lldb_regno = ent->lldb_regno; 463 return true; 464 } 465 } 466 return false; 467 } 468 469 bool 470 AssemblyParse_x86::instruction_length (Address addr, int &length) 471 { 472 const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize(); 473 llvm::SmallVector <uint8_t, 32> opcode_data; 474 opcode_data.resize (max_op_byte_size); 475 476 if (!addr.IsValid()) 477 return false; 478 479 const bool prefer_file_cache = true; 480 Error error; 481 Target *target = m_exe_ctx.GetTargetPtr(); 482 if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(), max_op_byte_size, error) == -1) 483 { 484 return false; 485 } 486 487 char out_string[512]; 488 const addr_t pc = addr.GetFileAddress(); 489 const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context, 490 opcode_data.data(), 491 max_op_byte_size, 492 pc, // PC value 493 out_string, 494 sizeof(out_string)); 495 496 length = inst_size; 497 return true; 498 } 499 500 501 bool 502 AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) 503 { 504 UnwindPlan::RowSP row(new UnwindPlan::Row); 505 int non_prologue_insn_count = 0; 506 m_cur_insn = m_func_bounds.GetBaseAddress (); 507 int current_func_text_offset = 0; 508 int current_sp_bytes_offset_from_cfa = 0; 509 UnwindPlan::Row::RegisterLocation initial_regloc; 510 Error error; 511 512 if (!m_cur_insn.IsValid()) 513 { 514 return false; 515 } 516 517 unwind_plan.SetPlanValidAddressRange (m_func_bounds); 518 unwind_plan.SetRegisterKind (eRegisterKindLLDB); 519 520 // At the start of the function, find the CFA by adding wordsize to the SP register 521 row->SetOffset (current_func_text_offset); 522 row->SetCFARegister (m_lldb_sp_regnum); 523 row->SetCFAOffset (m_wordsize); 524 525 // caller's stack pointer value before the call insn is the CFA address 526 initial_regloc.SetIsCFAPlusOffset (0); 527 row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc); 528 529 // saved instruction pointer can be found at CFA - wordsize. 530 current_sp_bytes_offset_from_cfa = m_wordsize; 531 initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 532 row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc); 533 534 unwind_plan.AppendRow (row); 535 536 // Allocate a new Row, populate it with the existing Row contents. 537 UnwindPlan::Row *newrow = new UnwindPlan::Row; 538 *newrow = *row.get(); 539 row.reset(newrow); 540 541 const bool prefer_file_cache = true; 542 543 Target *target = m_exe_ctx.GetTargetPtr(); 544 while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10) 545 { 546 int stack_offset, insn_len; 547 int machine_regno; // register numbers masked directly out of instructions 548 uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB numbering scheme 549 550 if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize) 551 { 552 // An unrecognized/junk instruction 553 break; 554 } 555 if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 556 { 557 // Error reading the instruction out of the file, stop scanning 558 break; 559 } 560 561 if (push_rbp_pattern_p ()) 562 { 563 row->SetOffset (current_func_text_offset + insn_len); 564 current_sp_bytes_offset_from_cfa += m_wordsize; 565 row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 566 UnwindPlan::Row::RegisterLocation regloc; 567 regloc.SetAtCFAPlusOffset (-row->GetCFAOffset()); 568 row->SetRegisterInfo (m_lldb_fp_regnum, regloc); 569 unwind_plan.AppendRow (row); 570 // Allocate a new Row, populate it with the existing Row contents. 571 newrow = new UnwindPlan::Row; 572 *newrow = *row.get(); 573 row.reset(newrow); 574 goto loopnext; 575 } 576 577 if (mov_rsp_rbp_pattern_p ()) 578 { 579 row->SetOffset (current_func_text_offset + insn_len); 580 row->SetCFARegister (m_lldb_fp_regnum); 581 unwind_plan.AppendRow (row); 582 // Allocate a new Row, populate it with the existing Row contents. 583 newrow = new UnwindPlan::Row; 584 *newrow = *row.get(); 585 row.reset(newrow); 586 goto loopnext; 587 } 588 589 // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the 590 // saved pc value of 0 on the stack. In this case we want to pretend we didn't see a stack movement at all -- 591 // normally the saved pc value is already on the stack by the time the function starts executing. 592 if (push_0_pattern_p ()) 593 { 594 goto loopnext; 595 } 596 597 if (push_reg_p (machine_regno)) 598 { 599 current_sp_bytes_offset_from_cfa += m_wordsize; 600 if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 601 { 602 row->SetOffset (current_func_text_offset + insn_len); 603 if (row->GetCFARegister() == m_lldb_sp_regnum) 604 { 605 row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 606 } 607 UnwindPlan::Row::RegisterLocation regloc; 608 regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 609 row->SetRegisterInfo (lldb_regno, regloc); 610 unwind_plan.AppendRow (row); 611 // Allocate a new Row, populate it with the existing Row contents. 612 newrow = new UnwindPlan::Row; 613 *newrow = *row.get(); 614 row.reset(newrow); 615 } 616 goto loopnext; 617 } 618 619 if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno)) 620 { 621 if (machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 622 { 623 row->SetOffset (current_func_text_offset + insn_len); 624 UnwindPlan::Row::RegisterLocation regloc; 625 regloc.SetAtCFAPlusOffset (-row->GetCFAOffset()); 626 row->SetRegisterInfo (lldb_regno, regloc); 627 unwind_plan.AppendRow (row); 628 // Allocate a new Row, populate it with the existing Row contents. 629 newrow = new UnwindPlan::Row; 630 *newrow = *row.get(); 631 row.reset(newrow); 632 goto loopnext; 633 } 634 } 635 636 if (sub_rsp_pattern_p (stack_offset)) 637 { 638 current_sp_bytes_offset_from_cfa += stack_offset; 639 if (row->GetCFARegister() == m_lldb_sp_regnum) 640 { 641 row->SetOffset (current_func_text_offset + insn_len); 642 row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 643 unwind_plan.AppendRow (row); 644 // Allocate a new Row, populate it with the existing Row contents. 645 newrow = new UnwindPlan::Row; 646 *newrow = *row.get(); 647 row.reset(newrow); 648 } 649 goto loopnext; 650 } 651 652 if (ret_pattern_p ()) 653 { 654 // we know where the end of the function is; set the limit on the PlanValidAddressRange 655 // in case our initial "high pc" value was overly large 656 // int original_size = m_func_bounds.GetByteSize(); 657 // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1; 658 // m_func_bounds.SetByteSize (calculated_size); 659 // unwind_plan.SetPlanValidAddressRange (m_func_bounds); 660 break; 661 } 662 663 // FIXME recognize the i386 picbase setup instruction sequence, 664 // 0x1f16: call 0x1f1b ; main + 11 at /private/tmp/a.c:3 665 // 0x1f1b: popl %eax 666 // and record the temporary stack movements if the CFA is not expressed in terms of ebp. 667 668 non_prologue_insn_count++; 669 loopnext: 670 m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 671 current_func_text_offset += insn_len; 672 } 673 674 // Now look at the byte at the end of the AddressRange for a limited attempt at describing the 675 // epilogue. We're looking for the sequence 676 677 // [ 0x5d ] mov %rbp, %rsp 678 // [ 0xc3 ] ret 679 // [ 0xe8 xx xx xx xx ] call __stack_chk_fail (this is sometimes the final insn in the function) 680 681 // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the 682 // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry. 683 684 uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS; 685 Address end_of_fun(m_func_bounds.GetBaseAddress()); 686 end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize()); 687 688 if (m_func_bounds.GetByteSize() > 7) 689 { 690 uint8_t bytebuf[7]; 691 Address last_seven_bytes(end_of_fun); 692 last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7); 693 if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1) 694 { 695 if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3) // mov, ret 696 { 697 ret_insn_offset = m_func_bounds.GetByteSize() - 1; 698 } 699 else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call 700 { 701 ret_insn_offset = m_func_bounds.GetByteSize() - 6; 702 } 703 } 704 } else if (m_func_bounds.GetByteSize() > 2) 705 { 706 uint8_t bytebuf[2]; 707 Address last_two_bytes(end_of_fun); 708 last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2); 709 if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1) 710 { 711 if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret 712 { 713 ret_insn_offset = m_func_bounds.GetByteSize() - 1; 714 } 715 } 716 } 717 718 if (ret_insn_offset != LLDB_INVALID_ADDRESS) 719 { 720 // Create a fresh, empty Row and RegisterLocation - don't mention any other registers 721 UnwindPlan::RowSP epi_row(new UnwindPlan::Row); 722 UnwindPlan::Row::RegisterLocation epi_regloc; 723 724 // When the ret instruction is about to be executed, here's our state 725 epi_row->SetOffset (ret_insn_offset); 726 epi_row->SetCFARegister (m_lldb_sp_regnum); 727 epi_row->SetCFAOffset (m_wordsize); 728 729 // caller's stack pointer value before the call insn is the CFA address 730 epi_regloc.SetIsCFAPlusOffset (0); 731 epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc); 732 733 // saved instruction pointer can be found at CFA - wordsize 734 epi_regloc.SetAtCFAPlusOffset (-m_wordsize); 735 epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc); 736 737 unwind_plan.AppendRow (epi_row); 738 } 739 740 unwind_plan.SetSourceName ("assembly insn profiling"); 741 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 742 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 743 744 return true; 745 } 746 747 /* The "fast unwind plan" is valid for functions that follow the usual convention of 748 using the frame pointer register (ebp, rbp), i.e. the function prologue looks like 749 push %rbp [0x55] 750 mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386) 751 */ 752 753 bool 754 AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan) 755 { 756 UnwindPlan::RowSP row(new UnwindPlan::Row); 757 UnwindPlan::Row::RegisterLocation pc_reginfo; 758 UnwindPlan::Row::RegisterLocation sp_reginfo; 759 UnwindPlan::Row::RegisterLocation fp_reginfo; 760 unwind_plan.SetRegisterKind (eRegisterKindLLDB); 761 762 if (!func.GetBaseAddress().IsValid()) 763 return false; 764 765 Target *target = m_exe_ctx.GetTargetPtr(); 766 767 uint8_t bytebuf[4]; 768 Error error; 769 const bool prefer_file_cache = true; 770 if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1) 771 return false; 772 773 uint8_t i386_prologue[] = {0x55, 0x89, 0xe5}; 774 uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5}; 775 int prologue_size; 776 777 if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0) 778 { 779 prologue_size = sizeof (i386_prologue); 780 } 781 else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0) 782 { 783 prologue_size = sizeof (x86_64_prologue); 784 } 785 else 786 { 787 return false; 788 } 789 790 pc_reginfo.SetAtCFAPlusOffset (-m_wordsize); 791 row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo); 792 793 sp_reginfo.SetIsCFAPlusOffset (0); 794 row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo); 795 796 // Zero instructions into the function 797 row->SetCFARegister (m_lldb_sp_regnum); 798 row->SetCFAOffset (m_wordsize); 799 row->SetOffset (0); 800 unwind_plan.AppendRow (row); 801 UnwindPlan::Row *newrow = new UnwindPlan::Row; 802 *newrow = *row.get(); 803 row.reset(newrow); 804 805 // push %rbp has executed - stack moved, rbp now saved 806 row->SetCFAOffset (2 * m_wordsize); 807 fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize); 808 row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo); 809 row->SetOffset (1); 810 unwind_plan.AppendRow (row); 811 812 newrow = new UnwindPlan::Row; 813 *newrow = *row.get(); 814 row.reset(newrow); 815 816 // mov %rsp, %rbp has executed 817 row->SetCFARegister (m_lldb_fp_regnum); 818 row->SetCFAOffset (2 * m_wordsize); 819 row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch 820 unwind_plan.AppendRow (row); 821 822 newrow = new UnwindPlan::Row; 823 *newrow = *row.get(); 824 row.reset(newrow); 825 826 unwind_plan.SetPlanValidAddressRange (func); 827 unwind_plan.SetSourceName ("fast unwind assembly profiling"); 828 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 829 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 830 return true; 831 } 832 833 bool 834 AssemblyParse_x86::find_first_non_prologue_insn (Address &address) 835 { 836 m_cur_insn = m_func_bounds.GetBaseAddress (); 837 if (!m_cur_insn.IsValid()) 838 { 839 return false; 840 } 841 842 const bool prefer_file_cache = true; 843 Target *target = m_exe_ctx.GetTargetPtr(); 844 while (m_func_bounds.ContainsFileAddress (m_cur_insn)) 845 { 846 Error error; 847 int insn_len, offset, regno; 848 if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0) 849 { 850 // An error parsing the instruction, i.e. probably data/garbage - stop scanning 851 break; 852 } 853 if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 854 { 855 // Error reading the instruction out of the file, stop scanning 856 break; 857 } 858 859 if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset) 860 || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)) 861 { 862 m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 863 continue; 864 } 865 866 // Unknown non-prologue instruction - stop scanning 867 break; 868 } 869 870 address = m_cur_insn; 871 return true; 872 } 873 874 875 876 877 878 879 //----------------------------------------------------------------------------------------------- 880 // UnwindAssemblyParser_x86 method definitions 881 //----------------------------------------------------------------------------------------------- 882 883 UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) : 884 lldb_private::UnwindAssembly(arch), 885 m_cpu(cpu), 886 m_arch(arch) 887 { 888 } 889 890 891 UnwindAssembly_x86::~UnwindAssembly_x86 () 892 { 893 } 894 895 bool 896 UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) 897 { 898 ExecutionContext exe_ctx (thread.shared_from_this()); 899 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 900 return asm_parse.get_non_call_site_unwind_plan (unwind_plan); 901 } 902 903 bool 904 UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) 905 { 906 ExecutionContext exe_ctx (thread.shared_from_this()); 907 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 908 return asm_parse.get_fast_unwind_plan (func, unwind_plan); 909 } 910 911 bool 912 UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn) 913 { 914 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 915 return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn); 916 } 917 918 UnwindAssembly * 919 UnwindAssembly_x86::CreateInstance (const ArchSpec &arch) 920 { 921 const llvm::Triple::ArchType cpu = arch.GetMachine (); 922 if (cpu == llvm::Triple::x86) 923 return new UnwindAssembly_x86 (arch, k_i386); 924 else if (cpu == llvm::Triple::x86_64) 925 return new UnwindAssembly_x86 (arch, k_x86_64); 926 return NULL; 927 } 928 929 930 //------------------------------------------------------------------ 931 // PluginInterface protocol in UnwindAssemblyParser_x86 932 //------------------------------------------------------------------ 933 934 ConstString 935 UnwindAssembly_x86::GetPluginName() 936 { 937 return GetPluginNameStatic(); 938 } 939 940 941 uint32_t 942 UnwindAssembly_x86::GetPluginVersion() 943 { 944 return 1; 945 } 946 947 void 948 UnwindAssembly_x86::Initialize() 949 { 950 PluginManager::RegisterPlugin (GetPluginNameStatic(), 951 GetPluginDescriptionStatic(), 952 CreateInstance); 953 } 954 955 void 956 UnwindAssembly_x86::Terminate() 957 { 958 PluginManager::UnregisterPlugin (CreateInstance); 959 } 960 961 962 lldb_private::ConstString 963 UnwindAssembly_x86::GetPluginNameStatic() 964 { 965 static ConstString g_name("x86"); 966 return g_name; 967 } 968 969 const char * 970 UnwindAssembly_x86::GetPluginDescriptionStatic() 971 { 972 return "i386 and x86_64 assembly language profiler plugin."; 973 } 974