19a1941b32dbd6de385a26fec7cac238a8fb9af25Greg Clayton//===-- UnwindAssembly-x86.cpp ----------------------------------*- C++ -*-===// 23a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 33a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The LLVM Compiler Infrastructure 43a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 53a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This file is distributed under the University of Illinois Open Source 63a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// License. See LICENSE.TXT for details. 73a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 83a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//===----------------------------------------------------------------------===// 93a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 109a1941b32dbd6de385a26fec7cac238a8fb9af25Greg Clayton#include "UnwindAssembly-x86.h" 113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 12dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda#include "llvm-c/Disassembler.h" 13c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen#include "llvm/Support/TargetSelect.h" 1497eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton 153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Address.h" 163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Error.h" 173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/ArchSpec.h" 183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/PluginManager.h" 1997eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "lldb/Symbol/UnwindPlan.h" 203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/ExecutionContext.h" 213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Process.h" 223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/RegisterContext.h" 233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Thread.h" 243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Target.h" 258badcb2503ed2e2884a48f66099c1d48494817f4Greg Clayton#include "lldb/Target/UnwindAssembly.h" 263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb; 283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb_private; 293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum CPU { 313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_i386, 323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_x86_64 333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum i386_register_numbers { 363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_eax = 0, 373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ecx = 1, 383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_edx = 2, 393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ebx = 3, 403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_esp = 4, 413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ebp = 5, 423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_esi = 6, 433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_edi = 7, 443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_eip = 8 453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum x86_64_register_numbers { 483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rax = 0, 493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rcx = 1, 503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rdx = 2, 513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rbx = 3, 523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rsp = 4, 533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rbp = 5, 543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rsi = 6, 553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rdi = 7, 563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r8 = 8, 573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r9 = 9, 583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r10 = 10, 593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r11 = 11, 603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r12 = 12, 613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r13 = 13, 623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r14 = 14, 633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r15 = 15, 643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rip = 16 653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastruct regmap_ent { 683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda const char *name; 693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int machine_regno; 703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int lldb_regno; 713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent i386_register_map[] = { 743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"eax", k_machine_eax, -1}, 753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ecx", k_machine_ecx, -1}, 763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"edx", k_machine_edx, -1}, 773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ebx", k_machine_ebx, -1}, 783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"esp", k_machine_esp, -1}, 793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ebp", k_machine_ebp, -1}, 803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"esi", k_machine_esi, -1}, 813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"edi", k_machine_edi, -1}, 823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"eip", k_machine_eip, -1} 833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent); 863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int i386_register_map_initialized = 0; 883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent x86_64_register_map[] = { 903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rax", k_machine_rax, -1}, 913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rcx", k_machine_rcx, -1}, 923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rdx", k_machine_rdx, -1}, 933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rbx", k_machine_rbx, -1}, 943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rsp", k_machine_rsp, -1}, 953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rbp", k_machine_rbp, -1}, 963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rsi", k_machine_rsi, -1}, 973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rdi", k_machine_rdi, -1}, 983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r8", k_machine_r8, -1}, 993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r9", k_machine_r9, -1}, 1003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r10", k_machine_r10, -1}, 1013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r11", k_machine_r11, -1}, 1023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r12", k_machine_r12, -1}, 1033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r13", k_machine_r13, -1}, 1043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r14", k_machine_r14, -1}, 1053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r15", k_machine_r15, -1}, 1063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rip", k_machine_rip, -1} 1073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 1083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent); 1103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int x86_64_register_map_initialized = 0; 1123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 1143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// AssemblyParse_x86 local-file class definition & implementation functions 1153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 1163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaclass AssemblyParse_x86 { 1183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendapublic: 1193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 120dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func); 121dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda 122dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda ~AssemblyParse_x86 (); 1233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan); 1253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1268280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan); 1273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool find_first_non_prologue_insn (Address &address); 1293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaprivate: 1313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda enum { kMaxInstructionByteSize = 32 }; 1323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool nonvolatile_reg_p (int machine_regno); 1343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_rbp_pattern_p (); 1353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_0_pattern_p (); 1363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool mov_rsp_rbp_pattern_p (); 1373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool sub_rsp_pattern_p (int& amount); 1383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_reg_p (int& regno); 1393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset); 1403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool ret_pattern_p (); 1413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t extract_4 (uint8_t *b); 1423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno); 1433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool instruction_length (Address addr, int &length); 1443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 145f4124deeb9532044a38c0774ced872f2709347daGreg Clayton const ExecutionContext m_exe_ctx; 1463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AddressRange m_func_bounds; 1483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Address m_cur_insn; 1503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t m_cur_insn_bytes[kMaxInstructionByteSize]; 1513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_ip_regnum; 1533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_sp_regnum; 1543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_fp_regnum; 1553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_ip_regnum; 1573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_sp_regnum; 1583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_fp_regnum; 1593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_wordsize; 1613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_cpu; 162dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda ArchSpec m_arch; 163dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda ::LLVMDisasmContextRef m_disasm_context; 164a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda 165a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86); 1663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 1673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 168dac50c2cc644f4114ea809103d6efb1e440b5063Jason MolendaAssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) : 169f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_exe_ctx (exe_ctx), 170f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_func_bounds(func), 171f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_cur_insn (), 172f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_machine_ip_regnum (LLDB_INVALID_REGNUM), 173f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_machine_sp_regnum (LLDB_INVALID_REGNUM), 174f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_machine_fp_regnum (LLDB_INVALID_REGNUM), 175f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_lldb_ip_regnum (LLDB_INVALID_REGNUM), 176f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_lldb_sp_regnum (LLDB_INVALID_REGNUM), 177f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_lldb_fp_regnum (LLDB_INVALID_REGNUM), 178f4124deeb9532044a38c0774ced872f2709347daGreg Clayton m_wordsize (-1), 179dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda m_cpu(cpu), 180e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda m_arch(arch) 1818280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda{ 1823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int *initialized_flag = NULL; 1833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (cpu == k_i386) 1843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 1853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_ip_regnum = k_machine_eip; 1863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_sp_regnum = k_machine_esp; 1873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_fp_regnum = k_machine_ebp; 1883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_wordsize = 4; 1893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda initialized_flag = &i386_register_map_initialized; 1903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 1913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 1923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 1933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_ip_regnum = k_machine_rip; 1943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_sp_regnum = k_machine_rsp; 1953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_fp_regnum = k_machine_rbp; 1963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_wordsize = 8; 1973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda initialized_flag = &x86_64_register_map_initialized; 1983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 1993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // we only look at prologue - it will be complete earlier than 512 bytes into func 2013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_func_bounds.GetByteSize() == 0) 2023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_func_bounds.SetByteSize(512); 2033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 204f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Thread *thread = m_exe_ctx.GetThreadPtr(); 205f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (thread && *initialized_flag == 0) 2063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 207f4124deeb9532044a38c0774ced872f2709347daGreg Clayton RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 20808d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton if (reg_ctx) 2093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct regmap_ent *ent; 2113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int count, i; 2123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (cpu == k_i386) 2133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = i386_register_map; 2153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_i386_register_map; 2163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 2183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = x86_64_register_map; 2203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_x86_64_register_map; 2213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (i = 0; i < count; i++, ent++) 2233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 22408d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name); 2253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ri) 2263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent->lldb_regno = ri->kinds[eRegisterKindLLDB]; 2273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda *initialized_flag = 1; 2293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // on initial construction we may not have a Thread so these have to remain 2333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // uninitialized until we can get a RegisterContext to set up the register map table 2343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*initialized_flag == 1) 2353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t lldb_regno; 2373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno)) 2383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_sp_regnum = lldb_regno; 2393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno)) 2403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_fp_regnum = lldb_regno; 2413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno)) 2423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_ip_regnum = lldb_regno; 2433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 244dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda 245dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(), 246dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda (void*)this, 247dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda /*TagType=*/1, 248dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda NULL, 249dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda NULL); 2503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 252dac50c2cc644f4114ea809103d6efb1e440b5063Jason MolendaAssemblyParse_x86::~AssemblyParse_x86 () 253dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda{ 254dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda ::LLVMDisasmDispose(m_disasm_context); 255dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda} 2563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This function expects an x86 native register number (i.e. the bits stripped out of the 2583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// actual instruction), not an lldb register number. 2593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 2613a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::nonvolatile_reg_p (int machine_regno) 2623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 2633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_i386) 2643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda switch (machine_regno) { 2663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_ebx: 2673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention 2683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_esi: 2693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_edi: 2703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_esp: 2713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda default: 2733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_x86_64) 2773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda switch (machine_regno) { 2793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rbx: 2803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rsp: 2813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention 2823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r12: 2833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r13: 2843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r14: 2853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r15: 2863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda default: 2883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Macro to detect if this is a REX mode prefix byte. 2963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48) 2973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the source register number (the "R" bit) 2993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2) 3003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the destination register number (the "B" bit) 3023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_DSTREG(opcode) ((opcode) & 0x1) 3033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbp [0x55] 3053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_rbp_pattern_p () { 3063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x55) 3083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq $0 ; the first instruction in start() [0x6a 0x00] 3133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_0_pattern_p () 3143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 3153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x6a && *(p + 1) == 0x0) 3173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5] 3223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5] 3233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_rsp_rbp_pattern_p () { 3243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x48) 3263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*(p) == 0x8b && *(p + 1) == 0xec) 3283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*(p) == 0x89 && *(p + 1) == 0xe5) 3303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// subq $0x20, %rsp 3353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) { 3363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x48) 3383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 8-bit immediate operand 3403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x83 && *(p + 1) == 0xec) { 3413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda amount = (int8_t) *(p + 2); 3423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 32-bit immediate operand 3453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x81 && *(p + 1) == 0xec) { 3463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda amount = (int32_t) extract_4 (p + 2); 3473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Not handled: [0x83 0xc4] for imm8 with neg values 3503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // [0x81 0xc4] for imm32 with neg values 3513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbx 3553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushl $ebx 3563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_reg_p (int& regno) { 3573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int regno_prefix_bit = 0; 3593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // If we have a rex prefix byte, check to see if a B bit is set 3603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x41) { 3613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno_prefix_bit = 1 << 3; 3623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p >= 0x50 && *p <= 0x57) { 3653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno = (*p - 0x50) | regno_prefix_bit; 3663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Look for an instruction sequence storing a nonvolatile register 3723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// on to the stack frame. 3733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0] 3753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4] 3763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) { 3773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int src_reg_prefix_bit = 0; 3793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int target_reg_prefix_bit = 0; 3803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) { 3823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda src_reg_prefix_bit = REX_W_SRCREG (*p) << 3; 3833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda target_reg_prefix_bit = REX_W_DSTREG (*p) << 3; 3843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (target_reg_prefix_bit == 1) { 3853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // rbp/ebp don't need a prefix bit - we know this isn't the 3863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // reg we care about. 3873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x89) { 3933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda /* Mask off the 3-5 bits which indicate the destination register 3943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if this is a ModR/M byte. */ 3953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int opcode_destreg_masked_out = *(p + 1) & (~0x38); 3963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101 3983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda and three bits between them, e.g. 01nnn101 3993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda We're looking for a destination of ebp-disp8 or ebp-disp32. */ 4003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int immsize; 4013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (opcode_destreg_masked_out == 0x45) 4023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda immsize = 2; 4033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else if (opcode_destreg_masked_out == 0x85) 4043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda immsize = 4; 4053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 4063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int offset = 0; 4093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (immsize == 2) 4103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda offset = (int8_t) *(p + 2); 4113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (immsize == 4) 4123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda offset = (uint32_t) extract_4 (p + 2); 4133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (offset > 0) 4143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit; 4173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda rbp_offset = offset > 0 ? offset : -offset; 4183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// ret [0xc9] or [0xc2 imm8] or [0xca imm8] 4243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4253a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::ret_pattern_p () 4263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 4283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3) 4293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t 4343a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::extract_4 (uint8_t *b) 4353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t v = 0; 4373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (int i = 3; i >= 0; i--) 4383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda v = (v << 8) | b[i]; 4393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return v; 4403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4433a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno) 4443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct regmap_ent *ent; 4463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int count, i; 4473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_i386) 4483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = i386_register_map; 4503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_i386_register_map; 4513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 4533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = x86_64_register_map; 4553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_x86_64_register_map; 4563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (i = 0; i < count; i++, ent++) 4583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ent->machine_regno == machine_regno) 4603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ent->lldb_regno != -1) 4613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda lldb_regno = ent->lldb_regno; 4633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4703a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::instruction_length (Address addr, int &length) 4713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 472dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize(); 473e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda llvm::SmallVector <uint8_t, 32> opcode_data; 474e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda opcode_data.resize (max_op_byte_size); 475800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 476800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!addr.IsValid()) 477800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 478800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 479dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda const bool prefer_file_cache = true; 480dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda Error error; 481dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda Target *target = m_exe_ctx.GetTargetPtr(); 482e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(), max_op_byte_size, error) == -1) 4833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4848280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 4853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 486dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda 487dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda char out_string[512]; 488dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda const addr_t pc = addr.GetFileAddress(); 489dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context, 490e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda opcode_data.data(), 491dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda max_op_byte_size, 492dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda pc, // PC value 493dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda out_string, 494dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda sizeof(out_string)); 495dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda 496dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda length = inst_size; 4973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 5023a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) 5033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 50468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::RowSP row(new UnwindPlan::Row); 5053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int non_prologue_insn_count = 0; 506800d11d87769e1a7083f7a5545613625396deb3eJason Molenda m_cur_insn = m_func_bounds.GetBaseAddress (); 5073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int current_func_text_offset = 0; 5083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int current_sp_bytes_offset_from_cfa = 0; 509a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda UnwindPlan::Row::RegisterLocation initial_regloc; 51019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda Error error; 5113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 512800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!m_cur_insn.IsValid()) 513800d11d87769e1a7083f7a5545613625396deb3eJason Molenda { 514800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 515800d11d87769e1a7083f7a5545613625396deb3eJason Molenda } 516800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 5173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.SetPlanValidAddressRange (m_func_bounds); 5183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.SetRegisterKind (eRegisterKindLLDB); 5193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // At the start of the function, find the CFA by adding wordsize to the SP register 52168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset); 52268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFARegister (m_lldb_sp_regnum); 52368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (m_wordsize); 5243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // caller's stack pointer value before the call insn is the CFA address 526a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda initial_regloc.SetIsCFAPlusOffset (0); 52768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc); 5283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // saved instruction pointer can be found at CFA - wordsize. 5303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa = m_wordsize; 531a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 53268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc); 5333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 53568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda 53668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 53768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::Row *newrow = new UnwindPlan::Row; 53868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 53968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 54068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda 54126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 5423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 543f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Target *target = m_exe_ctx.GetTargetPtr(); 5443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10) 5453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int stack_offset, insn_len; 5473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int machine_regno; // register numbers masked directly out of instructions 5483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB numbering scheme 5493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize) 5513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // An unrecognized/junk instruction 5533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 5543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 555f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 5563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Error reading the instruction out of the file, stop scanning 5583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 5593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 5603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_rbp_pattern_p ()) 5623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 56368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset + insn_len); 5643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += m_wordsize; 56568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 5663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 56768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda regloc.SetAtCFAPlusOffset (-row->GetCFAOffset()); 56868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_fp_regnum, regloc); 5693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 57068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 57168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 57268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 57368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 5743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 5753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 576a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda 577a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda if (mov_rsp_rbp_pattern_p ()) 578a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda { 57968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset + insn_len); 58068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFARegister (m_lldb_fp_regnum); 581a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda unwind_plan.AppendRow (row); 58268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 58368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 58468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 58568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 586a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda goto loopnext; 587a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda } 588a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda 5898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the 5908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // saved pc value of 0 on the stack. In this case we want to pretend we didn't see a stack movement at all -- 5918280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // normally the saved pc value is already on the stack by the time the function starts executing. 5923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_0_pattern_p ()) 5933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 5953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 5963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_reg_p (machine_regno)) 5983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += m_wordsize; 6003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 6013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 60268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset + insn_len); 60368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda if (row->GetCFARegister() == m_lldb_sp_regnum) 6043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 60568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 6063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 6083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 60968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (lldb_regno, regloc); 6103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 61168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 61268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 61368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 61468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 6153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno)) 6203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 6223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 62368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset + insn_len); 6243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 62568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda regloc.SetAtCFAPlusOffset (-row->GetCFAOffset()); 62668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (lldb_regno, regloc); 6273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 62868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 62968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 63068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 63168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 6323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (sub_rsp_pattern_p (stack_offset)) 6373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += stack_offset; 63968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda if (row->GetCFARegister() == m_lldb_sp_regnum) 6403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 64168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (current_func_text_offset + insn_len); 64268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (current_sp_bytes_offset_from_cfa); 6433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 64468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda // Allocate a new Row, populate it with the existing Row contents. 64568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 64668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 64768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 6483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ret_pattern_p ()) 6533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // we know where the end of the function is; set the limit on the PlanValidAddressRange 6553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // in case our initial "high pc" value was overly large 6563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // int original_size = m_func_bounds.GetByteSize(); 6573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1; 6583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // m_func_bounds.SetByteSize (calculated_size); 6593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // unwind_plan.SetPlanValidAddressRange (m_func_bounds); 6603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 6613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // FIXME recognize the i386 picbase setup instruction sequence, 6643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 0x1f16: call 0x1f1b ; main + 11 at /private/tmp/a.c:3 6653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 0x1f1b: popl %eax 6663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // and record the temporary stack movements if the CFA is not expressed in terms of ebp. 6673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda non_prologue_insn_count++; 6693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaloopnext: 6703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 6713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_func_text_offset += insn_len; 6723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 67419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // Now look at the byte at the end of the AddressRange for a limited attempt at describing the 675528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // epilogue. We're looking for the sequence 67619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 677528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // [ 0x5d ] mov %rbp, %rsp 678528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // [ 0xc3 ] ret 679528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // [ 0xe8 xx xx xx xx ] call __stack_chk_fail (this is sometimes the final insn in the function) 680528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 681528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the 682528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry. 683528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 684528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS; 685528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda Address end_of_fun(m_func_bounds.GetBaseAddress()); 686528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize()); 687528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 688528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (m_func_bounds.GetByteSize() > 7) 68919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 690528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda uint8_t bytebuf[7]; 691528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda Address last_seven_bytes(end_of_fun); 692528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7); 693528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1) 69419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 695528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3) // mov, ret 69619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 697528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda ret_insn_offset = m_func_bounds.GetByteSize() - 1; 698528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda } 699528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call 700528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda { 701528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda ret_insn_offset = m_func_bounds.GetByteSize() - 6; 70219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 70319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 704528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda } else if (m_func_bounds.GetByteSize() > 2) 705528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda { 706528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda uint8_t bytebuf[2]; 707528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda Address last_two_bytes(end_of_fun); 708528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2); 709528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1) 710528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda { 711528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret 712528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda { 713528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda ret_insn_offset = m_func_bounds.GetByteSize() - 1; 714528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda } 715528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda } 716528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda } 717528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 718528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda if (ret_insn_offset != LLDB_INVALID_ADDRESS) 719528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda { 720528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // Create a fresh, empty Row and RegisterLocation - don't mention any other registers 72168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::RowSP epi_row(new UnwindPlan::Row); 722528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda UnwindPlan::Row::RegisterLocation epi_regloc; 723528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 724528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // When the ret instruction is about to be executed, here's our state 72568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda epi_row->SetOffset (ret_insn_offset); 72668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda epi_row->SetCFARegister (m_lldb_sp_regnum); 72768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda epi_row->SetCFAOffset (m_wordsize); 728528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 729528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // caller's stack pointer value before the call insn is the CFA address 730528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda epi_regloc.SetIsCFAPlusOffset (0); 73168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc); 732528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 733528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda // saved instruction pointer can be found at CFA - wordsize 734528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda epi_regloc.SetAtCFAPlusOffset (-m_wordsize); 73568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc); 736528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda 737528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda unwind_plan.AppendRow (epi_row); 73819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 73919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 7408280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetSourceName ("assembly insn profiling"); 74137816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 74237816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 7438280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 7453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 7463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 7478280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda/* The "fast unwind plan" is valid for functions that follow the usual convention of 7488280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda using the frame pointer register (ebp, rbp), i.e. the function prologue looks like 7498280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda push %rbp [0x55] 7508280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386) 7518280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda*/ 7528280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 7548280cbe80c79bc206335831dd732e0f9fb69c519Jason MolendaAssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan) 7553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 75668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::RowSP row(new UnwindPlan::Row); 7578280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation pc_reginfo; 7588280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation sp_reginfo; 7598280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation fp_reginfo; 7608280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetRegisterKind (eRegisterKindLLDB); 7618280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7628280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda if (!func.GetBaseAddress().IsValid()) 7638280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7648280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 765f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Target *target = m_exe_ctx.GetTargetPtr(); 766f4124deeb9532044a38c0774ced872f2709347daGreg Clayton 7678280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t bytebuf[4]; 7688280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda Error error; 76926100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 770f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1) 7718280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7728280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7738280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t i386_prologue[] = {0x55, 0x89, 0xe5}; 7748280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5}; 7758280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda int prologue_size; 7768280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7778280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0) 7788280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7798280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda prologue_size = sizeof (i386_prologue); 7808280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7818280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0) 7828280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7838280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda prologue_size = sizeof (x86_64_prologue); 7848280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7858280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda else 7868280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7878280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7888280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda pc_reginfo.SetAtCFAPlusOffset (-m_wordsize); 79168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo); 7928280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7938280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda sp_reginfo.SetIsCFAPlusOffset (0); 79468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo); 7958280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7968280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // Zero instructions into the function 79768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFARegister (m_lldb_sp_regnum); 79868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (m_wordsize); 79968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (0); 8008280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 80168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda UnwindPlan::Row *newrow = new UnwindPlan::Row; 80268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 80368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 8048280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 8058280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // push %rbp has executed - stack moved, rbp now saved 80668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (2 * m_wordsize); 8078280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize); 80868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo); 80968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (1); 8108280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 8118280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 81268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 81368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 81468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 81568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda 8168280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // mov %rsp, %rbp has executed 81768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFARegister (m_lldb_fp_regnum); 81868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetCFAOffset (2 * m_wordsize); 81968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch 8208280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 8218280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 82268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda newrow = new UnwindPlan::Row; 82368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda *newrow = *row.get(); 82468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda row.reset(newrow); 82568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda 8268280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetPlanValidAddressRange (func); 82737816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda unwind_plan.SetSourceName ("fast unwind assembly profiling"); 82837816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 82937816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 8308280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return true; 8313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 8343a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::find_first_non_prologue_insn (Address &address) 8353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn = m_func_bounds.GetBaseAddress (); 837800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!m_cur_insn.IsValid()) 838800d11d87769e1a7083f7a5545613625396deb3eJason Molenda { 839800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 840800d11d87769e1a7083f7a5545613625396deb3eJason Molenda } 841800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 84226100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 843f4124deeb9532044a38c0774ced872f2709347daGreg Clayton Target *target = m_exe_ctx.GetTargetPtr(); 8443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda while (m_func_bounds.ContainsFileAddress (m_cur_insn)) 8453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 8463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Error error; 8473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int insn_len, offset, regno; 8483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0) 8493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 8503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // An error parsing the instruction, i.e. probably data/garbage - stop scanning 8513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 8523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 853f4124deeb9532044a38c0774ced872f2709347daGreg Clayton if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 8543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 8553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Error reading the instruction out of the file, stop scanning 8563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 8573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 8583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset) 8603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)) 8613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 8623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 8633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda continue; 8643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 8653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Unknown non-prologue instruction - stop scanning 8673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 8683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 8693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda address = m_cur_insn; 8713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 8723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 8803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// UnwindAssemblyParser_x86 method definitions 8813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 8823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 883888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) : 884888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton lldb_private::UnwindAssembly(arch), 885dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda m_cpu(cpu), 886dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda m_arch(arch) 887888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{ 888888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton} 889888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 890888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 891888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::~UnwindAssembly_x86 () 892888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{ 893888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton} 894888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton 8953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 896f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) 8973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 898f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ExecutionContext exe_ctx (thread.shared_from_this()); 899dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 9003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return asm_parse.get_non_call_site_unwind_plan (unwind_plan); 9013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 904f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) 9053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 906f4124deeb9532044a38c0774ced872f2709347daGreg Clayton ExecutionContext exe_ctx (thread.shared_from_this()); 907dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 9088280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return asm_parse.get_fast_unwind_plan (func, unwind_plan); 9093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 912f4124deeb9532044a38c0774ced872f2709347daGreg ClaytonUnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn) 9133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 914dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); 9153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn); 9163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9188badcb2503ed2e2884a48f66099c1d48494817f4Greg ClaytonUnwindAssembly * 919f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::CreateInstance (const ArchSpec &arch) 9203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 921940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton const llvm::Triple::ArchType cpu = arch.GetMachine (); 922940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton if (cpu == llvm::Triple::x86) 923888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return new UnwindAssembly_x86 (arch, k_i386); 924940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton else if (cpu == llvm::Triple::x86_64) 925888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton return new UnwindAssembly_x86 (arch, k_x86_64); 926940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton return NULL; 9273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------ 9313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// PluginInterface protocol in UnwindAssemblyParser_x86 9323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------ 9333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9340e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString 935f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginName() 9363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9370e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton return GetPluginNameStatic(); 9383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t 942f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginVersion() 9433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return 1; 9453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid 948f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Initialize() 9493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda PluginManager::RegisterPlugin (GetPluginNameStatic(), 9513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda GetPluginDescriptionStatic(), 9523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda CreateInstance); 9533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid 956f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Terminate() 9573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda PluginManager::UnregisterPlugin (CreateInstance); 9593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9620e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString 963f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginNameStatic() 9643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9650e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton static ConstString g_name("x86"); 9660e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton return g_name; 9673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 9683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 9693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char * 970f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginDescriptionStatic() 9713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return "i386 and x86_64 assembly language profiler plugin."; 9733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 974