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