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 27using namespace lldb; 28using namespace lldb_private; 29 30enum CPU { 31 k_i386, 32 k_x86_64 33}; 34 35enum 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 47enum 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 67struct regmap_ent { 68 const char *name; 69 int machine_regno; 70 int lldb_regno; 71}; 72 73static 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 85const int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent); 86 87static int i386_register_map_initialized = 0; 88 89static 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 109const int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent); 110 111static int x86_64_register_map_initialized = 0; 112 113//----------------------------------------------------------------------------------------------- 114// AssemblyParse_x86 local-file class definition & implementation functions 115//----------------------------------------------------------------------------------------------- 116 117class AssemblyParse_x86 { 118public: 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 130private: 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 168AssemblyParse_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 252AssemblyParse_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 260bool 261AssemblyParse_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] 305bool 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] 313bool 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] 323bool 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 335bool 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 356bool 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] 376bool 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] 424bool 425AssemblyParse_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 433uint32_t 434AssemblyParse_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 442bool 443AssemblyParse_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 469bool 470AssemblyParse_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 501bool 502AssemblyParse_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 bool need_to_push_row = false; 601 // the PUSH instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer, 602 // we need to add a new row of instructions. 603 if (row->GetCFARegister() == m_lldb_sp_regnum) 604 { 605 need_to_push_row = true; 606 row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 607 } 608 // record where non-volatile (callee-saved, spilled) registers are saved on the stack 609 if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 610 { 611 need_to_push_row = true; 612 UnwindPlan::Row::RegisterLocation regloc; 613 regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 614 row->SetRegisterInfo (lldb_regno, regloc); 615 } 616 if (need_to_push_row) 617 { 618 row->SetOffset (current_func_text_offset + insn_len); 619 unwind_plan.AppendRow (row); 620 // Allocate a new Row, populate it with the existing Row contents. 621 newrow = new UnwindPlan::Row; 622 *newrow = *row.get(); 623 row.reset(newrow); 624 } 625 goto loopnext; 626 } 627 628 if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno)) 629 { 630 if (machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 631 { 632 row->SetOffset (current_func_text_offset + insn_len); 633 UnwindPlan::Row::RegisterLocation regloc; 634 regloc.SetAtCFAPlusOffset (-row->GetCFAOffset()); 635 row->SetRegisterInfo (lldb_regno, regloc); 636 unwind_plan.AppendRow (row); 637 // Allocate a new Row, populate it with the existing Row contents. 638 newrow = new UnwindPlan::Row; 639 *newrow = *row.get(); 640 row.reset(newrow); 641 goto loopnext; 642 } 643 } 644 645 if (sub_rsp_pattern_p (stack_offset)) 646 { 647 current_sp_bytes_offset_from_cfa += stack_offset; 648 if (row->GetCFARegister() == m_lldb_sp_regnum) 649 { 650 row->SetOffset (current_func_text_offset + insn_len); 651 row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 652 unwind_plan.AppendRow (row); 653 // Allocate a new Row, populate it with the existing Row contents. 654 newrow = new UnwindPlan::Row; 655 *newrow = *row.get(); 656 row.reset(newrow); 657 } 658 goto loopnext; 659 } 660 661 if (ret_pattern_p ()) 662 { 663 // we know where the end of the function is; set the limit on the PlanValidAddressRange 664 // in case our initial "high pc" value was overly large 665 // int original_size = m_func_bounds.GetByteSize(); 666 // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1; 667 // m_func_bounds.SetByteSize (calculated_size); 668 // unwind_plan.SetPlanValidAddressRange (m_func_bounds); 669 break; 670 } 671 672 // FIXME recognize the i386 picbase setup instruction sequence, 673 // 0x1f16: call 0x1f1b ; main + 11 at /private/tmp/a.c:3 674 // 0x1f1b: popl %eax 675 // and record the temporary stack movements if the CFA is not expressed in terms of ebp. 676 677 non_prologue_insn_count++; 678loopnext: 679 m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 680 current_func_text_offset += insn_len; 681 } 682 683 // Now look at the byte at the end of the AddressRange for a limited attempt at describing the 684 // epilogue. We're looking for the sequence 685 686 // [ 0x5d ] mov %rbp, %rsp 687 // [ 0xc3 ] ret 688 // [ 0xe8 xx xx xx xx ] call __stack_chk_fail (this is sometimes the final insn in the function) 689 690 // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the 691 // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry. 692 693 uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS; 694 Address end_of_fun(m_func_bounds.GetBaseAddress()); 695 end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize()); 696 697 if (m_func_bounds.GetByteSize() > 7) 698 { 699 uint8_t bytebuf[7]; 700 Address last_seven_bytes(end_of_fun); 701 last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7); 702 if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1) 703 { 704 if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3) // mov, ret 705 { 706 ret_insn_offset = m_func_bounds.GetByteSize() - 1; 707 } 708 else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call 709 { 710 ret_insn_offset = m_func_bounds.GetByteSize() - 6; 711 } 712 } 713 } else if (m_func_bounds.GetByteSize() > 2) 714 { 715 uint8_t bytebuf[2]; 716 Address last_two_bytes(end_of_fun); 717 last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2); 718 if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1) 719 { 720 if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret 721 { 722 ret_insn_offset = m_func_bounds.GetByteSize() - 1; 723 } 724 } 725 } 726 727 if (ret_insn_offset != LLDB_INVALID_ADDRESS) 728 { 729 // Create a fresh, empty Row and RegisterLocation - don't mention any other registers 730 UnwindPlan::RowSP epi_row(new UnwindPlan::Row); 731 UnwindPlan::Row::RegisterLocation epi_regloc; 732 733 // When the ret instruction is about to be executed, here's our state 734 epi_row->SetOffset (ret_insn_offset); 735 epi_row->SetCFARegister (m_lldb_sp_regnum); 736 epi_row->SetCFAOffset (m_wordsize); 737 738 // caller's stack pointer value before the call insn is the CFA address 739 epi_regloc.SetIsCFAPlusOffset (0); 740 epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc); 741 742 // saved instruction pointer can be found at CFA - wordsize 743 epi_regloc.SetAtCFAPlusOffset (-m_wordsize); 744 epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc); 745 746 unwind_plan.AppendRow (epi_row); 747 } 748 749 unwind_plan.SetSourceName ("assembly insn profiling"); 750 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 751 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 752 753 return true; 754} 755 756/* The "fast unwind plan" is valid for functions that follow the usual convention of 757 using the frame pointer register (ebp, rbp), i.e. the function prologue looks like 758 push %rbp [0x55] 759 mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386) 760*/ 761 762bool 763AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan) 764{ 765 UnwindPlan::RowSP row(new UnwindPlan::Row); 766 UnwindPlan::Row::RegisterLocation pc_reginfo; 767 UnwindPlan::Row::RegisterLocation sp_reginfo; 768 UnwindPlan::Row::RegisterLocation fp_reginfo; 769 unwind_plan.SetRegisterKind (eRegisterKindLLDB); 770 771 if (!func.GetBaseAddress().IsValid()) 772 return false; 773 774 Target *target = m_exe_ctx.GetTargetPtr(); 775 776 uint8_t bytebuf[4]; 777 Error error; 778 const bool prefer_file_cache = true; 779 if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1) 780 return false; 781 782 uint8_t i386_prologue[] = {0x55, 0x89, 0xe5}; 783 uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5}; 784 int prologue_size; 785 786 if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0) 787 { 788 prologue_size = sizeof (i386_prologue); 789 } 790 else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0) 791 { 792 prologue_size = sizeof (x86_64_prologue); 793 } 794 else 795 { 796 return false; 797 } 798 799 pc_reginfo.SetAtCFAPlusOffset (-m_wordsize); 800 row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo); 801 802 sp_reginfo.SetIsCFAPlusOffset (0); 803 row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo); 804 805 // Zero instructions into the function 806 row->SetCFARegister (m_lldb_sp_regnum); 807 row->SetCFAOffset (m_wordsize); 808 row->SetOffset (0); 809 unwind_plan.AppendRow (row); 810 UnwindPlan::Row *newrow = new UnwindPlan::Row; 811 *newrow = *row.get(); 812 row.reset(newrow); 813 814 // push %rbp has executed - stack moved, rbp now saved 815 row->SetCFAOffset (2 * m_wordsize); 816 fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize); 817 row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo); 818 row->SetOffset (1); 819 unwind_plan.AppendRow (row); 820 821 newrow = new UnwindPlan::Row; 822 *newrow = *row.get(); 823 row.reset(newrow); 824 825 // mov %rsp, %rbp has executed 826 row->SetCFARegister (m_lldb_fp_regnum); 827 row->SetCFAOffset (2 * m_wordsize); 828 row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch 829 unwind_plan.AppendRow (row); 830 831 newrow = new UnwindPlan::Row; 832 *newrow = *row.get(); 833 row.reset(newrow); 834 835 unwind_plan.SetPlanValidAddressRange (func); 836 unwind_plan.SetSourceName ("fast unwind assembly profiling"); 837 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 838 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 839 return true; 840} 841 842bool 843AssemblyParse_x86::find_first_non_prologue_insn (Address &address) 844{ 845 m_cur_insn = m_func_bounds.GetBaseAddress (); 846 if (!m_cur_insn.IsValid()) 847 { 848 return false; 849 } 850 851 const bool prefer_file_cache = true; 852 Target *target = m_exe_ctx.GetTargetPtr(); 853 while (m_func_bounds.ContainsFileAddress (m_cur_insn)) 854 { 855 Error error; 856 int insn_len, offset, regno; 857 if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0) 858 { 859 // An error parsing the instruction, i.e. probably data/garbage - stop scanning 860 break; 861 } 862 if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 863 { 864 // Error reading the instruction out of the file, stop scanning 865 break; 866 } 867 868 if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset) 869 || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)) 870 { 871 m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 872 continue; 873 } 874 875 // Unknown non-prologue instruction - stop scanning 876 break; 877 } 878 879 address = m_cur_insn; 880 return true; 881} 882 883 884 885 886 887 888//----------------------------------------------------------------------------------------------- 889// UnwindAssemblyParser_x86 method definitions 890//----------------------------------------------------------------------------------------------- 891 892UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) : 893 lldb_private::UnwindAssembly(arch), 894 m_cpu(cpu), 895 m_arch(arch) 896{ 897} 898 899 900UnwindAssembly_x86::~UnwindAssembly_x86 () 901{ 902} 903 904bool 905UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) 906{ 907 ExecutionContext exe_ctx (thread.shared_from_this()); 908 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 909 return asm_parse.get_non_call_site_unwind_plan (unwind_plan); 910} 911 912bool 913UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) 914{ 915 ExecutionContext exe_ctx (thread.shared_from_this()); 916 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 917 return asm_parse.get_fast_unwind_plan (func, unwind_plan); 918} 919 920bool 921UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn) 922{ 923 AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 924 return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn); 925} 926 927UnwindAssembly * 928UnwindAssembly_x86::CreateInstance (const ArchSpec &arch) 929{ 930 const llvm::Triple::ArchType cpu = arch.GetMachine (); 931 if (cpu == llvm::Triple::x86) 932 return new UnwindAssembly_x86 (arch, k_i386); 933 else if (cpu == llvm::Triple::x86_64) 934 return new UnwindAssembly_x86 (arch, k_x86_64); 935 return NULL; 936} 937 938 939//------------------------------------------------------------------ 940// PluginInterface protocol in UnwindAssemblyParser_x86 941//------------------------------------------------------------------ 942 943ConstString 944UnwindAssembly_x86::GetPluginName() 945{ 946 return GetPluginNameStatic(); 947} 948 949 950uint32_t 951UnwindAssembly_x86::GetPluginVersion() 952{ 953 return 1; 954} 955 956void 957UnwindAssembly_x86::Initialize() 958{ 959 PluginManager::RegisterPlugin (GetPluginNameStatic(), 960 GetPluginDescriptionStatic(), 961 CreateInstance); 962} 963 964void 965UnwindAssembly_x86::Terminate() 966{ 967 PluginManager::UnregisterPlugin (CreateInstance); 968} 969 970 971lldb_private::ConstString 972UnwindAssembly_x86::GetPluginNameStatic() 973{ 974 static ConstString g_name("x86"); 975 return g_name; 976} 977 978const char * 979UnwindAssembly_x86::GetPluginDescriptionStatic() 980{ 981 return "i386 and x86_64 assembly language profiler plugin."; 982} 983