UnwindAssembly-x86.cpp revision 8badcb2503ed2e2884a48f66099c1d48494817f4
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
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"
248badcb2503ed2e2884a48f66099c1d48494817f4Greg Clayton#include "lldb/Target/UnwindAssembly.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
8428badcb2503ed2e2884a48f66099c1d48494817f4Greg ClaytonUnwindAssembly *
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