UnwindAssembly-x86.cpp revision f6e287a873007543f3b419a71546ab8f007be90b
1f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton//===-- UnwindAssemblyx86.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 10f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton#include "UnwindAssemblyx86.h" 113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1297eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "llvm-c/EnhancedDisassembly.h" 1397eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton 143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Address.h" 153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Error.h" 163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/ArchSpec.h" 173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/PluginManager.h" 1897eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "lldb/Symbol/UnwindPlan.h" 193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/ExecutionContext.h" 203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Process.h" 213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/RegisterContext.h" 223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Thread.h" 233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Target.h" 2497eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "lldb/Target/UnwindAssemblyProfiler.h" 253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb; 273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb_private; 283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum CPU { 303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_i386, 313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_x86_64 323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum i386_register_numbers { 353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_eax = 0, 363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ecx = 1, 373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_edx = 2, 383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ebx = 3, 393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_esp = 4, 403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_ebp = 5, 413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_esi = 6, 423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_edi = 7, 433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_eip = 8 443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum x86_64_register_numbers { 473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rax = 0, 483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rcx = 1, 493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rdx = 2, 503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rbx = 3, 513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rsp = 4, 523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rbp = 5, 533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rsi = 6, 543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rdi = 7, 553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r8 = 8, 563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r9 = 9, 573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r10 = 10, 583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r11 = 11, 593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r12 = 12, 603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r13 = 13, 613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r14 = 14, 623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_r15 = 15, 633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda k_machine_rip = 16 643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastruct regmap_ent { 673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda const char *name; 683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int machine_regno; 693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int lldb_regno; 703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent i386_register_map[] = { 733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"eax", k_machine_eax, -1}, 743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ecx", k_machine_ecx, -1}, 753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"edx", k_machine_edx, -1}, 763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ebx", k_machine_ebx, -1}, 773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"esp", k_machine_esp, -1}, 783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"ebp", k_machine_ebp, -1}, 793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"esi", k_machine_esi, -1}, 803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"edi", k_machine_edi, -1}, 813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"eip", k_machine_eip, -1} 823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent); 853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int i386_register_map_initialized = 0; 873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent x86_64_register_map[] = { 893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rax", k_machine_rax, -1}, 903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rcx", k_machine_rcx, -1}, 913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rdx", k_machine_rdx, -1}, 923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rbx", k_machine_rbx, -1}, 933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rsp", k_machine_rsp, -1}, 943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rbp", k_machine_rbp, -1}, 953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rsi", k_machine_rsi, -1}, 963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rdi", k_machine_rdi, -1}, 973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r8", k_machine_r8, -1}, 983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r9", k_machine_r9, -1}, 993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r10", k_machine_r10, -1}, 1003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r11", k_machine_r11, -1}, 1013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r12", k_machine_r12, -1}, 1023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r13", k_machine_r13, -1}, 1033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r14", k_machine_r14, -1}, 1043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"r15", k_machine_r15, -1}, 1053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda {"rip", k_machine_rip, -1} 1063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 1073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent); 1093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int x86_64_register_map_initialized = 0; 1113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 1133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// AssemblyParse_x86 local-file class definition & implementation functions 1143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 1153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaclass AssemblyParse_x86 { 1173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendapublic: 1183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AssemblyParse_x86 (Target &target, Thread *thread, int cpu, AddressRange func); 1203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan); 1223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1238280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan); 1243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool find_first_non_prologue_insn (Address &address); 1263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaprivate: 1283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda enum { kMaxInstructionByteSize = 32 }; 1293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool nonvolatile_reg_p (int machine_regno); 1313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_rbp_pattern_p (); 1323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_0_pattern_p (); 1333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool mov_rsp_rbp_pattern_p (); 1343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool sub_rsp_pattern_p (int& amount); 1353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool push_reg_p (int& regno); 1363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset); 1373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool ret_pattern_p (); 1383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t extract_4 (uint8_t *b); 1393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno); 1403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda bool instruction_length (Address addr, int &length); 1413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Target &m_target; 1433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Thread* m_thread; 1443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AddressRange m_func_bounds; 1463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Address m_cur_insn; 1483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t m_cur_insn_bytes[kMaxInstructionByteSize]; 1493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_ip_regnum; 1513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_sp_regnum; 1523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_machine_fp_regnum; 1533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_ip_regnum; 1553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_sp_regnum; 1563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_lldb_fp_regnum; 1573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_wordsize; 1593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int m_cpu; 160a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda 161a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86); 1623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 1633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1643a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::AssemblyParse_x86 (Target& target, Thread* thread, int cpu, AddressRange func) : 165dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_target (target), m_thread (thread), m_func_bounds(func), m_cur_insn (), 166a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda m_machine_ip_regnum (-1), m_machine_sp_regnum (-1), m_machine_fp_regnum (-1), 167a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda m_lldb_ip_regnum (-1), m_lldb_sp_regnum (-1), m_lldb_fp_regnum (-1), 168dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_wordsize (-1), m_cpu(cpu) 1698280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda{ 1703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int *initialized_flag = NULL; 1713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_ip_regnum = m_lldb_sp_regnum = m_lldb_fp_regnum = -1; 1723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (cpu == k_i386) 1733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 1743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_ip_regnum = k_machine_eip; 1753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_sp_regnum = k_machine_esp; 1763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_fp_regnum = k_machine_ebp; 1773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_wordsize = 4; 1783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda initialized_flag = &i386_register_map_initialized; 1793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 1803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 1813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 1823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_ip_regnum = k_machine_rip; 1833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_sp_regnum = k_machine_rsp; 1843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_machine_fp_regnum = k_machine_rbp; 1853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_wordsize = 8; 1863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda initialized_flag = &x86_64_register_map_initialized; 1873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 1883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // we only look at prologue - it will be complete earlier than 512 bytes into func 1903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_func_bounds.GetByteSize() == 0) 1913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_func_bounds.SetByteSize(512); 1923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_thread && *initialized_flag == 0) 1943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 19508d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton RegisterContext *reg_ctx = m_thread->GetRegisterContext().get(); 19608d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton if (reg_ctx) 1973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 1983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct regmap_ent *ent; 1993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int count, i; 2003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (cpu == k_i386) 2013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = i386_register_map; 2033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_i386_register_map; 2043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 2063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = x86_64_register_map; 2083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_x86_64_register_map; 2093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (i = 0; i < count; i++, ent++) 2113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 21208d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name); 2133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ri) 2143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent->lldb_regno = ri->kinds[eRegisterKindLLDB]; 2153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda *initialized_flag = 1; 2173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // on initial construction we may not have a Thread so these have to remain 2213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // uninitialized until we can get a RegisterContext to set up the register map table 2223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*initialized_flag == 1) 2233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t lldb_regno; 2253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno)) 2263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_sp_regnum = lldb_regno; 2273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno)) 2283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_fp_regnum = lldb_regno; 2293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno)) 2303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_lldb_ip_regnum = lldb_regno; 2313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This function expects an x86 native register number (i.e. the bits stripped out of the 2363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// actual instruction), not an lldb register number. 2373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 2393a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::nonvolatile_reg_p (int machine_regno) 2403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 2413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_i386) 2423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda switch (machine_regno) { 2443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_ebx: 2453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_ebp: // not actually a nonvolatile but often treated as such by convention 2463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_esi: 2473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_edi: 2483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_esp: 2493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda default: 2513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_x86_64) 2553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 2563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda switch (machine_regno) { 2573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rbx: 2583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rsp: 2593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_rbp: // not actually a nonvolatile but often treated as such by convention 2603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r12: 2613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r13: 2623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r14: 2633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda case k_machine_r15: 2643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda default: 2663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 2693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Macro to detect if this is a REX mode prefix byte. 2743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48) 2753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the source register number (the "R" bit) 2773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2) 2783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the destination register number (the "B" bit) 2803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_DSTREG(opcode) ((opcode) & 0x1) 2813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbp [0x55] 2833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_rbp_pattern_p () { 2843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 2853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x55) 2863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq $0 ; the first instruction in start() [0x6a 0x00] 2913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_0_pattern_p () 2923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 2933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 2943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x6a && *(p + 1) == 0x0) 2953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 2963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 2973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 2983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 2993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5] 3003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5] 3013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_rsp_rbp_pattern_p () { 3023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x48) 3043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*(p) == 0x8b && *(p + 1) == 0xec) 3063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*(p) == 0x89 && *(p + 1) == 0xe5) 3083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// subq $0x20, %rsp 3133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) { 3143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x48) 3163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 8-bit immediate operand 3183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x83 && *(p + 1) == 0xec) { 3193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda amount = (int8_t) *(p + 2); 3203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 32-bit immediate operand 3233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x81 && *(p + 1) == 0xec) { 3243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda amount = (int32_t) extract_4 (p + 2); 3253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Not handled: [0x83 0xc4] for imm8 with neg values 3283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // [0x81 0xc4] for imm32 with neg values 3293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbx 3333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushl $ebx 3343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_reg_p (int& regno) { 3353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int regno_prefix_bit = 0; 3373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // If we have a rex prefix byte, check to see if a B bit is set 3383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && *p == 0x41) { 3393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno_prefix_bit = 1 << 3; 3403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p >= 0x50 && *p <= 0x57) { 3433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno = (*p - 0x50) | regno_prefix_bit; 3443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 3483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Look for an instruction sequence storing a nonvolatile register 3503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// on to the stack frame. 3513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0] 3533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %eax, -0xc(%ebp) [0x89 0x45 0xf4] 3543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) { 3553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 3563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int src_reg_prefix_bit = 0; 3573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int target_reg_prefix_bit = 0; 3583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) { 3603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda src_reg_prefix_bit = REX_W_SRCREG (*p) << 3; 3613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda target_reg_prefix_bit = REX_W_DSTREG (*p) << 3; 3623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (target_reg_prefix_bit == 1) { 3633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // rbp/ebp don't need a prefix bit - we know this isn't the 3643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // reg we care about. 3653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda p++; 3683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0x89) { 3713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda /* Mask off the 3-5 bits which indicate the destination register 3723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if this is a ModR/M byte. */ 3733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int opcode_destreg_masked_out = *(p + 1) & (~0x38); 3743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101 3763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda and three bits between them, e.g. 01nnn101 3773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda We're looking for a destination of ebp-disp8 or ebp-disp32. */ 3783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int immsize; 3793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (opcode_destreg_masked_out == 0x45) 3803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda immsize = 2; 3813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else if (opcode_destreg_masked_out == 0x85) 3823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda immsize = 4; 3833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 3843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int offset = 0; 3873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (immsize == 2) 3883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda offset = (int8_t) *(p + 2); 3893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (immsize == 4) 3903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda offset = (uint32_t) extract_4 (p + 2); 3913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (offset > 0) 3923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 3943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit; 3953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda rbp_offset = offset > 0 ? offset : -offset; 3963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 3973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 3983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 3993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// ret [0xc9] or [0xc2 imm8] or [0xca imm8] 4023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4033a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::ret_pattern_p () 4043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t *p = m_cur_insn_bytes; 4063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3) 4073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t 4123a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::extract_4 (uint8_t *b) 4133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t v = 0; 4153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (int i = 3; i >= 0; i--) 4163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda v = (v << 8) | b[i]; 4173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return v; 4183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4213a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno) 4223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct regmap_ent *ent; 4243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int count, i; 4253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_i386) 4263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = i386_register_map; 4283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_i386_register_map; 4293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 4313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ent = x86_64_register_map; 4333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda count = size_of_x86_64_register_map; 4343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda for (i = 0; i < count; i++, ent++) 4363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ent->machine_regno == machine_regno) 4383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ent->lldb_regno != -1) 4393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda lldb_regno = ent->lldb_regno; 4413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 4423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return false; 4453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastruct edis_byte_read_token 4483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Address *address; 4503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Target *target; 4513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}; 4523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int 4553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaread_byte_for_edis (uint8_t *buf, uint64_t offset_address, void *arg) 4563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (arg == 0) 4583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return -1; 4593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct edis_byte_read_token *tok = (edis_byte_read_token *) arg; 4603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Address *base_address = tok->address; 4613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Target *target = tok->target; 4623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Address read_addr = *base_address; 4643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda read_addr.SetOffset (offset_address); 4653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint8_t onebyte_buf[1]; 4673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Error error; 46826100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 46926100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton if (target->ReadMemory (read_addr, prefer_file_cache, onebyte_buf, 1, error) != -1) 4703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda *buf = onebyte_buf[0]; 4723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return 0; 4733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return -1; 4753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 4763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 4793a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::instruction_length (Address addr, int &length) 4803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 4813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda const char *triple; 482800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 483800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!addr.IsValid()) 484800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 485800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 4863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // FIXME should probably pass down the ArchSpec and work from that to make a portable triple 4873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_cpu == k_i386) 488a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda triple = "i386-unknown-unknown"; 4893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda else 490a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda triple = "x86_64-unknown-unknown"; 4913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 4923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda EDDisassemblerRef disasm; 4933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda EDInstRef cur_insn; 4943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 495a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda if (EDGetDisassembler (&disasm, triple, kEDAssemblySyntaxX86ATT) != 0) 4963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 4978280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 4983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 4993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint64_t addr_offset = addr.GetOffset(); 5013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda struct edis_byte_read_token arg; 5023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda arg.address = &addr; 5033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda arg.target = &m_target; 5043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr_offset, &arg) != 1) 5053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5068280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 5073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 5083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda length = EDInstByteSize (cur_insn); 5093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda EDReleaseInst (cur_insn); 5103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 5113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 5123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 5153a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) 5163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 5173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row row; 5183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int non_prologue_insn_count = 0; 519800d11d87769e1a7083f7a5545613625396deb3eJason Molenda m_cur_insn = m_func_bounds.GetBaseAddress (); 5203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int current_func_text_offset = 0; 5213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int current_sp_bytes_offset_from_cfa = 0; 522a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda UnwindPlan::Row::RegisterLocation initial_regloc; 52319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda Error error; 5243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 525800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!m_cur_insn.IsValid()) 526800d11d87769e1a7083f7a5545613625396deb3eJason Molenda { 527800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 528800d11d87769e1a7083f7a5545613625396deb3eJason Molenda } 529800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 5303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.SetPlanValidAddressRange (m_func_bounds); 5313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.SetRegisterKind (eRegisterKindLLDB); 5323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // At the start of the function, find the CFA by adding wordsize to the SP register 5343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetOffset (current_func_text_offset); 5353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetCFARegister (m_lldb_sp_regnum); 5363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetCFAOffset (m_wordsize); 5373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // caller's stack pointer value before the call insn is the CFA address 539a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda initial_regloc.SetIsCFAPlusOffset (0); 540a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda row.SetRegisterInfo (m_lldb_sp_regnum, initial_regloc); 5413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // saved instruction pointer can be found at CFA - wordsize. 5433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa = m_wordsize; 544a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 545a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda row.SetRegisterInfo (m_lldb_ip_regnum, initial_regloc); 5463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 54826100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 5493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10) 5513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int stack_offset, insn_len; 5533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int machine_regno; // register numbers masked directly out of instructions 5543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda uint32_t lldb_regno; // register numbers in lldb's eRegisterKindLLDB numbering scheme 5553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize) 5573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // An unrecognized/junk instruction 5593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 5603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 56126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 5623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Error reading the instruction out of the file, stop scanning 5643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 5653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 5663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_rbp_pattern_p ()) 5683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetOffset (current_func_text_offset + insn_len); 5703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += m_wordsize; 5713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetCFAOffset (current_sp_bytes_offset_from_cfa); 5723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 5733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regloc.SetAtCFAPlusOffset (-row.GetCFAOffset()); 5743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetRegisterInfo (m_lldb_fp_regnum, regloc); 5753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 5763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 5773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 578a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda 579a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda if (mov_rsp_rbp_pattern_p ()) 580a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda { 581a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda row.SetOffset (current_func_text_offset + insn_len); 582a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda row.SetCFARegister (m_lldb_fp_regnum); 583a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda unwind_plan.AppendRow (row); 584a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda goto loopnext; 585a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda } 586a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda 5878280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the 5888280cbe80c79bc206335831dd732e0f9fb69c519Jason 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 -- 5898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // normally the saved pc value is already on the stack by the time the function starts executing. 5903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_0_pattern_p ()) 5913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 5933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 5943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 5953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_reg_p (machine_regno)) 5963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 5973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += m_wordsize; 5983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 5993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetOffset (current_func_text_offset + insn_len); 6013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (row.GetCFARegister() == m_lldb_sp_regnum) 6023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetCFAOffset (current_sp_bytes_offset_from_cfa); 6043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 6063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa); 6073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetRegisterInfo (lldb_regno, regloc); 6083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 6093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno)) 6143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (machine_regno_to_lldb_regno (machine_regno, lldb_regno)) 6163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetOffset (current_func_text_offset + insn_len); 6183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda UnwindPlan::Row::RegisterLocation regloc; 6193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda regloc.SetAtCFAPlusOffset (-row.GetCFAOffset()); 6203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetRegisterInfo (lldb_regno, regloc); 6213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 6223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (sub_rsp_pattern_p (stack_offset)) 6273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_sp_bytes_offset_from_cfa += stack_offset; 6293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (row.GetCFARegister() == m_lldb_sp_regnum) 6303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetOffset (current_func_text_offset + insn_len); 6323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda row.SetCFAOffset (current_sp_bytes_offset_from_cfa); 6333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda unwind_plan.AppendRow (row); 6343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda goto loopnext; 6363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (ret_pattern_p ()) 6393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 6403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // we know where the end of the function is; set the limit on the PlanValidAddressRange 6413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // in case our initial "high pc" value was overly large 6423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // int original_size = m_func_bounds.GetByteSize(); 6433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1; 6443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // m_func_bounds.SetByteSize (calculated_size); 6453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // unwind_plan.SetPlanValidAddressRange (m_func_bounds); 6463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 6473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // FIXME recognize the i386 picbase setup instruction sequence, 6503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 0x1f16: call 0x1f1b ; main + 11 at /private/tmp/a.c:3 6513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // 0x1f1b: popl %eax 6523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // and record the temporary stack movements if the CFA is not expressed in terms of ebp. 6533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 6543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda non_prologue_insn_count++; 6553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaloopnext: 6563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 6573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda current_func_text_offset += insn_len; 6583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 6593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 66019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // Now look at the byte at the end of the AddressRange for a limited attempt at describing the 66119e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // epilogue. If this function is built -fomit-frame-pointer (so the CFA is defined in terms of the 66219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // stack pointer) we'd need to profile every instruction which causes rsp to change to backtrace 66319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // all the time. But assuming the CFA is in terms of rbp most of the time, this one additional Row 66419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // will be sufficient. 66519e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 66619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda if (m_func_bounds.GetByteSize() > 2) 66719e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 66819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda Address last_insn (m_func_bounds.GetBaseAddress()); 66919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda last_insn.SetOffset (last_insn.GetOffset() + m_func_bounds.GetByteSize() - 1); 67019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda uint8_t bytebuf[1]; 67126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton if (m_target.ReadMemory (last_insn, prefer_file_cache, bytebuf, 1, error) != -1) 67219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 67319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda if (bytebuf[0] == 0xc3) // ret aka retq 67419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda { 67519e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // Create a fresh, empty Row and RegisterLocation - don't mention any other registers 67619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda UnwindPlan::Row epi_row; 67719e54354ca524df5f39352569cf3ec615e69e89dJason Molenda UnwindPlan::Row::RegisterLocation epi_regloc; 67819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 67919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // When the ret instruction is about to be executed, here's our state 68019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_row.SetOffset (m_func_bounds.GetByteSize() - 1); 68119e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_row.SetCFARegister (m_lldb_sp_regnum); 68219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_row.SetCFAOffset (m_wordsize); 68319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 68419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // caller's stack pointer value before the call insn is the CFA address 68519e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_regloc.SetIsCFAPlusOffset (0); 68619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_row.SetRegisterInfo (m_lldb_sp_regnum, epi_regloc); 68719e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 68819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda // saved instruction pointer can be found at CFA - wordsize 68919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_regloc.SetAtCFAPlusOffset (-m_wordsize); 69019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda epi_row.SetRegisterInfo (m_lldb_ip_regnum, epi_regloc); 69119e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 69219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda unwind_plan.AppendRow (epi_row); 69319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 69419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 69519e54354ca524df5f39352569cf3ec615e69e89dJason Molenda } 69619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda 6978280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetSourceName ("assembly insn profiling"); 6988280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 6993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 7003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 7013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 7028280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda/* The "fast unwind plan" is valid for functions that follow the usual convention of 7038280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda using the frame pointer register (ebp, rbp), i.e. the function prologue looks like 7048280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda push %rbp [0x55] 7058280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda mov %rsp,%rbp [0x48 0x89 0xe5] (this is a 2-byte insn seq on i386) 7068280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda*/ 7078280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 7098280cbe80c79bc206335831dd732e0f9fb69c519Jason MolendaAssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan) 7103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 7118280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row row; 7128280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation pc_reginfo; 7138280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation sp_reginfo; 7148280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda UnwindPlan::Row::RegisterLocation fp_reginfo; 7158280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetRegisterKind (eRegisterKindLLDB); 7168280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7178280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda if (!func.GetBaseAddress().IsValid()) 7188280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7198280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7208280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t bytebuf[4]; 7218280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda Error error; 72226100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 72326100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton if (m_target.ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1) 7248280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7258280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7268280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t i386_prologue[] = {0x55, 0x89, 0xe5}; 7278280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5}; 7288280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda int prologue_size; 7298280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7308280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0) 7318280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7328280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda prologue_size = sizeof (i386_prologue); 7338280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7348280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0) 7358280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7368280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda prologue_size = sizeof (x86_64_prologue); 7378280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7388280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda else 7398280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda { 7408280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return false; 7418280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda } 7428280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7438280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda pc_reginfo.SetAtCFAPlusOffset (-m_wordsize); 7448280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo); 7458280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7468280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda sp_reginfo.SetIsCFAPlusOffset (0); 7478280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo); 7488280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7498280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // Zero instructions into the function 7508280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetCFARegister (m_lldb_sp_regnum); 7518280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetCFAOffset (m_wordsize); 7528280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetOffset (0); 7538280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 7548280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7558280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // push %rbp has executed - stack moved, rbp now saved 7568280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetCFAOffset (2 * m_wordsize); 7578280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize); 7588280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo); 7598280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetOffset (1); 7608280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 7618280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7628280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda // mov %rsp, %rbp has executed 7638280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetCFARegister (m_lldb_fp_regnum); 7648280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetCFAOffset (2 * m_wordsize); 7658280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda row.SetOffset (prologue_size); /// 3 or 4 bytes depending on arch 7668280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.AppendRow (row); 7678280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda 7688280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda unwind_plan.SetPlanValidAddressRange (func); 7698280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return true; 7703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 7713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 7723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 7733a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::find_first_non_prologue_insn (Address &address) 7743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 7753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn = m_func_bounds.GetBaseAddress (); 776800d11d87769e1a7083f7a5545613625396deb3eJason Molenda if (!m_cur_insn.IsValid()) 777800d11d87769e1a7083f7a5545613625396deb3eJason Molenda { 778800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return false; 779800d11d87769e1a7083f7a5545613625396deb3eJason Molenda } 780800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 78126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton const bool prefer_file_cache = true; 7823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda while (m_func_bounds.ContainsFileAddress (m_cur_insn)) 7833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 7843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda Error error; 7853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda int insn_len, offset, regno; 7863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0) 7873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 7883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // An error parsing the instruction, i.e. probably data/garbage - stop scanning 7893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 7903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 79126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton if (m_target.ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1) 7923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 7933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Error reading the instruction out of the file, stop scanning 7943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 7953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 7963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 7973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset) 7983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset)) 7993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 8003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len); 8013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda continue; 8023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 8033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda // Unknown non-prologue instruction - stop scanning 8053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda break; 8063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 8073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda address = m_cur_insn; 8093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return true; 8103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 8183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// UnwindAssemblyParser_x86 method definitions 8193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//----------------------------------------------------------------------------------------------- 8203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 822f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) 8233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AssemblyParse_x86 asm_parse(thread.GetProcess().GetTarget(), &thread, m_cpu, func); 8253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return asm_parse.get_non_call_site_unwind_plan (unwind_plan); 8263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 829f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) 8303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AssemblyParse_x86 asm_parse(thread.GetProcess().GetTarget(), &thread, m_cpu, func); 8328280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda return asm_parse.get_fast_unwind_plan (func, unwind_plan); 8333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool 836f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, Target& target, Thread* thread, Address& first_non_prologue_insn) 8373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AssemblyParse_x86 asm_parse(target, thread, m_cpu, func); 8393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn); 8403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 842dad0b760f95a68f38f4c1eb3e0f0bc8097dffae5Greg ClaytonUnwindAssemblyProfiler * 843f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::CreateInstance (const ArchSpec &arch) 8443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 845940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton const llvm::Triple::ArchType cpu = arch.GetMachine (); 846940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton if (cpu == llvm::Triple::x86) 847f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton return new UnwindAssembly_x86 (k_i386); 848940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton else if (cpu == llvm::Triple::x86_64) 849f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton return new UnwindAssembly_x86 (k_x86_64); 850940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton return NULL; 8513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------ 8553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// PluginInterface protocol in UnwindAssemblyParser_x86 8563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------ 8573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char * 859f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginName() 8603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 861f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton return "UnwindAssembly_x86"; 8623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char * 865f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetShortPluginName() 8663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 867f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton return "unwindassembly.x86"; 8683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t 872f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginVersion() 8733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return 1; 8753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid 878f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Initialize() 8793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda PluginManager::RegisterPlugin (GetPluginNameStatic(), 8813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda GetPluginDescriptionStatic(), 8823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda CreateInstance); 8833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid 886f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Terminate() 8873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 8883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda PluginManager::UnregisterPlugin (CreateInstance); 8893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char * 893f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginNameStatic() 8943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 895f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton return "UnwindAssembly_x86"; 8963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 8973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 8983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char * 899f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginDescriptionStatic() 9003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 9013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return "i386 and x86_64 assembly language profiler plugin."; 9023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 903